iOS Universal Links(通用链接)

iOS Universal Links(通用链接)

最近项目中,微信SDK针对 iOS 13系统版本安全性,进行了对应升级,微信SDK版本为openSDK(1.8.6)。在微信官方介绍中,1.8.6版本支持Universal Links方式跳转,对openSDK分享进行合法性校验。

本篇文章中,相关配置:

  1. 项目 BundleID:com.test123.www
  2. Universal Links :https://www.test123.com/
  3. teamID:teamID

1、微信开放平台配置Universal Links

iOS Universal Links(通用链接)_第1张图片

比如说,我配置的Links是 https://www.test123.com/

  1. 苹果对Universal Links的要求:https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content
  2. 微信对Universal Links配置要求
    a)Universal Links必须支持https
    b)Universal Links配置的paths不能带query参数
    c)微信使用Universal Links拉起第三方App时,会在Universal Links末尾拼接路径和参数,因此App配置的paths必须加上通配符**/***

确认App的Universal Links配置成功

微信使用第三方App的Universal Links唤起第三方App时,会在Universal Links末尾拼接路径和参数,因此开发者Universal Links配置必须加上通配符,并测试Universal Links拼接字符串能否唤起app

{ "appID": "teamID.com.test123.www", "paths": ["/testFolder/*","*"] }

teamID:在苹果开发者网站获取

BundleID:com.test123.www

2、生成 apple-app-site-association 文件

创建一个名字叫做apple-app-site-association,包含固定格式的json文件,该文件没有后缀名

比如:

{
    "applinks":{
        "apps":[

        ],
        "details":[
            {
                "paths":["/testFolder/*","*"],
                "appID":"TeamID.com.test123.www"
            }
        ]
    }
}

appID格式为:TeamID + . + BundleID

注意:

1、文件没有后缀名,不加`.json`后缀,MINI TYPE一定是application/json
2、`paths`是数组,下标越小匹配优先级越高
3、` appID`格式为 {teamId}.{bundleId}
4、上传到 web server 根目录下,也可以放到.well-known
5、web server 需要支持 https, 不支持任何重定向
  • 第一次启动APP的时候,它会从上面的域名请求JSON 文件 apple-app-site-association。当你第一次启动 APP,它会从 https://www.test123.com/apple-app-site-association 下载这个文件。
  • 完整网址为 https://www.test123.com/apple-app-site-association 在浏览器里,访问,可以直接下载该文件
  • 苹果在线检验 https://search.developer.apple.com/appsearch-validation-tool/ 可以测试你的association是否可用

如图:测试返回的是如下结果,说明配置成功,但你的 app 还没有上传到 App Store ,所以还有Error提示。

iOS Universal Links(通用链接)_第2张图片

3、打开Associated Domains开关,将Universal Links域名加到配置上

  • 在苹果开发者网站,同样需要打开Domains选项
  • 格式: 前缀必须为applinks:,applinks:后为你的服务器的域名 。比如 applinks:test123.com
  • domains可以添加多个

iOS Universal Links(通用链接)_第3张图片

6、配置Xcode

(1) 在 Xcode 中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序 id(如下图所示)。

iOS Universal Links(通用链接)_第4张图片

(2) 在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在 “info”标签栏的“LSApplicationQueriesSchemes“添加weixin 和weixinULAPI(如下图所示)。

iOS Universal Links(通用链接)_第5张图片

7、WXApi代码

特别注意:

必须对通用链接处理!每次分享到微信,会分享失败,重复显示“正在连接”!

//iOS 13以上版本,微信处理通用链接,会走此回调
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray> * __nullable
restorableObjects))restorationHandler {
    
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webUrl = userActivity.webpageURL;
        ZYLog(@"continueUserActivity:%@",webUrl);
    }
    
    //处理通用链接
    //当APP被UniversalLink调起后,
    BOOL ret = [WXApi handleOpenUniversalLink:userActivity delegate:self];
    ZYLog(@"处理微信通过Universal Link启动App时传递的数据:%d",ret);
    return ret;
}

//低于iOS 13版本,微信处理通用链接,会走此回调
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
    NSLog(@"options 跳转回本APP...url:%@",url);
    
    //低于iOS 13版本,这里处理通用链接回调
    if ([url.scheme rangeOfString:@"wxTest123Test123Test123"].length!=0) {
        ZYLog(@"再次跳回。。。");
        //wxTest123Test123Test123://resendContextReqByScheme?wechat_auth_context_id=123455678
        return [WXApi handleOpenURL:url delegate:self];
    }

详细代码:

// 向微信注册
[WXApi registerApp:@"wxxxxxxxxxxx" universalLink:@"https://www.test123.com/"];
#pragma mark - ******************** 微信 ********************
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return  [WXApi handleOpenURL:url delegate:self];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    NSLog(@"跳转回本APP...%@",url);
    return [WXApi handleOpenURL:url delegate:self];
}

//iOS 13以上版本,进行微信相关操作会走此回调
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray> * __nullable
restorableObjects))restorationHandler {
    
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webUrl = userActivity.webpageURL;
        ZYLog(@"continueUserActivity:%@",webUrl);
    }
    
    //处理通用链接
    //当APP被UniversalLink调起后,
    BOOL ret = [WXApi handleOpenUniversalLink:userActivity delegate:self];
    ZYLog(@"处理微信通过Universal Link启动App时传递的数据:%d",ret);
    return ret;
}

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
    NSLog(@"options 跳转回本APP...url:%@",url);
    
    //低于iOS 13版本,这里处理通用链接回调
    if ([url.scheme rangeOfString:@"wxTest123Test123Test123"].length!=0) {
        ZYLog(@"再次跳回。。。");
        //wxTest123Test123Test123://resendContextReqByScheme?wechat_auth_context_id=123455678
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    //微信支付的回调
    if ([url.host isEqualToString:@"pay"]){ //微信支付的回调
        NSString *result = [url absoluteString];
        NSLog(@"微信------%@",result);
        NSArray *array = [result componentsSeparatedByString:@"="];
        NSString *resultNumber = [array lastObject];
        NSLog(@"微信------%@",resultNumber);
        if ([resultNumber integerValue] == 0){ //成功
            //发送支付成功的通知
            //[[NSNotificationCenter defaultCenter] postNotificationName:NoticePaySuccess object:nil];
        }else if ([resultNumber integerValue] == -1) { //错误
            //发送支付失败的通知
            //[[NSNotificationCenter defaultCenter] postNotificationName:NoticePayFailure object:nil];
        }else if ([resultNumber integerValue] == -2){ //用户取消
            //发送支付取消的通知
            //[[NSNotificationCenter defaultCenter] postNotificationName:NoticePayCancel object:nil];
        }
    }
    
    
    return YES;
}

- (void)onReq:(BaseReq*)req
{
    ZYLog(@"微信请求App提供内容onReq:%@",req);
    if([req isKindOfClass:[GetMessageFromWXReq class]])
    {
        // 微信请求App提供内容, 需要app提供内容后使用sendRsp返回
        NSString *strTitle = [NSString stringWithFormat:@"微信请求App提供内容"];
        NSString *strMsg = @"微信请求App提供内容,App要调用sendResp:GetMessageFromWXResp返回给微信";
    }
    else if([req isKindOfClass:[ShowMessageFromWXReq class]])
    {
        ShowMessageFromWXReq* temp = (ShowMessageFromWXReq*)req;
        WXMediaMessage *msg = temp.message;
        
        //显示微信传过来的内容
        WXAppExtendObject *obj = msg.mediaObject;
        
        NSString *strTitle = [NSString stringWithFormat:@"微信请求App显示内容"];
        NSString *strMsg = [NSString stringWithFormat:@"标题:%@ \n内容:%@ \n附带信息:%@ \n缩略图:%u bytes\n\n", msg.title, msg.description, obj.extInfo, msg.thumbData.length];
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        //[alert show];
    }
    else if([req isKindOfClass:[LaunchFromWXReq class]])
    {
        //从微信启动App
        NSString *strTitle = [NSString stringWithFormat:@"从微信启动"];
        NSString *strMsg = @"这是从微信启动的消息";
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        //[alert show];
    }
}

#pragma mark - ******************** WXApiDelegate ********************
- (void)onResp:(BaseResp *)resp {
    /*
     enum  WXErrCode {
     WXSuccess           = 0,    成功
     WXErrCodeCommon     = -1,  普通错误类型
     WXErrCodeUserCancel = -2,    用户点击取消并返回
     WXErrCodeSentFail   = -3,   发送失败
     WXErrCodeAuthDeny   = -4,    授权失败
     WXErrCodeUnsupport  = -5,   微信不支持
     };
     */
    //微信支付的类
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回结果,实际支付结果需要去微信服务器端查询
        NSString *strMsg,*strTitle = [NSString stringWithFormat:@"支付结果"];
        if (resp.errCode == 0) {
            strMsg = @"支付结果:成功!";
            NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
            
        }else{
            strMsg = [NSString stringWithFormat:@"支付结果:失败!"];
            NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
            
        }
        
    }
    
    //微信登录的类
    if([resp isKindOfClass:[SendAuthResp class]]){
        if (resp.errCode == 0) {  //成功。
            //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。
            
        }else{ //失败
            NSLog(@"error %@",resp.errStr);
           
        }
    }

    //微信分享的类
    if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
        //微信分享 微信回应给第三方应用程序的类
        SendMessageToWXResp *response = (SendMessageToWXResp *)resp;
        NSLog(@"error code %d  error msg %@  lang %@   country %@",response.errCode,response.errStr,response.lang,response.country);
        if (resp.errCode == 0) {//成功。
            //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。
                
        }else{ //失败
           
        }
    }
}

你可能感兴趣的:(iOS Universal Links(通用链接))