日常使用中,经常会遇到分享、支付等功能需要跳转到另一个 app 进行处理,然后处理回调信息。本篇将对这个功能进行学习。
应用间跳转是通过苹果实现的类似于路由的 URL Schemes(自定义协议头)实现的。应用B约定好打开自身的协议头,应用A则在特定的场合调用这个协议头,实现跳转。
URL Scheme
A->B
直接跳转
B中注册
要跳转到B,就得先让B注册自己的 URL Schemes。在 Info->URL Types 中新建一个:
这里的添加最终映射到的是 plist 文件中,URL Schemes 将在 plist 文件中以键值对的方式保存,可以自由的添加和删除
A中调用
B中注册好了 URL Schemes,我们可以直接在 safari 中输入 zacharyB1://
就可以打开 app 了,这也是很多h5中要打开关联的 app 都提示在 safari 中打开的原因。我们现在在A中添加跳转逻辑:
1 | - (IBAction)jumpToAppB:(id)sender { |
这里要注意一点,iOS9 后引入了白名单的概念。A在调用 canOpenURL:
方法的时候,会在A的白名单中查看是否可以跳转应用B,所以我们还要提前将B注册到A的白名单当中。具体做法就是在应用A的 plist 文件中,添加 LSApplicationQueriesSchemes
数组,然后减价键值为 zacharyB1
的字符串:
添加好白名单后,就可以正常的跳转了。
带参数的跳转
A中调用
上面是直接跳转打开应用B,但是实际情况下,我们可能要打开B的某个页面,并且要传递一些参数过去。本身 openURL
是不带参数的,我们需要按照约定的规则,将参数作为 URL 的一部分传入,由应用B自己解析。
比如区分跳转到B的某一个页面1还是页面2,我们分别定制 URL:
1 | - (IBAction)jumpToAppBPage1:(id)sender { |
B中处理
在A调起B后,B中会执行特定方法,我们可以在其中添加处理逻辑,获取参数:
1 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation |
B->A
B返回A的过程和A调用B的过程类似,相当于B主动调用A的 URL Scheme。B如何知道是哪个应用调用了它呢?这就需要A将自己的 URL Scheme 传给B。同样的,需要约定规则,比如如下:
1 | 应用B的URL Schemes://要传的参数?应用A的URL Schemes |
将应用A的 URL Scheme 在末尾传入,并且以 ?
分隔。B拿到后取出A的 URL Scheme,在必要的时候(如点击某个按钮)通过其调起应用A。
1 | - (IBAction)page1BackToAppA:(id)sender { |
Universal Links
除了 URL Scheme,iOS9中还提供了一种系统级的 APP 唤醒方式。这可以使你的应用可以通过传统的HTTP链接来启动APP(如果iOS设备上已经安装了你的app,不管在微信里还是在哪里), 或者打开网页(iOS设备上没有安装你的app)。
开启使用
首先要在开发者中心中开启这一功能:
然后在项目的配置中找到 Capabilities->Associated Domains:
以 applinks:
开头,后面跟着你的域名。这个域名必须支持 HTTPS 的 GET 请求。在第一次启动 APP 的时候,系统会自动到这个域名的根目录下,请求名为apple-app-site-association的文件,即会发送 https://domain.com/apple-app-site-association
请求。
apple-app-site-association 格式
apple-app-site-association 是一个内容为json文件,且没有后缀名的文件(不能带.json的后缀)。文件内容大致如下:
1 | { |
appID 的组成部分为:TeamID . BundleId TeamID
。其中,TeamID
可以从苹果开发账号页面也 Your Account 下查看,BundleId 就直接在工程里看了。
完成这步后,系统就将域名和 app 绑定了起来。在任何其它应用中加载这个域名下的链接都将自动打开你绑定的 app。
APP 内的处理
打开 APP 后会调用以下方法:
1 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{ |
当 userActivity
是 NSUserActivityTypeBrowsingWeb
类型, 则意味着它已经由通用链接 API 代理。这样的话, 它保证用户打开的 URL 将有一个非空的 webpageURL
属性。