Reputation: 680
I am trying to build a share extension that allows the user to select photos and share with my app. Once they click share, I have a custom UI that prompts for a choice. Depending on the choice they make the main app should open a specific view and pass the images as arguments to a specific function within the view.
I can successfully save the image to a shared container. After that, I want to notify the main app. The following code is supposed to do that (in the extension's ShareViewController
):
private func notifyMainApp() {
// Notify the main app using URL scheme or UserDefaults
UserDefaults(suiteName: "group.com.mycompany.myapp")?.set(true, forKey: "newImageAvailable")
completeRequest()
}
private func completeRequest() {
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: { _ in
guard let url = URL(string: "myapp://handleImage") else { return }
_ = self.openURL(url)
})
print("Completing")
}
@objc private func openURL(_ url: URL) -> Bool {
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
return application.perform(#selector(openURL(_:)), with: url) != nil
}
responder = responder?.next
}
return false
}
On my main App's side, this is the AppCode:
import SwiftUI
@main
struct myApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func applicationDidBecomeActive(_ application: UIApplication) {
NotificationCenter.default.addObserver(self, selector: #selector(handleSharedImage), name: UserDefaults.didChangeNotification, object: nil)
handleSharedImage()
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
print("Application opened via URL scheme: \(url)")
if url.scheme == "myApp" && url.host == "handleImage" {
handleSharedImage()
return true
}
return false
}
@objc func handleSharedImage() {
print("Handling shared image")
let userDefaults = UserDefaults(suiteName: "group.com.mycompany.myapp")
if let selectedType = userDefaults?.string(forKey: "selectedType") {
print("Found selected type: \(selectedType)")
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.yourcompany.yourapp")
let fileURL = containerURL?.appendingPathComponent("sharedImage.png")
if let imageData = try? Data(contentsOf: fileURL!), let image = UIImage(data: imageData) {
// Handle the image and the selected type (e.g., show it in a view or upload it to a server)
print("Image loaded from shared container: \(image) with type: \(selectedType)")
NotificationCenter.default.post(name: NSNotification.Name("SharedImageHandled"), object: nil, userInfo: ["image": image, "type": selectedType])
} else {
print("Failed to load image data from shared container")
}
// Reset the flag
userDefaults?.removeObject(forKey: "selectedType")
} else {
print("No selected type found in UserDefaults")
}
}
}
The app is successfully opened but nothing happens and the logs show me that the URL scheme, despite having opened the App, doesn't trigger any logs. I've tried to find some information about this but most tutorials deal with creating standalone extensions, not extensions that share the app. Any help is thus appreciated.
Upvotes: 0
Views: 56