iOS 唤起第三方App
iOS是一个封闭的系统,应用之间是不可以互相读取文件的。
实现途径:
URL Scheme
是苹果为方便app之间互相调用而设计的。
- 你可以通过一个类似URL的链接,通过系统的OpenURL来唤起该App,并可以传递一些参数。
- 要求:每个URL必须能唯一标识一个App,如果你设置的URL与别的APP的URL冲突,此时,你的APP不一定会被调用起来。
例如:下列常用URL Scheme
//微信URLscheme
@"weixin://app/%@/pay/?nonceStr=%@&package=Sign%%3DWXPay&partnerId=%@&prepayId=%@&timeStamp=%@&sign=%@&signType=SHA1"
//高德地图
@"iosamap://path?sourceApplication=ApplicationName&sid=BGVIS1&slat=%f&slon=%f&sname=当前位置&did=BGVIS2&dlat=%f&dlon=%f&dname=%@&dev=0&m=0&t=0"
//百度地图
@"baidumap://map/direction?origin=%f,%f&destination=latlng:%f,%f|name=%@&mode=driving&coord_type=gcj02"
//腾讯地图
@"qqmap://map/routeplan?from=当前位置&fromcoord=%f,%f&type=drive&tocoord=%f,%f&to=%@&coord_type=1&policy=0"
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]]; //唤起浏览器 打开网页
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://158********"]]; //唤起发送信心功能
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://158********"]]; //唤起拔打电话功能
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://362****@qq.com"]]; //唤起邮件功能
实例教学: App1 唤起 App2
创建两个app: App1唤起方 App2接收方
APP2_接收方需要做的事情:
(1)设置URL Scheme
-
第一种方法:info.plist
URL Schemes:唯一性
-
URL identifier:可以是任何值,但建议用“反域名”(例如 “com.fcplayer.testHello”)
-
第二种方法: Target—>Info—>URL Types
URL Schemes:唯一性
-
identifier:可以是任何值,但建议用“反域名”(例如 “com.fcplayer.testHello”)
(2) 在AppDelegate.m里面增加回调方法
#pragma mark --回调方法
/// iOS 9.0+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
// Keys for application:openURL:options:
UIApplicationOpenURLOptionsSourceApplicationKey // value is an NSString containing the bundle ID of the originating application
UIApplicationOpenURLOptionsAnnotationKey // value is a property-list typed object corresponding to what the originating application passed in UIDocumentInteractionController's annotation property
UIApplicationOpenURLOptionsOpenInPlaceKey // value is a bool NSNumber, set to YES if the file needs to be copied before use
}
/// iOS 2.0–9.0
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
}
/// iOS 4.2–9.0
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
//通过sourceApplication来判断来自哪个app以决定要不要唤醒自己的app
if ([sourceApplication isEqualToString:@"Bundle identifier"])
{
NSLog(@"%@", sourceApplication); //来源于哪个app(Bundle identifier)
NSLog(@"scheme:%@", [url scheme]); //url scheme
NSLog(@"query: %@", [url query]); //可以通过[url query]来获得查询串 (传递参数)
return YES;
}
else{
return NO;
}
}
APP1_唤起方需要做的事情:
1.唤起方法:
唤起方直接在点击事件里调用唤起方法:
/// 三个方法:
/// iOS 3.0+
- (BOOL)canOpenURL:(NSURL *)url;
/// iOS 10.0+
- (void)openURL:(NSURL *)url options:(NSDictionary *)options completionHandler:(void (^)(BOOL success))completion;
/// iOS 2.0–10.0
- (BOOL)openURL:(NSURL *)url;
//e.g. 唤起第三方App
- (void)evokeOtherApp {
//app2是应用的唯一的scheme
//scheme 必须是“app2://lanch” “weixin://app”类似的格式:
NSURL *url = [NSURL URLWithString:@"app2://lanch?key=param"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if ([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) {
//iOS 10.0+
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
}else{
//iOS 2~10
[[UIApplication sharedApplication] openURL:url];
}
}
else
{
//一般是没有安装
NSLog(@"跳转下载app链接");
}
}
2.sheme设置
如果你是iOS 9.0以上的系统,有时候会报错:
2017-01-05 11:06:24.343 APP1[235:48284] -canOpenURL: failed for URL: "app2://lanch?key=param" - error: "This app is not allowed to query for scheme app2"
因为:iOS 9.0以上的系统需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查唤起的第三方应用是否安装。受此影响,当你的应用在iOS 9中需要使用 QQ/QQ空间/支付宝/微信SDK
的相关能力时,需要在“Info.plist”里增加白名单:
key>LSApplicationQueriesSchemes
wechat
weixin
sinaweibohd
sinaweibo
sinaweibosso
weibosdk
weibosdk2.5
mqqapi
mqq
mqqOpensdkSSoLogin
mqqconnect
mqqopensdkdataline
mqqopensdkgrouptribeshare
mqqopensdkfriend
mqqopensdkapi
mqqopensdkapiV2
mqqopensdkapiV3
mqzoneopensdk
wtloginmqq
wtloginmqq2
mqqwpa
mqzone
mqzonev2
mqzoneshare
wtloginqzone
mqzonewx
mqzoneopensdkapiV2
mqzoneopensdkapi19
mqzoneopensdkapi
mqzoneopensdk
alipay
alipayshare
解决方案:
(1)在Info.plist里,配置支持http协议:
NSAppTransportSecurity
NSAllowsArbitraryLoads
`
(2)在Info.plist里,配置scheme到LSApplicationQueriesSchemes,也就是白名单:
LSApplicationQueriesSchemes
app2
app3
app4
(3)延伸...?
// 代码动态把key加入白名单(不可行)
var info = Bundle.main.infoDictionary
guard var array:[Any] = info?["LSApplicationQueriesSchemes"] as? [Any] else {return}
array.append(iosKey)
print(array)
var info2 = Bundle.main.infoDictionary
print(info2)
3.没有安装的处理
控制台输出错误:
2017-01-05 11:22:30.741 APP1[252:51626] -canOpenURL: failed for URL: "app3://lanch?key=param" - error: "(null)"
2017-01-05 11:22:30.746 APP1[252:51626] -canOpenURL: failed for URL: "app3://lanch?key=param" - error: "(null)"
2017-01-05 11:22:30.746 APP1[252:51626] [[UIApplication sharedApplication] canOpenURL:url] = 0
一般是没有安装App,可以跳转下载链接。
Demo下载地址:
链接: https://pan.baidu.com/s/1kViBtS7 密码: kvid