WWDC2019:What‘s New in Universal Links

WWDC2019 Session 717 : What’s New in Universal Links

Universal Link 之前只支持 iOS tvOS 平台,现在全面登录到 macOS 平台上了,无论你是用 UIKit 还是 AppKit 开发的 Mac App 都可以使用 Universal Link

上面是 session 视频原 link ,整个视频不长,也就 20min

这一次 WWDC2019 Universal Links 主要的变化有 2 点

  • apple-app-site-association file 支持精细化地址匹配写法
  • Universal Links 支持 macOS

OverView 总览

Universal Link 的基本运作机制

  • 通过在 XCode 的 App 配置中配置了相关信息以及安全域名指定
  • 通过在 Https only 的安全域名上部署一个配置 apple-app-site-association file
  • file 中配置上丰富的 website 与 app 的链接信息
  • 在 website 与 app之间建立起了安全有效的握手机制
  • 实现 website 的 url 与 app 的直接联动

相对于自定义的 schemes 来说 Universal Link 能带给你更安全更流畅的体验

补充:schemes 上最令人诟病的就是 app 劫持,很多 app 会冒充注册知名大厂的 app scheme 从而拦截调常规的大厂 scheme 唤起,这一点在 Universal Link 就能很好的避免

apple-app-site-association file 支持精细化地址匹配

-w626

上图是用知乎的 apple-app-site-association file 的老写法示例

-w796

这是新的写法,支持了更多更强的配置能力

  • apps 这个字段只有在 iOS 上有用,tvOS/macOS 这个字段可以忽略
  • details 字段结构大幅度变化
    • 以前是字典 appID 为 Key,现在是数组,并且支持 appIDs 这样的 key,可以一套配置适配多个 appID,大幅度减少工作量
    • 新增 components 字段,可以进一步约束 Universal Link 的生效条件
      • 可以通过 / 来配置支持的 path 格式条件
      • 可以通过 # 来配置支持的锚点条件
      • 可以通过 ? 来配置支持的字段条件
      • exclude 是排除字段,符合这个条件的 Universal Link 不生效

-w794

视频中还有更详细的 components 字段配置说明,左边是 components 配置,右边是匹配的 url 格式

Universal Links 网络服务的配置建议

在部署网络服务,配置 apple-app-site-association file 的时候,苹果建议还要遵循一下几点 Tips

  • 必须支持 https:

必须是正规证书,不能使用自定义证书

  • URL 使用 ASCII 编码

因为在 URL 中会使用很多符号诸如 # ?% ,因此要使用 ASCII 编码

  • 减少 apple-app-site-association file 的大小

减少大小有助于在拥堵的网络条件下,更顺畅的生效 Universal Link。如果你的应用面向不通的国家,针对不同的国家有不同的配置文件,可以通过国家标记符来分别配置,从而让用户只下载最精简的 json file

  • apple-app-site-association file 的 download & update 策略:

当 app 安装到设备的时候,会从配置域名上下载这个 json file 到本地,从而根据配置生效相关的功能。并且设备上下载的这个 json file 会不定期的更新(亲测过,app 发布版本更新的时候也会准确触发 json file 的更新)

  • 使用 Smart Banner

网页中的 Smart Banner 与 Universal Links 一起配合使用,可以有效的引导未安装 app 的用户前往下载,已安装 app 的用户就可以顺畅的进行跳转

Universal Links 支持 macOS

在 XCode 中配置 Universal Links

-w802

  • 支持配置子域名
  • 支持配置父域名(子域名优先)
  • 支持配置特殊字符的域名,但必须 Punycode 编码

开发 Univsersal Links 的代码,支持 macOS

1
2
3
4
5
6
7
8
9
10
11
12
// Configuring Your App
func application(_ application: Application, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([ UserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return false
}
for queryItem in components.queryItems ?? [] {

return true
}

在支持 macOS 的情况下,appDelegate 的 Universal Link 的处理也是这个 delegate,区别只是 UIApplication 变为 NSApplication。

由于这个 delegate 会由很多其他的快捷方式触发,不仅仅由 Universal Link 触发,所以通过 NSUserActivityTypeBrowsingWeb 来判断来源,剩下的就是标准的 url 处理了

  • url 的失败处理 Fail Gracefully

Universal Links 生效的时候,由于外界传参是可以任意进行拼接调用的,所以需要小心的处理好各种数据,传参等原因导致的错误

macOS 下的 Universal Links 工作机制与 iOS下存在一定的差异

  • 默认打开网页,会提示用户是否需要打开app
  • 远程登录下无法生效
  • Appstore 签名 macApp 可以在下载 App 后立刻生效
  • 开发者签名的 macApp 必须在用户运行过一次后生效

在 mac app 中打开一个 Universal Link

1
2
3
4
5
6
7
8
9
10
11
// UIApplication
UIApplication.shared.open(url, options: [ .universalLinksOnly: true ]) {

}

// NSWorkspace
let configuration = NSWorkspace.OpenConfiguration()
configuration.requiresUniversalLinks = true
NSWorkspace.shared.open(url, configuration: configuration) {

}

PS: 补充文档

以前写过的一篇 UniversalLink 的部署实践:

Universal Link 部署采坑记