一文弄懂iOS应用间跳转的scheme和Universal Links两种方案

在 iOS 中,应用间的跳转是通过 URL 来实现的,目前有两种跳转方案。

  • 应用协议:注册应用协议,即 scheme 方案。
  • 统一链接:关联通用链接,即 Universal Links 方案。

不论使用哪种方案进行跳转,处理跳转事件的方式是一样的。

一、跳转事件

因为后续的操作,都需要通过接收事件来查看运行效果,因此我们先解一下如何接收应用间跳转事件。

在 iOS 9 之后,通过实现UIApplicationDelegate协议的如下方法,可以接收应用间跳转的事件。

某些应用,设计者可能也会用这个方法里接收应用内跳转。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    NSLog(@"应用跳转:url = %@, options = %@", url, options);
    return YES;
}

在 iOS 13 之后,如果启用了“UIScene”支持的话,上述方法不会被调用,需要实现UIWindowSceneDelegate协议的如下方法,来接收应用间跳转事件。

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    UIOpenURLContext *context = URLContexts.anyObject;
    NSLog(@"应用跳转:url = %@, options = %@", context.URL, context.options);
}

UIScene 是用于支持多窗口(Multiple Windows)的技术,单窗口应用完全可以关闭它。

  1. 删除 Info.plist 中“Application Scene Manifest”字段,即对应键名为UIApplicationSceneManifest的字段。
  2. 删除UIApplicationDelegate是否实现了包含UISceneSession参数的方法。
  3. 删除UIWindowSceneDelegate的实现文件,默认为SceneDelegate.hSceneDelegate.m方法。

二、应用协议 - scheme

应用协议跳转,是目前最简便、最直接的应用间跳转方式。虽然有明显的缺点,但有不少应用依然还在采用这种方式。

  • 可能与其它应用冲突。
  • 未安装应用时,跳转需求无法落地。
  • 不够安全,不支持动态配置和控制。

1、注册协议

由于是 URL 方案,协议 scheme 命名应符合RFC-3986规范。

1、在Xcode > Targets > Info 选项卡 > URL Types 中配置。
iOS scheme 配置
2、或者,直接在Info.plist中设置。

除非复制粘贴,一般不建议这么做。

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>None</string>
        <key>CFBundleURLName</key>
        <string>demo</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>demo</string>
        </array>
    </dict>
</array>

2、使用协议

在构造NSURL时,需要添加:来表明它是 URL 中的 scheme 部分。

NSURL *url = [NSURL URLWithString:@"demo:"];
[UIApplication.sharedApplication openURL:url options:@{
    UIApplicationOpenURLOptionUniversalLinksOnly: @(NO)
} completionHandler:^(BOOL success) {
    NSLog(@"openURL: %@", success ? @"YES" : @"NO");
}];

参数 url 可以仅包含 scheme 也可以包含其它信息,但需要注意的是,大部分系统对于 URL 的长度都是有限制的(通常为1024字节),为了避免数据丢失,可以通过options参数传递数据(Web中不支持)。

  • demo:
  • demo://message
  • demo://message?id=123

options 参数目前支持提供如下两个键值。

  • UIApplicationOpenURLOptionUniversalLinksOnly 是否仅使用 Universal Links 且安装了应用时,才执行跳转。
  • UIApplicationOpenExternalURLOptionsEventAttributionKey 传递给目标应用的事件数据信息。

3、检测协议

通过 -[UIApplication canOpenURL:] 可以检测目标应用是否安装,避免跳转无法落地的问题。

需要注意的是,这个方法只能确定有应用注册了该协议,不能确定注册该协议的应用为目标应用。

NSURL *url = [NSURL URLWithString:@"demo:"];
if ([UIApplication.sharedApplication canOpenURL:url]) {
    NSLog(@"可以打开目标应用");
}

Apple 为了避免该方法被滥用,只有在预置的白名单内的 scheme,该方法才会返回正确的值。

Info.plist中,添加Queried URL Schemes配置(键为LSApplicationQueriesSchemes的数组),并将要检测的 scheme 添加其中,虽然没有官方说明,但该数组通常被认为有 50 个的数量限制。

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>demo</string>
</array>

三、统一链接 - Universal Link

统一链接 Universal Links 是当前推荐的应用跳转实现方式。

