Когда я могу использовать SFSafariViewController, WKWebView или UIWebView с универсальными ссылками?

В Универсальные ссылки раздела iOS Руководство по программированию поиска приложений, Apple говорит:

Если вы создаете экземпляр объекта SFSafariViewController, WKWebView или UIWebView для обработки универсальной ссылки, iOS откроет ваш веб-сайт в Safari вместо того, чтобы открывать ваше приложение. Однако, если пользователь нажимает универсальную ссылку из встроенного объекта SFSafariViewController, WKWebView или UIWebView, iOS откроет ваше приложение.

Что значит «обрабатывать универсальную ссылку»? Могу ли я никогда не открывать указанный URL с SFSafariViewController, WKWebView или UIWebView? Применяется ли это только в течение -[UIApplicationDelegate application:continueUserActivity:restorationHandler:], или есть тайм-аут? Означает ли это, что мы никогда не сможем открыть URL-адрес в SFSafariViewController, WKWebView или UIWebView?


person Heath Borders    schedule 15.01.2016    source источник


Ответы (2)


Я не уверен, что полностью понимаю ваш вопрос.

Чтобы охватить основы, я позволю Apple объяснить что такое универсальная ссылка:

Универсальные ссылки позволяют пользователям открывать ваше приложение, когда они переходят по ссылкам на ваш веб-сайт в представлениях WKWebView и UIWebView и на страницах Safari, в дополнение к ссылкам, которые приводят к вызову openURL :, например тем, которые встречаются в Почте, Сообщениях и других приложениях.

Итак, представьте, что вы работаете над клиентом Twitter и просматриваете временную шкалу, вы встречаете твит со следующей ссылкой на видео YouTube: https://youtu.be/ejQod8liXm0

Если вы нажмете на него, поскольку это URL-адрес HTTP, вы ожидаете, что Safari откроет ссылку. Однако я думаю, что все мы, разработчики iOS, почти все можем согласиться с тем фактом, что нативные приложения лучше, поэтому удобнее для пользователей будет открывать видео в официальном приложении YouTube , даже от вашего стороннего клиента.

Это то, что позволяют «Универсальные ссылки»; если приложение YouTube регистрируется на iOS как приложение, отвечающее за обработку https://www.youtube.com (* ), все участники экосистемы iOS выиграют, если мы будем следовать правилам API. То же самое происходит, если вы запускаете веб-сайт и хотите, чтобы любой из вашего контента запускал ваше официальное приложение iOS, чтобы открываться, если оно установлено у вашего пользователя, или чтобы пользователю было предложено установить его для лучшего пользователя. опыт (и, конечно, помочь вашему бизнесу).

Итак, разобравшись со всем этим, давайте вернемся к исходному тексту:

Если вы создаете экземпляр объекта SFSafariViewController, WKWebView или UIWebView для обработки универсальной ссылки, iOS откроет ваш веб-сайт в Safari вместо того, чтобы открывать ваше приложение. Однако, если пользователь нажимает универсальную ссылку из встроенного объекта SFSafariViewController, WKWebView или UIWebView, iOS откроет ваше приложение.

Это означает, что если в вашем приложении пользователь нажимает универсальную ссылку на ваш контент (пример: http://www.your-company.com/foo), и вы не обнаружите это в коде вашего приложения, например, с помощью регулярного выражения, а вместо этого создаете экземпляр SFSafariViewController, WKWebView или UIWebView, чтобы открыть его, как если бы он были обычной ссылкой на The New York Times или что-то в этом роде, ОС поймет, что вместо открытия этого в своем приложении вы хотите, чтобы Safari справилась с этим за вас. Помните: вся цель универсальных ссылок состоит в том, чтобы пользователю было удобнее работать с URL-адресом, который обрабатывается собственным приложением, а не браузером.

Об этом говорится в первом предложении. Что касается второго, он устраняет потенциальный последующий вопрос: что, если пользователь нажмет на универсальную ссылку на мой контент из встроенного браузера из другого приложения, которое мне не принадлежит? Затем в предложении говорится , ОС будет вести себя нормально: она откроет ваше приложение с соблюдением правил Universal Link.

TL; DR: вам также необходимо обнаруживать универсальные ссылки на ваш контент из вашего приложения в коде и обрабатывать их. iOS не справится с этим за вас. Вместо этого, если вы укажете ОС открыть универсальную ссылку на контент вашего приложения во встроенном браузере из вашего приложения, она будет делать именно так, как было сказано.

РЕДАКТИРОВАТЬ: Если вам нужна помощь в выборе между запросом SFSafariViewController или -openURL:options:completitionHandler: API на открытие URL-адреса, эта ссылка должна вам помочь; я бы порекомендовал сначала использовать -openURL:options:completitionHandler:, а если не удалось, то используйте SFSafariViewController или аналогичный.

Надеюсь, это поможет, и я правильно понял ваш вопрос.

Ваше здоровье! И счастливого программирования на iOS 11! :)

