背景:
iOS 微信sdk在1.8.7之后使用苹果推荐的universal link实现支付完成(成功、失败、取消)的回调。
universal link 和 url scheme是两种实现APP间跳转的方式。
Url Scheme
在自己的工程中配置url scheme,是为了让其他app能够跳转到自己的app,url scheme需要有唯一性,如果和其他app或者系统app相同,就会无法跳转。在工程中配置:
这里的配置为了让支付宝和微信支付完成后跳回到自己的app。
支付宝或者微信支付完成后,会携带支付结果跳转到我们的app中。需要在以下的方法中进行回调处理。
这里有个问题:我们使用的flutter 插件,微信和支付宝插件是两个独立的插件,那么这两个插件中的
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options
这个方法都会被回调。会不会造成冲突? 如果支付宝的回调走到微信插件的回调中,以下的方法会返回NO. 因为支付宝的回调url是"safepay://"开头的。 这里返回NO,自然就会走到支付宝插件中的该方法中,而那里会返回YES.这个方法返回NO,代表,不处理该url回调。同理微信回调也是这样。
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
下面的例子演示,其他app DemoA怎么跳转到我们的app,下面是DemoA中的跳转代码:
当然首先需要MyApp按照上面的方法配置url scheme:MyAppScheme
同时,需要将MyApp的url scheme加入到DemoA的白名单中。MyAppScheme://后面也可以带参数
#pragma mark - DemoA -> MyApp
- (IBAction)jumpToMyApp:(id)sender {
NSString *urlString = @"MyAppScheme://";//没有参数
NSURL *url = [NSURL URLWithString:urlString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
}
else {
[self showMessage:@"没有该应用"];
}
}
加入白名单的方法:
这里有个问题: 很多app都接入了支付宝、微信sdk,那为什么支付宝和微信app里面不需要注册其他app的白名单呢?原因如下:
Universal Link
苹果新推出的app之间跳转方法
应用比较广泛案例:用户分享app中某个内容到微信,用户在微信聊天中点开这个(universal link),例如:www.xxx.com/mypage?id=1… 就可以直接跳转到app中的个人主页页面!然而微信的webview中检测到uniersal link,禁止了跳转。那一般的解决方法就是:在微信浏览器网页中提示用户在safari中打开该网页,在safari中打开该网页就可以直接跳转app。
配置步骤:
1,在公司官网服务器跟域名下(尽量使用一级域名)新建 .well-known 文件夹(苹果推荐新建!!!)。在里面放入apple-app-site-association,切记没有后缀名。文件的内容是json格式,推荐使用在线 json.cn编辑。
2,苹果开发者账号后台打开identifier的associated domains。
3,xcode中添加associated domains。
4,代码中处理universal link的跳转:
//universal link的处理方式
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nonnull))restorationHandler{
return [WXApi handleOpenUniversalLink:userActivity delegate:[FluwxResponseHandler defaultManager]];
}
universal link的原理就是,用户第一次安装app后打开app,会去xcode中配置的associated domains地址下(也就是公司官网一级域名下)拉取apple-app-site-association文件,注册到系统中,这样就形成了universal link连接和app bundle id的对应。这样一来,在safari(下拉一下)或备忘录中,点击universal link就可以直接打开app了。
问题是:如果用户安装app后第一次打开app,由于各种原因(网络不好等)没有拉取到apple-app-site-association文件怎么办?网上写:苹果系统会在合适的时间再去拉取该文件。
服务器上apple-app-site-association的更新不会让iOS本地的apple-app-site-association同步更新,即iOS只会在App第一次启动时请求一次,以后除非App更新或重新安装,否则不会在每次打开时请求apple-app-site-association
别人app拿到我们的universal link,怎么使用代码跳转:
[[UIApplication sharedApplication] openURL:@"universal link" options:@{
UIApplicationOpenURLOptionUniversalLinksOnly:@YES
} completionHandler:nil];
UIApplicationOpenURLOptionUniversalLinksOnly设置为YES,表示如果打开的是一个http或者https网址,如果没有安装这个APP的话,那么就返回失败,无法打开,这是为了防止一些APP的广告,如果你只是应用间跳转,那么就设置为NO即可,因为应用件跳转不可能是一个合法的网址,并且应用间跳转不要添加特殊符号,字母就可以,比如要跳到URLSchemes为zyyc的APP,这个URLSchemes就不要写成zyy_c这样的格式,被坑了一天,添加了白名单也没用……
另外需要注意的是:微信支付回调处理需要同时处理universal link和url scheme的方式,以兼容微信app的新老版本。
我公司的app的apple-app-site-association文件:
那对于其他app或者H5,只要使用 我公司域名/iosappcams/*** 这样的链接都可以跳转到我们的APP中。
***可以用来区分不同的APP和H5,例如我们在微信开放平台注册的universal link就是:
当然也可以在apple-app-site-association文件为不同第三方配置多个不同path。
微信
微信sdk,免密签约,必须使用Universal link的方式。
微信支付和微信内H5跳转APP,可以同时使用URL Scheme和Universal link两种方式,调试过程中发现,两种方式都配置的情况下,还是走的URL Scheme.
微信内H5跳转APP,使用开放标签<wx-open-launch-app>
developers.weixin.qq.com/doc/offiacc…
iOS在杀死的情况下冷启动,微信H5跳转App需要在didFinishLaunchingWithOptions中获取启动的Url
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
NSURL *url = (NSURL *)launchOptions[UIApplicationLaunchOptionsURLKey];
_launchURL = [url absoluteString];
}
return YES;
}
参考文章:
https://www.jianshu.com/p/ef0cd17a35d6
https://segmentfault.com/q/1010000004038441
https://www.jianshu.com/p/138b44833cda
https://community.jiguang.cn/article/464296
https://my.oschina.net/jlongtian/blog/1551656