iosswiftopenurlios18

Unable to Open Main App from Action Extension in iOS 18 - Previously Working Methods Now Fail


I'm developing an iOS app with an Action Extension, and I'm facing a critical issue in iOS 18. The functionality to open the main app from the extension, which was working in iOS 17 and earlier, is no longer functioning in iOS 18.

Previous Implementations (Both worked up to iOS 17, both fail in iOS 18):

Original Method in action view controller

    private func restore() {
        let publicURL = String(kUTTypeURL)
        let publicText = String(kUTTypeText)

        let extensionItem: NSExtensionItem = extensionContext?.inputItems.first as! NSExtensionItem
        let itemProvider = extensionItem.attachments?.first as! NSItemProvider
        if itemProvider.hasItemConformingToTypeIdentifier(publicURL) {
            itemProvider.loadItem(forTypeIdentifier: publicURL, options: nil, completionHandler: { [weak self] item, _ in
                if let fileURL: NSURL = item as? NSURL,
                   let tmpURL = VPRealmManager.restore(url: fileURL as URL)
                {
                    let sharedDefaults = UserDefaults(suiteName: Key.AppGroup.Identifier)!
                    sharedDefaults.set(tmpURL.absoluteString, forKey: "backup_file_key") // そのページのURL保存
                    sharedDefaults.synchronize()
                    self?.openVoicepaperApp(path: "restore")
                }
            })
        }

        closeExtension()
    }

func openVoicepaperApp(path: String = "") {
    let url = NSURL(string: "voicepaper2://" + path)
    let selectorOpenURL = sel_registerName("openURL:")
    let context = NSExtensionContext()
    context.open(url! as URL, completionHandler: nil)

    var responder = self as UIResponder?
    while responder != nil {
        if responder?.responds(to: selectorOpenURL) == true {
            responder?.perform(selectorOpenURL, with: url)
        }
        responder = responder!.next
    }
}

Simplified Method:

func openVoicepaperApp(path: String = "") {
    if let url = URL(string: "voicepaper2://" + path) {
        extensionContext?.open(url, completionHandler: nil)
    }
}

In the Main App (AppDelegate.swift):

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    // ... other URL handling logic ...

    let DefaultsForAppGroup = UserDefaults(suiteName: Key.AppGroup.Identifier)!
    if url.absoluteString.contains("restore"), let fileUrl = DefaultsForAppGroup.object(forKey: "backup_file_key") as? String,
       let backupFileURL = URL(string: fileUrl)
    {
        // Show alert and perform restore
    }

    return true
}

The Problem:

Both implementations of openVoicepaperApp in the Action Extension fail to open the main app in iOS 18, whereas they both worked in iOS 17 and earlier versions. This prevents the restore process from starting in iOS 18.

Any insights, suggestions, or alternative approaches would be greatly appreciated. Thank you!


Solution

  • I encountered a similar issue, but I found a way to ensure that opening the main app from the extension works on iOS 18. Below is a simple implementation you can use:

    /// Redirect To App
    func redirectToApp() {
        let urlString = "Your URL"
        guard let redirectionURL = URL(string: urlString) else {
            return
        }
        print("Redirecting to URL: \(urlString)")
        openURL(redirectionURL)
    }
    
    /// Open URL Code
    @objc @discardableResult func openURL(_ url: URL) -> Bool {
        var responder: UIResponder? = self
        while responder != nil {
            if let application = responder as? UIApplication {
                if #available(iOS 18.0, *) {
                    application.open(url, options: [:], completionHandler: nil)
                    return true
                } else {
                    return application.perform(#selector(openURL(_:)), with: url) != nil
                }
            }
            responder = responder?.next
        }
        return false
    }