person dinesharjani    schedule 31.07.2017
comment
›Если вы нажмете на него, поскольку это URL-адрес HTTP, вы ожидаете, что Safari откроет ссылку. Если ссылка на YouTube находится в обычном UITableViewCell, мне придется как-то обрабатывать ссылку на YouTube, либо с -[UIApplication openURL:options:completionHandler:], либо с UIWebView, WKWebView , или SFSafariViewController. Я предполагаю, что если я обработаю ссылку на YouTube с помощью веб-представления, система не откроет приложение youtube, но -openURL:options:completionHandler: откроет. Как мне узнать, что делать? - person Heath Borders; 31.07.2017
comment
Я думаю, следующая ссылка дает ответы, которые вы ищете: useyourloaf.com/ blog / openurl-deprecated-in-ios10 Идея состоит в том, что вы можете сначала использовать -openURL:options:completitionHandler:, а если это не удалось (успех boolean is false), вы можете вместо этого использовать SFSafariViewController или аналогичный. - person dinesharjani; 31.07.2017
comment
Обновите свой ответ, включив его напрямую, и я отмечу вас как правильную. Спасибо! - person Heath Borders; 31.07.2017
comment
@HeathBorders Готово! - person dinesharjani; 01.08.2017

Я решил эту проблему с помощью моего класса Swift 4 ниже. Если возможно, он также использует встроенный браузер Safari. Вы можете использовать аналогичный метод и в вашем случае.

import UIKit
import SafariServices

class OpenLink {
    static func inAnyNativeWay(url: URL, dontPreferEmbeddedBrowser: Bool = false) { // OPEN AS UNIVERSAL LINK IF EXISTS else : EMBEDDED or EXTERNAL
        if #available(iOS 10.0, *) {
            // Try to open with owner universal link app
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : true]) { (success) in
                if !success {
                    if dontPreferEmbeddedBrowser {
                        withRegularWay(url: url)
                    } else {
                        inAnyNativeBrowser(url: url)
                    }
                }
            }
        } else {
            if dontPreferEmbeddedBrowser {
                withRegularWay(url: url)
            } else {
                inAnyNativeBrowser(url: url)
            }
        }
    }
    private static func isItOkayToOpenUrlInSafariController(url: URL) -> Bool {
        return url.host != nil && (url.scheme == "http" || url.scheme == "https") //url.host!.contains("twitter.com") == false
    }
    static func inAnyNativeBrowser(url: URL) { // EMBEDDED or EXTERNAL BROWSER
        if isItOkayToOpenUrlInSafariController(url: url) {
            inEmbeddedSafariController(url: url)
        } else {
            withRegularWay(url: url)
        }
    }
    static func inEmbeddedSafariController(url: URL) { // EMBEDDED BROWSER ONLY
        let vc = SFSafariViewController(url: url, entersReaderIfAvailable: false)
        if #available(iOS 11.0, *) {
            vc.dismissButtonStyle = SFSafariViewController.DismissButtonStyle.close
        }
        mainViewControllerReference.present(vc, animated: true)
    }
    static func withRegularWay(url: URL) { // EXTERNAL BROWSER ONLY
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey(rawValue: "no"):"options"]) { (good) in
                if !good {
                    Logger.log(text: "There is no application on your device to open this link.")
                }
            }
        } else {
            UIApplication.shared.openURL(url)
        }
    }
}
person Salih    schedule 12.10.2018