Расширение Swift 3 iMessage не открывает URL-адрес

Я создаю расширение iMessage для приложения iOS.

Согласно примеру 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 занимает весь экран, не открывая сафари или другое приложение.

В чем проблема? Как я могу достичь желаемой функциональности?


person Daumantas Versockas    schedule 06.09.2016    source источник


Ответы (6)


Я думаю, что Safari Browser открывается только для 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

            })
        }
    }
person benaneesh    schedule 06.09.2016
comment
Я безуспешно пытался позвонить extensionContext?.openURL(url, completionHandler:nil). По крайней мере, в iOS 10. - person Daumantas Versockas; 07.09.2016
comment
я использую этот блок кода, чтобы открыть URL-адрес моей глубокой ссылки, но он не работает self.extensionContext?.open(url as URL, completeHandler: {(success: Bool) in }) - person Shauket Sheikh; 24.05.2017

Используя технику, показанную Хулио Бейлоном

Исправлено для Swift 4, и этот openURL устарел.

Обратите внимание, что метод extensionContext?.openURL не работает с расширением iMessage — он открывает только ваше текущее приложение.

Я разместил полный образец приложения, показывающий технику, на GitHub с соответствующий фрагмент здесь:

    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
    }
person Andy Dent    schedule 07.03.2019
comment
Посмотрите на пример приложения, на которое я ссылался, и посмотрите, где оно находится в этом коде. Это слишком сложно объяснить вне контекста. Эти образцы тщательно обработаны, чтобы продемонстрировать только один основной момент в каждом образце. github.com/AndyDentFree/im-plausibilities/tree/master/webFromIM - person Andy Dent; 26.07.2019
comment
Похоже, это не работает в Xcode 11. Получение ошибки «open(_:options:completionHandler:)» недоступно в расширениях приложений для iOS. - person NSExceptional; 20.10.2019
comment
Я тоже это заметил - см. "> stackoverflow.com/questions/58153341/ - person Andy Dent; 20.10.2019

Вот код, который я использую для открытия URL-адреса из расширения iMessage. В настоящее время мы работаем над тем, чтобы открыть приложение «Музыка» в приложении 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
        }
    }
}
person Julio Bailon    schedule 30.08.2018
comment
Спасибо, но я думаю, вы обнаружите, что context.open можно удалить, так как он ничего не делает. Работает код, который проходит вверх по дереву, чтобы найти, кто отвечает на openURL. - person Andy Dent; 06.03.2019
comment
Опубликовал ответ ниже, спасибо, обновлен для текущей версии iOS и Swift 4, используя вашу технику. - person Andy Dent; 08.03.2019

Кажется, невозможно открыть приложение из расширения сообщения, за исключением сопутствующего приложения, содержащегося в рабочей области. Мы попытались открыть Safari из нашего расширения сообщений, но это не сработало, кажется, это ограничение предусмотрено замыслом.

Вы можете попробовать другие сценарии, чтобы решить вашу проблему:

  1. Веб-просмотр в расширенном расширении сообщения

    У вас может быть веб-просмотр в вашем расширении сообщений, и когда вы нажимаете на сообщение, вы можете открыть расширенный режим и открыть свой URL-адрес в веб-просмотре.

Пользователь не будет в Safari, но страница будет встроена в ваше расширение для сообщений.

  1. Откройте URL-адрес во вспомогательном приложении

    Щелкнув по сообщению, вы можете открыть свое приложение-компаньон (через схему URL с MyApp://?myParam=myValue) со специальным параметром; приложение-компаньон должно реагировать на этот параметр и может перенаправлять в Safari через OpenUrl.

В этом случае вы сделаете несколько перенаправлений перед веб-страницей, но это должно позволить вернуться к беседе.

Мы также обнаружили, что можем создать экземпляр SKStoreProductViewController в расширении сообщения, если вы хотите открыть Apple Store прямо в сообщениях и позволить пользователю покупать товары.

person Christian Navelot    schedule 10.10.2016
comment
Это возможно. Пожалуйста, проверьте следующий ответ ниже. - person Julio Bailon; 30.08.2018

Если вам нужно только вставить ссылку, то вы должны использовать activeConversation.insertText и вставить ссылку. Прикосновение к сообщению откроет Safari.

person radar    schedule 03.10.2017

  1. openURL в didSelectMessage:беседа: с помощью extensionContext

  2. обрабатывать схему URL-адресов в вашем хосте AppDelegate

person handrenliang    schedule 06.10.2016
comment
унаследованный метод didSelectMessage:conversation: не вызывается при нажатии на нужное сообщение. Он срабатывает, когда сообщение выбирается перед отправкой. Более того, обработка схемы URL в делегате хост-приложения еще хуже, хост-приложение может быть даже не запущено, несмотря на то, что в лучшем случае оно находится в фоновом режиме... - person Daumantas Versockas; 07.10.2016
comment
@DaumantasVersockas Когда вы нажимаете на отправленное сообщение, вы должны обработать его методом didBecomeActiveWithConversation: вы можете получить selectedMessage из Conversion. Использование extensionContext openURL запустит ваше хост-приложение. - person handrenliang; 07.10.2016