在Universal Links的iOS App Search Programming Guide部分,Apple说:
如果您实例化SFSafariViewController,WKWebView或UIWebView 对象处理通用链接,iOS在Safari中打开您的网站 而不是打开你的应用程序。但是,如果用户点击通用 从嵌入式SFSafariViewController,WKWebView或中的链接 UIWebView对象,iOS打开你的应用程序。
"处理通用链接"意思?我是否可以使用SFSafariViewController
,WKWebView
或UIWebView
打开指定的网址?它是否仅在-[UIApplicationDelegate application:continueUserActivity:restorationHandler:]
期间适用,或者是否存在超时?这是否意味着我们无法在SFSafariViewController
,WKWebView
或UIWebView
中打开网址?
答案 0 :(得分:5)
我不确定我完全理解你的问题。
为了涵盖基础知识,我将允许Apple解释what a Universal Link is:
通用链接允许用户在WKWebView和UIWebView视图和Safari页面中点击指向您网站的链接时打开您的应用,此外还有导致调用openURL的链接:,例如Mail,Messages和其他应用程序。
基本上,假设您正在Twitter客户端上工作,并且通过时间线,您会收到包含以下YouTube视频链接的推文:https://youtu.be/ejQod8liXm0
如果您点按它,因为它是HTTP网址,您希望Safari打开该链接。但是,我认为我们所有iOS开发人员几乎都同意本机应用程序更好的事实,因此更好的用户体验将是官方YouTube应用程序打开视频,甚至来自您的第三方客户。
这就是" Universal Links"允许;如果YouTube应用在iOS上注册为负责处理https://www.youtube.com(*)链接的应用,那么如果我们遵循API规则,iOS生态系统中的每个人都会受益。如果你运营一个网站并且你希望你的任何内容触发你的官方iOS应用程序打开(如果你的用户已经安装了它),或者如果用户想要安装它,那么就会发生同样的事情。更好的用户体验(当然也有助于您的业务)。
所以,尽管如此,让我们回到原文:
如果您实例化SFSafariViewController,WKWebView或UIWebView对象以处理通用链接,iOS将在Safari中打开您的网站,而不是打开您的应用程序。但是,如果用户从嵌入式SFSafariViewController,WKWebView或UIWebView对象中点击通用链接,iOS将打开您的应用程序。
这意味着,如果来自您的应用,您的用户会点击内容的通用链接(例如:http://www.your-company.com/foo),而您在应用的代码中未通过例如,正则表达式,而不是实例化SFSafariViewController
,WKWebView
或UIWebView
来打开它,好像它是The New York Times或其他东西的常规链接,操作系统会理解而不是在你的应用程序中打开它,你希望Safari为你处理这个。 请记住:Universal Links的全部目的是让用户通过本机应用程序处理URL而不是浏览器来获得更好的体验。
这是第一句话。至于第二个问题,它清除了一个潜在的后续问题:如果用户从嵌入式浏览器从另一个不属于我的应用程序中点击我的内容的通用链接会怎样?然后,句子说,操作系统将正常运行:它将打开你的应用程序,尊重通用链接规则。
TL; DR:您还需要在应用中检测来自您应用内容的通用链接,并在代码中处理。 iOS不会为您处理此问题。相反,如果您告诉操作系统从您的应用程序在嵌入式浏览器中打开应用程序内容的通用链接,它将完全按照说明执行。
编辑:如果您在要求SFSafariViewController
或-openURL:options:completitionHandler:
API打开网址时需要帮助,this link should help you; 我的建议是首先使用-openURL:options:completitionHandler:
,如果不成功,请使用SFSafariViewController
或类似。
希望这有帮助,并且我已正确理解您的问题。
干杯!和快乐的iOS 11编程! :)
答案 1 :(得分:4)
我在下面的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)
}
}
}