字节笔记本

2026年2月22日

iOS 深度跳转完全指南:Scheme 与 Universal Link 详解

本文详细介绍 iOS 深度跳转的两种实现方式:Scheme 和 Universal Link,对比它们的优缺点,并深入讲解 Universal Link 的开发配置和常见坑点。

前言

深度跳转是指点击 WAP 页面按钮,唤起对应 APP 并跳转到相应目标页面的技术。常见的应用场景包括:

  • 一键直达:点击"打开 APP"按钮,直接唤起应用并进入指定页面
  • 场景还原:未安装 APP 时引导下载,安装后仍能保持之前的浏览上下文

对于一键直达,可以使用 iOS 的 Scheme 或 Universal Link 实现;对于场景还原,则需要与前端、后台配合开发。

Scheme VS Universal Link

Scheme 的基本原理

Deeplink 相关的技术中,在 WAP 中唤起 APP 最广泛使用的是 Scheme 跳转:

javascript
location.href = 'schema://xxxx'

一般各大 APP 都会给自己做一套路由体系,可以直接在 Scheme 头后面对接路由体系:

objc
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
sourceApplication:(NSString*)sourceApplication
         annotation:(id)annotation {
    if ([[url absoluteString] hasPrefix:@"schema://"]) {
        // 路由处理
        return YES;
    }
}

Scheme 的弊端

1. 无法判断是否安装 App

浏览器没有能力判断手机是否安装了某个 App,因此采用讨巧的方法:

javascript
try {
    var appSchema = 'schema://xxxx';
    if ($.os.ios) {
        location.href = appSchema;
    } else {
        $('body').append('<iframe src="' + appSchema + '" style="display:none"></iframe>');
    }
} catch (e) {}

setTimeout(function () {
    if ($.os.ios) {
        location.href = 'https://itunes.apple.com/us/app/idxxxxxxx?mt=8';
    } else {
        location.href = 'https://xxx.xxx.xxx/xxx/xxx.apk';
    }
}, 1000);

原理

  • 首先发起跳转 Scheme
    • 如果没安装 App,会打开失败,无效果
    • 如果安装 App,会成功打开 App
  • 延迟 1000ms
    • 如果没安装 App,等延迟后会自动跳转下载
    • 如果安装 App,当前网页被暂停,延迟代码不会执行

iOS 的问题:安卓这么用挺好,但 iOS 有个讨厌的弹框。如果用户没有安装 App,会经历:

  1. Scheme 打开 App 失败,弹出错误提示框
  2. 延迟后,跳转 AppStore,再次弹出确认框

2. 被很多 App 禁止

Scheme 被广泛使用,但并不被很多 App 认可,比如微信手机百度等。这些客户端拦截了 Scheme,使得所有 Scheme 都无法生效。开发者只好针对这些特殊 UA 展现蒙层,引导用户用系统浏览器打开。

Universal Link 的优势

Universal Link 把普通 URL(http://xxx.xxx.xxx/xxx)也赋予了能打开 App 的能力:

  • 如果安装了 App,能像 Scheme 一样传递给 App
  • 如果没装 App,会继续在浏览器里跳转这个 Normal URL
  • 不同于 Scheme,在没装 App 时不会弹出讨人厌的错误框
  • 目前还没有基于 iOS 的 UI/WKWebView 的应用进行拦截,能突破微信/手百的封锁

Universal Link 开发

配置 apple-app-association

究竟哪些 URL 会被识别为 Universal Link,全看这个 apple-app-association 文件:

要求

  • 域名必须支持 HTTPS
  • 域名根目录下放这个文件 apple-app-association,不带任何后缀
  • 文件为 JSON 格式

示例(知乎的配置):

  • 知乎的 Universal Link 配置在 oia.zhihu.com 域名
  • Path 配置为 *,即所有路径都进行识别
  • 只有访问 https://oia.zhihu.com/xxxx 才会触发 Universal Link
  • 主域名 https://www.zhihu.com/xxx 不会触发

测试工具:苹果官方提供 App Search API Validation Tool 来测试配置是否正常。

配置 iOS App 工程

  1. 开发者中心证书打开 Associated Domains
  2. 工程配置 Associated Domains
  3. 将 apple-app-association 所在域名配置进去
  4. 编写 App 被唤醒后的处理逻辑:
objc
#pragma mark Universal Links
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webUrl = userActivity.webpageURL;
        [self handleUniversalLink:webUrl]; // 转化为 App 路由
    }
    return YES;
}

Universal Link 运作流程

  1. APP 第一次启动或更新版本后第一次启动
  2. APP 向工程里配置的域名发起 Get 请求拉取 apple-app-association
  3. APP 将 apple-app-association 注册给系统
  4. 由任意 WebView 发起跳转的 URL,如果命中了注册过的通用链接
  5. 打开 App,触发 Universal Link delegate
  6. 没命中,WebView 继续跳转 URL

Universal Link 采坑指南

坑点 1:跨域问题

这是最大的坑! Universal Link 必须要求跨域,如果不跨域就不生效(iOS 9.2 之后的改动)。

规则

  • 假如当前网页的域名是 A
  • 当前网页发起跳转的域名是 B
  • 必须要求 B 和 A 是不同域名,才会触发 Universal Link
  • 如果 B 和 A 相同,只会继续在当前 WebView 里面跳转

知乎的解决方案

  • 主域名 www.zhihu.com 用于正常网页访问
  • 单独准备 oia.zhihu.com 域名专为 Universal Link 使用
  • 这样在任何活动 WAP 页面里,都能顺利让 Universal Link 生效

坑点 2:apple-app-association 文件覆盖

问题:多个产品线共用机房集群时,如果都上传同名文件到根目录,会发生覆盖。

解决方案

  1. 共用同一个文件:将多个 JSON 合并,因为内容里有 App 的 Bundle ID 区分
  2. 接入层分发:不同域名在接入层分发不同的 JSON 文件

隐藏的坑:文件被覆盖后,用户必须重新安装 App 或更新 App 版本才能恢复。

坑点 3:用户行为导致失效

Universal Link 触发后打开 App,状态栏右上角会有文字提示"来自 XX App",点击可快速返回原 App。

问题:如果用户点了返回,苹果会记住这个行为,认为用户不需要跳出原 App,因此这个 App 的 Universal Link 会被关闭,再也无效。

恢复方法:让用户重新用 Safari 打开 Universal Link 页面,点击 Smart Bar 上的按钮重新开启。

统一 WAP & APP 体验

Universal Link 的域名通常没有实际页面,如果没安装 App 会 404。处理方法是将这个地址重定向到下载页面。

总结

特性SchemeUniversal Link
实现复杂度简单较复杂
判断是否安装 App不能能(通过跨域)
微信/手百支持被拦截支持
未安装 App 体验有错误弹框正常跳转网页
需要 HTTPS
需要前端配合

Scheme 和 Universal Link 各有适用场景。如果只是想简单实现 WAP 打开 App,Scheme 就够了;如果需要更好的用户体验,特别是要在微信等环境中使用,Universal Link 是更好的选择。

深度跳转的运用不仅限于唤起 APP,还可以实现一链直达、场景还原等更丰富的功能。


原文来源:极光社区 - 好好搬砖

分享: