在 iOS 中,应用间跳转是比较常见的,比如:广告墙推荐(推荐自家或者别人家的 App)、支付宝微信等第三方支付、微信微博等第三方登录、微信分享等等。

在 iOS 中,想要打开另一个 App、拨号、发邮件、网页等都可以通过 UIApplication 的方法实现:

1
- (BOOL)openURL:(NSURL*)url NS_DEPRECATED_IOS(2_0, 10_0, "Please use openURL:options:completionHandler: instead") NS_EXTENSION_UNAVAILABLE_IOS("");

其中,参数 URL 是指统一资源定位符,它包括

  • 协议头(scheme):用来决定查找资源的方式(比如 http://、ftp:// 等)
  • 路径(path)

注意:URL 可以没有路径(path),但是必须得有协议头(scheme)。在默认的情况下 App 是没有 URL 的,因此如果想要在 iOS 中打开一个 App,就得先设置它的 URL,并且只需要拿到它的协议头(scheme)就可以打开它了。

简单做一个应用间跳转:比如应用 Ya4iOS 跳转到应用 Yiyi,那么这个时候,得先在应用 Yiyi 中设置 URL(可以只设置协议头):

app_scheme.png

在 iOS 9,你需要在应用 Ya4iOS 中的 info.plist 文件中添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>Yiyi</string>
</array>
...
</dict>
</plist>

大概看起来是这样子的:

plist_settings.png

在应用 Ya4iOS 中添加以下代码,就可以跳转到应用 Yiyi 了:

1
2
3
4
5
6
7
8
9
10
// 1. 获取应用 Yiyi 的 URL,需要拼接
NSURL *url = [NSURL URLWithString:@"Yiyi://"];
// 2. 判断手机中是否安装了应用 Yiyi
if ([[UIApplication sharedApplication] canOpenURL:url]) {
// 3. 跳转到应用 Yiyi
[[UIApplication sharedApplication] openURL:url];
} else {
NSLog(@"error!");
}

注意:

  • 如果没有在应用 Ya4iOS 中添加 LSApplicationQueriesSchemes 的话,在 iOS 9 中会报这样的错误:
1
-canOpenURL: failed for URL: "Yiyi://" - error: "This app is not allowed to query for scheme yiyi"
  • 在 iOS 10 中,openURL: 这个方法已经被废弃,改用以下方法:
1
2
3
4
5
6
7
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
if (success) {
NSLog(@"success!");
} else {
NSLog(@"error!");
}
}];

如果希望能够像分享到微信那样,可以分享到好友列表或者分享到朋友圈,就需要微信那边在 AppDelegate 那边接受回调,我们直接按照微信的规则来编写跳转的 URL 即可。假如微信的 URL Scheme 是 weixin://,好友列表的 URL Scheme 是 weixin://Session,朋友圈的 URL Scheme 是 weixin://Timeline,那我们在跳转的地方这样写即可:

1
2
3
4
5
6
// 打开微信
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"weixin://"]];
// 打开微信的好友列表
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"weixin://Session"]];
// 打开微信的朋友圈
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"weixin://Timeline"]];

而微信那边可能是这样写的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 9.0 过时,Please use application:openURL:options:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(@"1 -> %@", url);
return YES;
}
// 9.0 过时,Please use application:openURL:options:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"2 -> %@", url);
return YES;
}
// iOS 9.0 或更高版本,都建议使用这个回调方法,具体可以进入系统文件看这 3 个方法的详细解释
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
NSLog(@"3 -> %@", url);
return YES;
}

实际上,如果希望微信那边处理完毕之后能够跳转回我们的应用,则需要按照微信的规则来做,大概是这样子:

在我们的应用设置 URL Scheme 比如 Ya4iOS,在跳转到微信的时候传递 weixin://Timeline?app=Ya4iOS 类似这样,只不过微信做了封装,我们只需要设置了我们应用本身的 URL Scheme 以及申请好的微信开发者 ID(wx12412643467c 之类的)就可以了。