React-native 实现iOS端唤起App

最近开发时产品提出的需求:站外扫描二维码唤醒App,并携带参数跳转到App内指定页面

  • 解决方案:Universal Links(通用链接)

    iOS9之后,Apple推出的一种通用链接,能够方便的通过https链接来启动APP,通过唯一的网址,不需要特别的schema就可以链接一个特定的视图到APP。
    这也就设计到universal links的几个特性:

    1. Unique:唯一性,不像自定义Url schemes那样,因为他使用到了你网站的http或者https链接
    2. Secure:安全性,当用户安装应用时,iOS会检测你上传到服务器上的文件,以确保你的网站允许其代表应用打开你的应用。
    3. Flexible:灵活性,当没有安装你的app时universal links也是可以正常使用的,当点击link时会直接在safari中打开url(当没有app时,我的处理方法是在打开的url中跳转到Appstore)。
    4. Simple:一个url可以为app和web提供服务。
    5. Private:其他app可以与你的app通信,不需要知道你的应用程序是否安装
  • 使用Universal Links

    1. 首先你需要有一个https开头的域名,并且具有SSL证书
    2. 打开XCode项目配置中的Associated Domains,在其中的Domains中填入你想支持的域名,必须以applinks:为前缀。
      配置项目中的Associated Domains:
  1. 创建一个内容为json格式的文件,苹果将会首次下载App的时候,从我们在项目配置的域名请求这个文件。文件名必须为apple-app-site-association,没有后缀名,格式:
{
    "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 下载你所上传的文件。

  • 传参到App

到这一步已经可以通过配置好的通用链接(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})
            }
        ) : '';
}

至此这个需求就完成了,但也有一些问题,做完后发现在 微信QQ等某些浏览器 中也无法直接通过通用链接唤起App,也需要再打开浏览器访问通用链接才能做跳转,我以我就只能又加了一个引导页来引导用户在浏览器中打开
React-native 实现iOS端唤起App_第1张图片
不知道是不是微信QQ现在把通用链接也给禁止掉了,如果有知道原因的朋友欢迎留言交流。

  • 更新:
    后面发现导致不能跳转的问题是因为没有在微信开放平台配置设置好的通用链接,所以导致无法跳转。

你可能感兴趣的:(react-native开发,ios)