常用的APP間通訊場景是支付和分享。接入支付寶等支付場景時需要跳轉到支付寶APP,完成支付后再將支付結果返回原來的APP,這樣就涉及APP間傳值。
新建App1和App2兩個應用,如果我想從App1調起App2,那么我需要添加App2的URL Scheme,不同于其他手機APPs的值,用來在App1發(fā)起openUrl方法時找到手機里的App2應用。
設置App2的URL Scheme為AppTwoScheme

App1想要調起App2時只需要通過如下方法即可
NSURL *url = [NSURL URLWithString: [NSString stringWithFormat: @"AppTwoScheme://com.zy.app1/subpath?para=%i&from=%@", 1, @"app1"]];
if ([[UIApplication sharedApplication] canOpenURL: url]) {
NSLog(@"canOpenUrl");
if (@available(iOS 10, *)) {
NSDictionary *options = @{UIApplicationOpenURLOptionsSourceApplicationKey : @YES};
[[UIApplication sharedApplication] openURL: url options: options completionHandler: nil];
}else{
[[UIApplication sharedApplication] openURL: url];
}
}
從iOS 10開始,還需要在App1中添加白名單LSApplicationQueriesSchemes數組

如果只需要從App1到App2,不需要返回,這要就可以了。
在App2的AppDelegate代理方法中接收傳入的值,如果使用SceneDelegate類,則在-(void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts代理方法中接收。
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle: @"提示" message: @"收到一條從APP1傳來的簡訊" preferredStyle: UIAlertControllerStyleAlert];
[self.window.rootViewController presentViewController: alertVC animated: YES completion: nil];
NSLog(@"absoulteString: %@", url.absoluteString);
NSLog(@"scheme: %@", url.scheme);
NSLog(@"host: %@", url.host);
NSLog(@"path: %@", url.path);
NSLog(@"query: %@", url.query);
NSLog(@"Url參數: %@", [self getURLParameters: url.absoluteString]);
if ([url.host isEqualToString: @"com.zy.app1"]) {
//從app1跳轉過來
}
return YES;
}
scheme、host和query等結果如下:


若需要將App2中的處理結果返回給App1,同樣的操作:設置App1的URL Scheme為AppOneScheme,添加App2的白名單為AppOneScheme,給App2一個觸發(fā)事件調用
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle: @"提示" message: @"收到一條從APP1傳來的簡訊" preferredStyle: UIAlertControllerStyleAlert];
[alertVC addAction: [UIAlertAction actionWithTitle: @"確定" style: UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSURL *oneUrl = [NSURL URLWithString: [NSString stringWithFormat: @"AppOneScheme://com.zy.app2?result=1"]];
if (@available(iOS 10, *)) {
[[UIApplication sharedApplication] openURL: oneUrl options: @{} completionHandler: nil];
}else{
[[UIApplication sharedApplication] openURL: oneUrl];
}
}]];
[self.window.rootViewController presentViewController: alertVC animated: YES completion: nil];
App1接收到的返回值為
-(void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
{
if (URLContexts.count > 0) {
NSEnumerator *enumerator = [URLContexts objectEnumerator];
UIOpenURLContext *urlContext = [enumerator nextObject];
NSURL *url = urlContext.URL;
NSLog(@"absoulteString: %@", url.absoluteString);
NSLog(@"scheme: %@", url.scheme);
NSLog(@"host: %@", url.host);
NSLog(@"path: %@", url.path);
NSLog(@"query: %@", url.query);
NSLog(@"Url參數: %@", [self getURLParameters: url.absoluteString]);
if ([url.host isEqualToString: @"com.zy.app2"]) {
//從app2返回的數據
}
}
}

如此,即完成了一組App間的傳值。
但要注意,如果從左上角的返回按鈕回到App1則無法將結果返回,因為沒有調用openURL吧。
