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>
80 lines
2.7 KiB
Swift
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)
|
|
}
|
|
}
|