跳转APP的方式目前主要有两种:URL Scheme和Universal Links
一、URL Scheme
- scheme是iOS9之前比较主流的一种跳转方案了, 更多的是用在了两个APP相互跳转中。也可以在Safari中输入schema://跳转到App内部。
- scheme跳转app会有提示框提示取消或者打开,如果没有安装app的会提示框提示无法打开网页(这一点不是很友好)。
1、app之间跳转:app1跳转至app2并传值
- 在app1的target → info → url type 里创建一个url scheme为com.cs.app1(这个是app1的scheme)
- 在app2的target → info → url type 里创建一个url scheme为com.cs.app2(这个是app2的scheme)
- 在app1的info.plist里创建白名单Queried URL Schemes里添加app2的scheme
- 在app2的info.plist里创建白名单Queried URL Schemes里添加app1的scheme
设置好以上步骤之后,在app1里完成如下代码(app2雷同)
//app1跳转app2方法
- (void)pushApp2:(UIButton *)sender
{
NSURL *url = [NSURL URLWithString:@"com.cs.app2://cs?name=xiaoa&age=10&sex=1&address=22222"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
//设备安装了app2 //打开url
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}else {
//设备没有安装app2, 打开AppStore去下载
NSString *appid = @"xxx";
NSString *str = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/cn/app/id%@", appid];
NSURL *url = [NSURL URLWithString:str];
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}
在app2的AppDelegate里完成接收(app1雷同)
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
//将url转为字符串
NSString * urlString = url.absoluteString;
//判断是通过什么跳转过来的
if ([urlString containsString:@"com.cs.app2"] ) {
NSLog(@"返回值转字典___%@",[self queryToDict:url.query]);
}
return YES;
}
//query转字典
- (NSDictionary *)queryToDict:(NSString *)query
{
if (query.length == 0 || [query isEqualToString:@"nil"] || [query isEqualToString:@"null"] || [query isEqual:[NSNull null]]) {
return nil;
}else{
NSMutableDictionary * paramsDict = [NSMutableDictionary dictionary];
NSArray * temp = [query componentsSeparatedByString:@"&"]; //根据&分割字符串
for (NSString * str in temp) {
NSArray * tempStr = [str componentsSeparatedByString:@"="]; //根据=分割字符串
[paramsDict setObject:tempStr[1] forKey:tempStr[0]];
}
return [paramsDict copy];
}
}
2、Safari跳转app
按照app之间的跳转方法设置好url type后,只需调用url = com.cs.app1://cs?name=xiaoa&age=10&sex=1&address=22222 即可。
* 注意:
当设置的url type有大写字母,例如:com.cs.App1 时,在AppDelegate里接收数据判断url.absoluteString时,当app之间跳转时区分大小写(返回com.cs.App1),Safari跳转app时不区分大小写(返回com.cs.app1)。
二、Universal Links
- 先看一下官方文档
- Universal Links(通用链接)是iOS9.0出的技术。如果我们的应用支持通用链接,那么就可以通过https链接来打开APP(手机中已经安装此APP),或者跳转到https链接(手机中没有安装此APP),必须是https。
1、生成 apple-app-site-association 文件
【原理】:在第一次安装APP的时候,手机的iOS系统会去指定的路径(这个路径是后面后端开发人员给的)下载apple-app-site-association文件。通过这个文件,iOS系统就会知道哪些URL是Universal Links,哪些不是Universal Links。从而我们指定的路径可以发生跳转。这个apple-app-site-association文件需要开发者去创建和放到一个苹果可以访问的服务器上。这个过程在xcode调试的时候也会发生。
新建一个名字为apple-app-site-association的纯文本文件(Json格式),不要有任何后缀,文件内容如下:
{
"applinks": {
"apps": [], //是限制只能在这几个app中使用, 基本是不填写,所以是空数组
"details": [ //如果有多个App需要支持Universal,details数组中可配置多个App的信息
{
"appID": "ABCD1234.com.apple.cs1", //TeamID.BundleID格式自行替换TeamID和BundleID
"paths": [ "/AHost/*", "/BHost/*"] //path 过滤需要处理的地址,不需要过滤处理则配置通配符*
},
{
"appID": "EFGH5678.com.apple.cs2",
"paths": [ "*" ]
}
]
}
}
- appID:组成方式是 TeamID.BundleID。登陆开发者中心,在Account → Membership里面可以找到Team ID。
- paths:设定App支持的路径,只有这些设定的路径的链接,才能被App所处理。通配符*代表支持域名下所有链接。如果是一个服务器对应一个APP跳转,那么这里其实填写一个 “ * ” 就可以了。
如果一个服务器支持多个APP跳转,则需要用不同的专用路径节点(填写 “ /节点/ * ”)去互相屏蔽。比如地址:https://cs.com/AHost/XXX(paths填写 " /AHost/ * "只能用于A应用的跳转;地址 https://cs.com/BHost/XXX(paths填写 " /BHost/ * ")只能用于B应用的跳转。
* 注意:配置apple-app-association
- 域名必须支持https
- 域名根目录下放这个文件apple-app-site-association,不带任何后缀
- 文件为json格式保存为文本即可
- json按着官网的要求填写即可
- 测试是否正确,直接访问域名+配置文件名如果能正确访问则放置的位置是正确的。例如你想通过访问”https://cs.com/xxx“来打开app,那么你要把配置文件放在”https://cs.com/“对应服务器根目录,通过访问”https://cs.com/apple-app-association“能直接访问配置文件则是正确的。
2、apple-app-site-association文件的存放
这个文件创建好之后,交给后端人员。让他们把这个文件放到指定的url的根目录下(URL不一定要指定,可以后端人员给啥我们就用啥也行。这个URL在配置XCode会用到)。这个根目录下除了放这个文件不要放其他东西。我们的URL是 https://cs.com/。
【验证】:验证后端是否正确放置的方法,这是浏览器输入这个地址,会直接下载apple-app-site-association文件。如果没有下载到这个软件,说明服务器配置不对。
可以使用apple的验证网站来验证文件是否能够被访问到。出现Error no apps with domain entitlements 是因为还没有发布,出现404错误,则说明apple-app-site-association文件未上传成功或者使用上面的域名不能访问到。
* 注意:
对于paths有填写专用路径节点的情况(比如我这里写的【"paths": [" /AHost/* "]】), 服务器不用在这个路径下添加真实的文件访问路径!访问applinks这个域名网址的时候,找不到的话不要重定向!!访问applinks网址的时候,找不到的话不要写一个专门的空白页!
3、Identifiers、Profiles相关配置
- 登录Apple Developer,选择Identifiers,在Capabilities里勾选Associated Domains 然后点Save保存。
- 选择Profiles重新选择上步设置好的Identifiers,之后下载配置文件双击安装。
4、app相关配置
- 在target → signing&capabilities → associated domains里添加我们要访问的地址的url。
配置associated domains的applinks,格式为:“applinks:xxx”。这里的xxx为一个域名,没有“https://”前缀,也没有“/”后缀。
例如:我们访问的地址是https://cs.com/AHost/XXX,在associated domains里添加:applinks:cs.com 即可。 - 然后在我们xxx.entitlements文件中查看associated domains里是否正确,不正确就修改。
- 在AppDelegate里接收处理如下:
//Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler
{
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *webpageURL = userActivity.webpageURL;
NSString *host = webpageURL.host;
// 在这里写需要的逻辑,比如跳转到某个详情页
if ([host isEqualToString:@"cs.com"]) {
} else{
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:webpageURL options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:webpageURL];
}
}
}
return YES;
}
5、完成跳转
- 安装了 App 时,通过 domain + path ,系统软件内部能够直接跳转到 App。
- 未安装 App 时,通过 domain + path ,跳转到 Safari 打开对应的引导页。
例如:点击 https://cs.com/AHost/xxx 即可跳转我们设置好的domain的app。
https://+applinks配置的域名+apple-app-site-association里的paths
* 注意:
首先如果使用 Universal Link ,那么就只用使用 domain/path 的路径来完成跳转。另外,又需要一个引导页,所以这个引导页必须发布到后端服务器对应的 path 中,或者使用前端路由到这个引导页。
6、最后问题
有人说:因为xcode的签名用的自动签名(即勾选了Automatically manage siging),导致iOS 系统 直接没有在APP 安装的时候去请求apple-app-site-association文件。【解决】:取消勾选Automatically manage siging。
apple-app-site-association文件改动后重新放到服务器。电脑浏览器下载下来的 apple-app-site-association文件依旧是修改前的数据。浏览器清理缓存后,下载下来的最新的apple-app-site-association文件。