【问题标题】:Swift 3 iMessage Extension doesn't open URLSwift 3 iMessage 扩展不打开 URL
【发布时间】:2017-01-14 01:28:28
【问题描述】:

我正在创建一个 iOS 应用程序 iMessage 扩展。

根据Example by Apple,我根据提供的逻辑创建消息

guard let url: URL = URL(string: "http://www.google.com") else { return }

let message = composeMessage(url: url)
activeConversation?.insert(message, completionHandler: { [weak self] (error: Error?) in
    guard let error = error else { return }
    self?.presentAlert(error: error)        
})

还有

private func composeMessage(url: URL) -> MSMessage {
    let layout = MSMessageTemplateLayout()
    layout.caption = "caption"
    layout.subcaption = "subcaption"
    layout.trailingSubcaption = "trailing subcaption"

    let message = MSMessage()
    message.url = url
    message.layout = layout

    return message
}

private func presentAlert(error: Error) {
    let alertController: UIAlertController = UIAlertController(
        title: "Error",
        message: error.localizedDescription,
        preferredStyle: .alert
    )

    let cancelAction: UIAlertAction = UIAlertAction(
        title: "OK",
        style: .cancel,
        handler: nil
    )

    alertController.addAction(cancelAction)

    present(
        alertController,
        animated: true,
        completion: nil
    )
}

据我了解,发送消息后,点击一下,应该会打开 Safari 浏览器。

当我点击发送的消息时,MessageViewController 屏幕会在整个屏幕中显示,而无需打开 safari 或其他应用程序。

问题出在哪里?如何实现所需的功能?

【问题讨论】:

    标签: ios swift swift3 imessage ios-messages-extension


    【解决方案1】:

    我认为 Safari 浏览器仅适用于 macOS。这对我有用:

    override func didSelectMessage(message: MSMessage, conversation: MSConversation) {
    
            if let message = conversation.selectedMessage {
                // message selected
    
                // Eg. open your app:
                let url = // your apps url
                self.extensionContext?.openURL(url, completionHandler: { (success: Bool) in
    
                })
            }
        }
    

    【讨论】:

    • 我曾尝试拨打extensionContext?.openURL(url, completionHandler:nil),但没有成功。至少在 iOS 10 中。
    • 我正在使用此代码块打开我的深层链接 url,但它不起作用 self.extensionContext?.open(url as URL, completionHandler:{ (success: Bool) in })
    【解决方案2】:

    使用Julio Bailon展示的技术

    已针对 Swift 4 修复,openURL 已被弃用。

    请注意,extensionContext?.openURL 技术在 iMessage 扩展程序中起作用 - 它只会打开您当前的应用程序。

    我在GitHub 上发布了一个完整的示例应用程序,展示了该技术,并在此处提供了相关的 sn-p:

        let handler = { (success:Bool) -> () in
            if success {
                os_log("Finished opening URL")
            } else {
                os_log("Failed to open URL")
            }
        }
    
        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)  // perform(openSel, with: url)
                return
            }
            responder = responder!.next
        }
    

    【讨论】:

    【解决方案3】:

    这是我用来从 iMessage 扩展程序打开 URL 的代码。目前正在努力在 WATUU iMessage 应用程序中打开音乐应用程序。例如使用 URL "https://itunes.apple.com/us/album/as%C3%AD/1154300311?i=1154300401&uo=4&app=music"

    此功能目前适用于 iOS 10、11 和 12

    func openInMessagingURL(urlString: String){
        if let url = NSURL(string:urlString){
            let context = NSExtensionContext()
            context.open(url, completionHandler: nil)
            var responder = self as UIResponder?
    
            while (responder != nil){
                if responder?.responds(to: Selector("openURL:")) == true{
                    responder?.perform(Selector("openURL:"), with: url)
                }
                responder = responder!.next
            }
        }
    }
    

    SWIFT 4 更新

    func openInMessagingURL(urlString: String){
        if let url = URL(string:urlString){
            let context = NSExtensionContext()
            context.open(url, completionHandler: nil)
            var responder = self as UIResponder?
    
            while (responder != nil){
                if responder?.responds(to: #selector(UIApplication.open(_:options:completionHandler:))) == true{
                    responder?.perform(#selector(UIApplication.open(_:options:completionHandler:)), with: url)
                }
                responder = responder!.next
            }
        }
    }
    

    【讨论】:

    • 谢谢,但我想你会发现 context.open 可以被删除,因为它没有做任何事情。沿着树向上查找谁响应 openURL 的代码是有效的。
    • 在下面发布了答案,谢谢,使用您的技术更新了当前的 iOS 和 Swift 4
    【解决方案4】:

    似乎无法从消息扩展中打开应用程序,但工作区中包含的配套应用程序除外。我们尝试从我们的消息扩展中打开 Safari,但没有成功,这个限制似乎是设计使然。

    您可以尝试其他方案来解决您的问题:

    1. 扩展消息扩展中的 Webview

      你可以在你的消息扩展中有一个 Webview,当你点击 在消息上,您可以打开扩展模式并在 网页浏览。

    用户不会在 Safari 中,但该页面将嵌入到您的消息扩展中。

    1. 在配套应用中打开网址

      点击消息后,您可以打开您的 Companion 应用程序(通过 带有特殊参数的 MyApp://?myParam=myValue) 的 Url Scheme ; Companion 应用程序应该对此参数做出反应并可以重定向 通过 OpenUrl 到 Safari。

    在这种情况下,您将在网页之前进行多次重定向,但它应该允许返回对话。

    我们还发现,如果您想直接在 Messages 中打开 Apple Store 并让用户购买商品,我们可以在 Message Extension 中实例化 SKStoreProductViewController。

    【讨论】:

    • 有可能。请检查下面的答案。
    【解决方案5】:

    如果你只需要插入一个链接,那么你应该使用activeConversation.insertText并插入链接。触摸消息将打开Safari

    【讨论】:

      【解决方案6】:
      1. didSelectMessage 中的 openURL:conversation: 通过使用 extensionContext

      2. 在您的主机 AppDelegate 中处理 URL 方案

      【讨论】:

      • 继承方法didSelectMessage:conversation: 在点击所需消息时不会被调用。在发送之前选择消息时触发。更重要的是,在宿主应用程序委托中处理 URL 方案更糟糕,宿主应用程序可能甚至还没有启动,尽管事实上,这是在后台作为最好的情况......
      • @DaumantasVersockas 当你点击发送的消息时,你应该在 didBecomeActiveWithConversation: 方法上处理它,你可以从 Conversion 中获取 selectedMessage。使用 extensionContext openURL 将启动您的主机应用程序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 2016-06-19
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      相关资源
      最近更新 更多