统一链接,本质其实就是以https作为 scheme 的应用协议跳转,因为默认情况下,https就是跳转 Web 应用的应用协议,也因此,通过统一链接跳转,在应用未安装时,可以将对应的网页作为落地页面。

在 iOS 中,统一链接是由系统处理的,而不是浏览器。
系统会将应用与统一链接的域名、路径进行关联,命中了关联会直接打开应用,而不需要经过浏览器中转,与 scheme 效果完全一样。

同样的,统一链接也并不是完美的。

  • 生效可能会延迟。
  • 依赖服务器。
  • 配置相对复杂。

1、准备

  • 域名。
  • 可以通过域名访问且支持 https 的 Web 服务器。
  • 交了保护费的开发者账号。

2、配置服务器

服务器必须实现如下接口,以域名example.com为例,下同。

名称
URLhttps://example.com/.well-known/apple-app-site-association
备用URLhttps://example.com/apple-app-site-association
MethodGET
Content-Typeapplication/json

接口数据示例:

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "TeamID_1.com.example.app1",
                "paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
            },
            {
                "appID": "TeamID_2.com.example.app2",
                "paths": [ "*" ]
            }
        ]
    }
}

通过如下链接来验证服务器配置是否正确,将example.com替换为实际域名。

  • https://app-site-association.cdn-apple.com/a/v1/example.com

3、配置项目

1、进入 Apple 开发者中心,配置应用的identifier开启Associated Domains能力。
app identifier 开启域名关联
2、在Xcode > Targets > Signing & Capabilities 选项卡中,添加Associated Domains能力,并关联域名。

关联域名的记录,格式为:applinks:域名

在Xcode中配置域名关联

4、Universal Link 工作流程

  1. 应用第一次启动,或者更新版本后第一次启动(实际结果,未体现在苹果官方文档上)。
  2. 系统检测到应用是否开启Associated Domains,并检查是否有applinks域名关联记录。
  3. 请求https://example.com/.well-known/apple-app-site-association查询配置文件。
  4. 如果上一步失败,则请求https://example.com/apple-app-site-association查询配置文件。
  5. apple-app-site-association注册到系统。
  6. 系统收到https的跳转请求后,先匹配已注册到系统的统一链接,如果命中,则直接打开应用,否则打开浏览器。
### iOS 应用内嵌 H5 页面跳转实现方法 为了实现在 iOS 应用中内嵌 H5 页面并能够顺利进行页面间的跳转,可以采用以下几种方式: #### 使用 `WKWebView` 加载网页 对于现代的 iOS 开发来说,推荐使用 `WKWebView` 来替代旧版的 `UIWebView`。这不仅能提供更好的性能表现,还支持更多的 HTML5 特性 JavaScript API。 ```swift import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() webView = WKWebView(frame: self.view.frame) webView.navigationDelegate = self let url = URL(string: "https://example.com")! let request = URLRequest(url: url) webView.load(request) view.addSubview(webView) } } ``` 当涉及到从 H5 页面向原生应用发送消息时,则可以通过注册自定义的消息处理器来处理这些通信请求[^1]。 #### 处理来自 H5 的事件通知 为了让 H5 可以触发特定的行为比如打开新的视图控制器或者其他操作,在 Swift 中设置相应的监听器是非常重要的。下面是一个简单的例子展示了怎样接收到来自 webview 内部发出的信息,并据此执行某些动作。 ```swift // 注册 message handler webView.configuration.userContentController.add(self, name: "share") extension ViewController: WKScriptMessageHandler { public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { guard message.name == "share", let body = message.body as? [String : Any], let tuid = body["tuid"] else { return } // Handle the received data here. print("Received share event with parameter \(tuid)") } } ``` 与此同时,在前端部分也需要相应地调整代码以便于发起这样的跨平台调用。这里给出了一段用于检测设备类型以及传递参数给宿主应用程序的例子[^2]。 ```javascript $(document).on('click','#btn',function(event){ if (navigator.userAgent.match(/iPhone|iPod|iPad/) && navigator.userAgent.indexOf('Safari') != -1 ) { const params = {'tuid': uid}; window.webkit.messageHandlers.share.postMessage(params); } else { console.log('Not an iOS device or not using Safari.'); } }); ``` 通过上述配置,就可以有效地建立起 H5 iOS 原生组件之间稳定可靠的桥梁,从而完成所需的任务流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值