XCode11 错误 "open(_:options:completionHandler:) is unavailable in application extensions"

XCode11 error "open(_:options:completionHandler:) is unavailable in application extensions"

启动 Touchgram v1.0 后,它是 99% 的 iMessage 应用程序扩展,我尝试更新到 XCode11。

我开始收到错误消息open(_:options:completionHandler:) is unavailable in application extensions

我确认即使在尝试从 iMessage 应用程序启动网络 URL 的 trivial sample 中也会发生这种情况:

对于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
    }

2020 年更新

我自己对这个问题的回答在下面详细说明了解决方法的工作原理。请注意,上面链接的示例已得到修复,既可以使用此变通方法,也可以显示在 iMessage 扩展本身的 WKWebView 内打开 Web URL。

正如在该样本的(唯一)issue 中记录的那样,这是 对 iOS 13 的故意更改,经 DTS 确认。我相信这是打击键盘扩展中滥用行为的一部分,它把 iMessage 扩展作为副作用。

我已经想出了一个解决方法,与他们推荐的相同。

  1. 使用 self.extensionContext?.open
  2. 将 URL 转发到您的父应用
  3. 让父应用程序启动外部应用程序或 URL 代表.

这是 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)
    }
}

因为这个问题的标题是通用的,并没有具体指代 Touchgram,所以我建议另一个解决方法有两个目的:

  1. 尝试帮助其他只阅读标题就解决这个问题的人;
  2. 寻找有关此解决方法和 Apple 政策兼容性的意见。

转到您的扩展程序的构建设置并将“仅需要 App-Extension-Safe API”的值更改为“否”可能就足够了。这确实有效,但阅读其他人对此的评论真的很有帮助。

除此之外,如果有人在扩展目标中有一些 pod 依赖,并且包含的​​ Pod 的文件中发生错误,那么可以通过将 Require Only App-Extension-Safe API 设置为 [=11] 来解决此错误=] 对于那个特定的 Pod。 以下是它的路径:

Pods -> Targets -> Your-Problematic-Pod -> Build Settings -> Require Only App-Extension-Safe API 将其设置为 NO