最近开发时产品提出的需求:站外扫描二维码唤醒App,并携带参数跳转到App内指定页面
解决方案:Universal Links(通用链接)
iOS9之后,Apple推出的一种通用链接,能够方便的通过https链接来启动APP,通过唯一的网址,不需要特别的schema就可以链接一个特定的视图到APP。
这也就设计到universal links的几个特性:
使用Universal Links
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "2DPZ6G2N6C.com.bat100appwap",
"paths": [ "*" ]
}
]
}
}
说明:
appID:组成方式是 teamId.bundle identifier(注意点号不要漏掉)。如上面的 2DPZ6G2N6C就是teamId。登陆开发者中心,在Account - Membership里面可以找到Team ID,bundle identifier可以直接在工程里查看
paths:是一个数组类型用来指定网站路径,并且是大小写敏感的:
1.使用“*” 指定整个网站,在域名下的任何地址都可以打开App。
2. “/wwdc/news/”: 指定链接,是指只允许 你设置的域名/wwdc/news/ 可以访问。
3. /videos/wwdc/2015/ 后面跟星号表示 域名/wwdc/news/+任何内容都可访问。
4. 如果想禁止某些域名访问可以在斜杠前加NOT,如:“NOT/wwdc/news/”。
details:details字段中可以写多个{ },也可只写一个{ },根据自己项目需要配置
{
"applinks": {
"apps": [],
"details": [
{
"appID": "2DPZ6G2N6C.com.bat100appwap",
"paths": [ "*" ]
}
]
}
}
创建好apple-app-site-association文件后,将其上传到域名服务器的根目录下或者.well-known子目录下。文件是通过https访问不需要有任何重定向。然后你可以直接在浏览器中输入 域名/apple-app-site-association 或者 域名/.well-known/apple-app-site-association 下载你所上传的文件。
到这一步已经可以通过配置好的通用链接(XCode中配置的域名)来唤起App了,重新下载安装App,在Safari中输入通用链接会直接唤起App打开,如果需要传值或者打开App内的某个页面,可以通过在通用链接后面拼接自己想要的参数和想要跳转的页面路由,在原生解析后传到RN中做相应的操作,下面是我的代码实现
let iosOpenAPPUrl = `https://******/downLoad.html?route=ExtensionIndex&isInvalid=${this.isInvalid}&id=${id}`;
这是我拼接的通用链接,******部分是我配置的通用链接,后面是拼接的参数和想要跳转的App内页面路由。
当唤起App时,会触发ios原生文件AppDelegate.m中的方法
// Universal Links唤醒App触发的方法
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
// 提取url参数
NSDictionary *dict = [self getUrlParameterWithUrl:url];
// 传给react-native
[WSNotification OCsendMessageToReactNative:dict];
}
return YES;
}
// 从URL中提取参数
- (NSDictionary *)getUrlParameterWithUrl:(NSURL *)url {
NSMutableDictionary *parm = [[NSMutableDictionary alloc]init];
//传入url创建url组件类
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
//回调遍历所有参数,添加入字典
[urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[parm setObject:obj.value forKey:obj.name];
}];
return parm;
}
在application:方法中监听唤起App事件,在getUrlParameterWithUrl方法中解析出通用链接中拼接的参数,WSNotification是自己封装的一个通知方法,通过它将参数传递给React-native,具体实现可以自己百度ios原生和React-native通信。
在React-native监听,根据传过来的参数做路由跳转或传参操作
import React, { Component } from 'react';
import { NativeEventEmitter, NativeModules, } from 'react-native';
const { WSNotification } = NativeModules;
const notificationManagerEmitter = Platform.OS.toLowerCase() === 'ios' ? new NativeEventEmitter(WSNotification) : '';
componentWillMount() {
// 监听唤醒App回调
this.subscription = Platform.OS.toLowerCase() === 'ios' ? notificationManagerEmitter.addListener( 'OCSendToRN', (reminder) => {
// 跳转到推广页面
this.props.navigation.navigate(reminder.route,{id:reminder.id,isInvalid:reminder.isInvalid})
}
) : '';
}