我什么时候可以使用带有通用链接的 SFSafariViewController、WKWebView 或 UIWebView?
When can I use a SFSafariViewController, WKWebView, or UIWebView with universal links?
在 Universal Links section of the iOS App Search Programming Guide 中,Apple 表示:
If you instantiate a SFSafariViewController, WKWebView, or UIWebView
object to handle a universal link, iOS opens your website in Safari
instead of opening your app. However, if the user taps a universal
link from within an embedded SFSafariViewController, WKWebView, or
UIWebView object, iOS opens your app.
"handle a universal link"是什么意思?我永远不能用 SFSafariViewController
、WKWebView
或 UIWebView
打开给定的 URL 吗?它仅在 -[UIApplicationDelegate application:continueUserActivity:restorationHandler:]
期间适用,还是有超时?这是否意味着我们永远无法在 SFSafariViewController
、WKWebView
或 UIWebView
中打开 URL?
我不确定我是否完全理解你的问题。
只是为了介绍基础知识,我将允许 Apple 进行解释 what a Universal Link is:
Universal links let users open your app when they tap links to your website within WKWebView and UIWebView views and Safari pages, in addition to links that result in a call to openURL:, such as those that occur in Mail, Messages, and other apps.
所以基本上,假设您正在使用 Twitter 客户端并浏览时间线,您会遇到一条包含以下 YouTube 视频的推文 link:https://youtu.be/ejQod8liXm0
如果您点击它,因为它是 HTTP URL,您会希望 Safari 打开 link。但是,我认为我们所有 iOS 开发人员几乎都同意 原生应用程序更好 ,因此更好的用户体验将 官方 YouTube 应用打开视频,甚至从您的第三方客户端。
这是"Universal Links"允许的;如果 YouTube 应用程序在 iOS 上注册为负责处理 https://www.youtube.com(*) link 的应用程序,iOS 生态系统中的每个人都会受益,如果我们遵循 API 规则。如果您 运行 一个网站并且您希望您的任何内容触发您的官方 iOS 应用程序打开(如果您的用户安装了它),或者如果用户安装了该应用程序则提示用户,也会发生同样的事情喜欢安装它以获得更好的用户体验(当然也是为了帮助您的业务)。
所以,抛开所有这些,让我们回到原文:
If you instantiate a SFSafariViewController, WKWebView, or UIWebView object to handle a universal link, iOS opens your website in Safari instead of opening your app. However, if the user taps a universal link from within an embedded SFSafariViewController, WKWebView, or UIWebView object, iOS opens your app.
这意味着,如果您的用户在您的应用中点击您的内容的通用 Link(例如:http://www.your-company.com/foo), and you do not detect this in your app's code via a regular expression for example, and instead instantiate a SFSafariViewController
, WKWebView
or UIWebView
to open it as if it were a regular link to The New York Times 或其他内容,OS 将理解而不是在您的应用程序中打开它,您希望 Safari 为您处理它。记住:Universal Links 的全部目的URL 由本机应用程序而非浏览器处理,让用户获得更好的体验。
第一句是这样说的。至于第二个,它清除了一个潜在的后续问题:如果用户从嵌入式浏览器 从另一个不是我的应用程序点击通用 Link 到我的内容怎么办? 然后,句子说,OS 将正常运行:它将打开您的应用程序,遵守通用 Link 规则。
TL;DR:您还需要在代码中检测您的应用程序内容的通用 Link,并处理它们。 iOS 不会为您处理。相反,如果您告诉 OS 在您的应用程序的嵌入式浏览器中打开一个通用 Link 到您的应用程序内容,它会完全按照指示执行。
编辑: 如果您需要帮助决定是询问 SFSafariViewController
还是 -openURL:options:completitionHandler:
API 打开 URL , this link should help you; 我的建议是先使用-openURL:options:completitionHandler:
,如果不成功,再使用SFSafariViewController
或类似的。
希望这对您有所帮助,并且我已经正确理解了您的问题。
干杯!快乐 iOS 11 编程! :)
我用下面的 Swift 4 class 解决了这个问题。如果可能,它还会使用嵌入式 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)
}
}
}
在 Universal Links section of the iOS App Search Programming Guide 中,Apple 表示:
If you instantiate a SFSafariViewController, WKWebView, or UIWebView object to handle a universal link, iOS opens your website in Safari instead of opening your app. However, if the user taps a universal link from within an embedded SFSafariViewController, WKWebView, or UIWebView object, iOS opens your app.
"handle a universal link"是什么意思?我永远不能用 SFSafariViewController
、WKWebView
或 UIWebView
打开给定的 URL 吗?它仅在 -[UIApplicationDelegate application:continueUserActivity:restorationHandler:]
期间适用,还是有超时?这是否意味着我们永远无法在 SFSafariViewController
、WKWebView
或 UIWebView
中打开 URL?
我不确定我是否完全理解你的问题。
只是为了介绍基础知识,我将允许 Apple 进行解释 what a Universal Link is:
Universal links let users open your app when they tap links to your website within WKWebView and UIWebView views and Safari pages, in addition to links that result in a call to openURL:, such as those that occur in Mail, Messages, and other apps.
所以基本上,假设您正在使用 Twitter 客户端并浏览时间线,您会遇到一条包含以下 YouTube 视频的推文 link:https://youtu.be/ejQod8liXm0
如果您点击它,因为它是 HTTP URL,您会希望 Safari 打开 link。但是,我认为我们所有 iOS 开发人员几乎都同意 原生应用程序更好 ,因此更好的用户体验将 官方 YouTube 应用打开视频,甚至从您的第三方客户端。
这是"Universal Links"允许的;如果 YouTube 应用程序在 iOS 上注册为负责处理 https://www.youtube.com(*) link 的应用程序,iOS 生态系统中的每个人都会受益,如果我们遵循 API 规则。如果您 运行 一个网站并且您希望您的任何内容触发您的官方 iOS 应用程序打开(如果您的用户安装了它),或者如果用户安装了该应用程序则提示用户,也会发生同样的事情喜欢安装它以获得更好的用户体验(当然也是为了帮助您的业务)。
所以,抛开所有这些,让我们回到原文:
If you instantiate a SFSafariViewController, WKWebView, or UIWebView object to handle a universal link, iOS opens your website in Safari instead of opening your app. However, if the user taps a universal link from within an embedded SFSafariViewController, WKWebView, or UIWebView object, iOS opens your app.
这意味着,如果您的用户在您的应用中点击您的内容的通用 Link(例如:http://www.your-company.com/foo), and you do not detect this in your app's code via a regular expression for example, and instead instantiate a SFSafariViewController
, WKWebView
or UIWebView
to open it as if it were a regular link to The New York Times 或其他内容,OS 将理解而不是在您的应用程序中打开它,您希望 Safari 为您处理它。记住:Universal Links 的全部目的URL 由本机应用程序而非浏览器处理,让用户获得更好的体验。
第一句是这样说的。至于第二个,它清除了一个潜在的后续问题:如果用户从嵌入式浏览器 从另一个不是我的应用程序点击通用 Link 到我的内容怎么办? 然后,句子说,OS 将正常运行:它将打开您的应用程序,遵守通用 Link 规则。
TL;DR:您还需要在代码中检测您的应用程序内容的通用 Link,并处理它们。 iOS 不会为您处理。相反,如果您告诉 OS 在您的应用程序的嵌入式浏览器中打开一个通用 Link 到您的应用程序内容,它会完全按照指示执行。
编辑: 如果您需要帮助决定是询问 SFSafariViewController
还是 -openURL:options:completitionHandler:
API 打开 URL , this link should help you; 我的建议是先使用-openURL:options:completitionHandler:
,如果不成功,再使用SFSafariViewController
或类似的。
希望这对您有所帮助,并且我已经正确理解了您的问题。
干杯!快乐 iOS 11 编程! :)
我用下面的 Swift 4 class 解决了这个问题。如果可能,它还会使用嵌入式 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)
}
}
}