我正在向我的应用程序添加一个iMessage extension
目标。该扩展应该发送具有url
属性的消息。当用户触摸消息时,我期望的行为是使用消息的url
属性打开浏览器。
我的messageView
中有一个按钮可以执行此代码:
@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)
}
如果我触摸该消息,它会扩展MessageViewController
然后我添加了这个:
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)
}
}
现在,当我触摸消息时,它会打开我的主应用程序,但仍然没有打开我的浏览器。
我在另一篇文章中看到(我无法发表评论,因此我打开了这篇文章)无法在Safari
中打开,但我有一个新闻应用程序,它可以插入文章的链接,并允许单击消息在浏览器窗口中打开文章,同时安装该应用程序。
那么,有人可以告诉我如何继续在浏览器窗口中强制打开链接吗?
谢谢。
这是在消息中插入链接的技巧。它不允许创建具有url属性的对象,而只是直接插入将在默认Web浏览器中打开的链接。
activeConversation?.insertText("https://google.com", completionHandler: nil)
我在 github 上发布了一个示例,展示了如何从 iMessage 扩展程序内部启动 URL。它只使用固定的URL,但启动代码是您需要的。
从我的自述文件复制
显而易见的是self.extensionContext.open
它被记录为"要求系统代表当前正在运行的应用扩展打开 URL"。
那行不通。但是,您可以向上迭代响应程序链,为打开方法(实际上是 iMessage 实例)找到合适的处理程序,并使用该对象调用open
。
此方法适用于将打开本地应用的 URL,例如相机的设置或 Web URL。
主代码
@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
}
}