问题
I just launched Touchgram v1.0 last week, which is 99% iMessage app extension, and am trying to update to XCode11.
I'm now getting an error open(_:options:completionHandler:) is unavailable in application extensions
I have confirmed this occurs even in a trivial sample that tries to launch a web URL from an iMessage app:
For example:
let openSel = #selector(UIApplication.open(_:options:completionHandler:))
while (responder != nil){
if responder?.responds(to: openSel ) == true {
// cannot package up multiple args to openSel
// so we explicitly call it on the iMessage application instance
// found by iterating up the chain
(responder as? UIApplication)?.open(url, completionHandler:handler)
return
}
responder = responder!.next
}
Also asked on the Apple Developer Forums.
回答1:
As documented in the (sole) issue on that sample, this was an intentional change in iOS 13 as confirmed by DTS. My belief is this was part of a crackdown on abusive behaviour in keyboard extensions, which picked up iMessage extensions as a side-effect.
I'd already come up with a workaround, which is the same as they recommend.
- Forward the URL to your parent app using
self.extensionContext?.open
- Have the parent app then launch the external app or URL on your behalf.
Here's the complete working extension from Touchgram
// UIViewController+iMessageContext.swift
// applied to class MessagesViewController: MSMessagesAppViewController, UrlOpeningInIMessage
protocol UrlOpeningInIMessage {
func openFromiMessageContext(url:URL)
}
extension UrlOpeningInIMessage where Self:UIViewController {
func openFromiMessageContext(url:URL) {
let handler = { (success:Bool) -> () in
if success {
os_log("Finished opening URL", log:tgEnv.logImUI, type:.debug)
} else {
os_log("Failed to open URL", log:tgEnv.logImUI, type:.debug)
}
}
// logic same as onLaunchMainPressed, since XCode11 unable to compile extension using UIApplication.open
// so we pass the URL through to the parent app to launch on our behalf
let appName = Bundle.appName()
let encodedUrl = url.dataRepresentation.base64EncodedString()
guard let appUrl: URL = URL(string: "\(appName)://?url=\(encodedUrl)") else { return }
// can only open our app, not generalised URLs
self.extensionContext?.open(appUrl, completionHandler: handler)
}
}
来源:https://stackoverflow.com/questions/58153341/xcode11-error-open-optionscompletionhandler-is-unavailable-in-application