Reputation: 17971
After launching Touchgram v1.0, which is 99% iMessage app extension, I tried to update to XCode11.
I started getting an error open(_:options:completionHandler:) is unavailable in application extensions
I 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
}
Update 2020
My own answer to this question, below, details how the workaround works. Note that the sample linked above has been fixed to both use this workaround and also show opening a web URL inside a WKWebView
inside the iMessage extension itself.
Upvotes: 4
Views: 3094
Reputation: 421
Because of this question' s title is generic and doesn' t refer specifically to Touchgram, i would suggest another workaround for two purposes:
It could be enough to go to your Extension' s Build settings and change the value for "Require Only App-Extension-Safe API" to "NO". This does the trick but it would be really helpful to read someone other' s comment about that.
In Addition to above, if someone have some pod dependency in the Extension Target, and error is happening in the files of the included Pod, then this error can be solved by setting Require Only App-Extension-Safe API
to No
for that particular Pod.
Following would be the path for it:
Pods -> Targets -> Your-Problematic-Pod -> Build Settings -> Require Only App-Extension-Safe API
set this to NO
.
Upvotes: 4
Reputation: 17971
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.
self.extensionContext?.open
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)
}
}
Upvotes: 4