Files
Nextcloud-Cookbook-iOS/ShareExtension/ShareViewController.swift
Hendrik Hogertz ce2a814e5a Add Share Extension for importing recipes via URL
Adds a Share Extension so users can share URLs from Safari (or any app)
to open the main app with the ImportURLSheet pre-filled. Uses a custom
URL scheme (nextcloud-cookbook://) as the bridge between the extension
and the main app.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 10:17:22 +01:00

80 lines
2.7 KiB
Swift

//
// ShareViewController.swift
// ShareExtension
//
// Created by Hendrik Hogertz on 15.02.26.
//
import UIKit
import UniformTypeIdentifiers
class ShareViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
handleSharedItems()
}
private func handleSharedItems() {
guard let extensionItems = extensionContext?.inputItems as? [NSExtensionItem] else {
completeRequest()
return
}
for item in extensionItems {
guard let attachments = item.attachments else { continue }
for provider in attachments {
if provider.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
provider.loadItem(forTypeIdentifier: UTType.url.identifier) { [weak self] item, _ in
if let url = item as? URL {
self?.openMainApp(with: url.absoluteString)
} else {
self?.completeRequest()
}
}
return
} else if provider.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) {
provider.loadItem(forTypeIdentifier: UTType.plainText.identifier) { [weak self] item, _ in
if let text = item as? String, let url = URL(string: text), url.scheme?.hasPrefix("http") == true {
self?.openMainApp(with: url.absoluteString)
} else {
self?.completeRequest()
}
}
return
}
}
}
completeRequest()
}
private func openMainApp(with urlString: String) {
guard let encoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let appURL = URL(string: "nextcloud-cookbook://import?url=\(encoded)")
else {
completeRequest()
return
}
// Use the responder chain to open the URL
var responder: UIResponder? = self
while let r = responder {
if let application = r as? UIApplication {
application.open(appURL, options: [:], completionHandler: nil)
break
}
responder = r.next
}
// Give the system a moment to process the URL before dismissing
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
self?.completeRequest()
}
}
private func completeRequest() {
extensionContext?.completeRequest(returningItems: nil)
}
}