ios 11 imessage extension message.url does not ope

2019-08-17 06:22发布

问题:

I'm adding an iMessage extension target to my app. The extension is supposed to send a message that has a url attribute. The behaviour I'm expecting when a user touches the message is to open the browser using the url attribute of the message.

I have a button in my messageView which executes this code:

@IBAction func labelButton(_ sender: Any) {
        let layout = MSMessageTemplateLayout()
        layout.imageTitle = "iMessage Extension"
        layout.caption = "Hello world!"
        layout.subcaption = "Test sub"
        guard let url: URL = URL(string: "https://google.com") else { return }

        let message = MSMessage()
        message.layout = layout
        message.summaryText = "Sent Hello World message"
        message.url = url

        activeConversation?.insert(message, completionHandler: nil)
    }

If I touch the message, it expands the MessageViewController

I have then added this:

override func didSelect(_ message: MSMessage, conversation: MSConversation) {

        if let message = conversation.selectedMessage {
            // message selected

            // Eg. open your app:
            self.extensionContext?.open(message.url!, completionHandler: nil)
        }
}

And now, when I touch the message, it opens my main app but still not my browser.

I have seen on another post (where I cannot comment, thus I opened this post) that it is impossible to open in Safari but I have a news app which inserts links to articles and allows with a click on the message to open the article in a browser window, while the app is installed.

So, can someone please tell how I can proceed to force opening the link in a browser window?

Thank you very much.

回答1:

Here is a trick to insert a link in a message. It does not allow to create an object that has an url attribute but just to insert a link directly which will open in Safari.

activeConversation?.insertText("https://google.com", completionHandler: nil)


回答2:

I have published a sample on github showing how to launch a URL from inside an iMessage extension. It just uses a fixed URL but the launching code is what you need.

Copying from my readme

The obvious thing to try is self.extensionContext.open which is documented as Asks the system to open a URL on behalf of the currently running app extension.

That doesn't work. However, you can iterate back up the responder chain to find a suitable handler for the open method (actually the iMessage instance) and invoke open with that object.

This approach works for URLs which will open a local app, like settings for a camera, or for web URLs.

The main code

@IBAction public func onOpenWeb(_ sender: UIButton)  {
    guard let url = testUrl else {return}

    // technique that works rather than self.extensionContext.open
    var responder = self as UIResponder?
    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
    }
}