iOS scheme跳转机制

本文详细介绍了iOS中应用间通过URL Scheme进行跳转的机制,包括注册URL Scheme的两种方法和实际使用场景。内容涵盖从一个应用跳转到另一个应用、指定界面、回退原应用、传递参数以及通过网址打开APP。文中还特别提到在iOS 9以后的权限设置要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

苹果手机中的APP都有一个沙盒,APP就是一个单独个体,信息独立,相互是不可以进行通信的.但是iOS的APP可以注册自己的URL Scheme,URL Scheme是为方便App之间相互调用而设计的.我们可以通过系统的openURL来打开该APP,并可以传递一些参数,URL Scheme必须能唯一表示一个APP,如果你设置的URL Scheme和逼得APP的URL Scheme冲突时,你的APP不一定会被启动起来.因为当你的APP在安装的时候,系统里面已经注册了你的URL Scheme.一般情况下,是会调用先安装的APP.但是iOS的系统APP的URL Scheme肯定是最高的,所以我们定义URL Scheme的时候,尽量避开系统APP已经定义过的URL Scheme

URL Scheme的命名应该是只能纯英文字符,而不能含有下划线或者数字

注册URL Scheme

方法一

在 TARGETS -> Info -> URL Types 点击添加
在这里插入图片描述

方法二

在info.plist中右击,选中
在这里插入图片描述
Add Row选项,然后输入URL types,类型为 Array

URL Identifier是自定义的 URL scheme 的名字,一般采用反转域名的方法保证该名字的唯一性,比如 com.DemoB.www,不过在iOS中打开一个应用程序只需要拿到这个应用程序的协议头(URL Scheme)即可,所以我们只需配置应用程序的协议头即可。一个应用是可以有多个URL Schemes的

使用

1. 应用A跳转到应用B

这里创建了两个应用:DemoA 和DemoB,DemoB注册了Scheme为"DemoBScheme",下面来实现DemoA→DemoB的跳转

#pragma mark - DemoA -> DemoB
- (IBAction)jumpToDemoB:(id)sender {
    NSString *urlString = @"DemoBScheme://";//没有参数
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
        }];
    }
    else {
        [self showMessage:@"没有该应用"];
    }
}

分别运行两个应用,然后在DemoA中点击相应的按钮跳转到DemoB,会发现并不能跳转,因为在iOS9以后,如果使用canOpenURL:方法,改方法所涉及的URL Scheme必须在Info.plist中将它们列为白名单,否则不能使用

在info.plist中添加LSApplicationQueriesSchemes字段,该字段对应的是数组类型,然后添加键值DemoBScheme(DemoB的Scheme)
在这里插入图片描述
然后运行,点击按钮就可以跳转到demoB

2. 跳转到指定界面

有的时候我们需要跳转到某个应用的特定页面,比如分享的时候需要分享到朋友圈页面

  1. 首先在DemoB中创建PageOne和PageTwo页面
    . 在 DemoA中的点击事件中,我们可以修改urlString为 DemoBScheme://page1,其中DemoBScheme:// 是DemoB应用的scheme ,page1是与DemoB约定好的跳转到PageOne页面的标识符
#pragma mark - 跳转到pageOne页面
- (IBAction)jumpToPageOne:(id)sender {
// DemoBScheme:是DemoB应用的scheme page1是与DemoB约定好的跳转到PageOne页面的标识符 ?是分割符(当然也可以用其他符号作分割),在DemoB中通过分隔符来截取DemoA的scheme, DemoAScheme是自己的scheme,用来从DemoB跳转回来
   NSString *urlString = @"DemoBScheme://page1?DemoAScheme";
   NSURL *url = [NSURL URLWithString:urlString];
   if ([[UIApplication sharedApplication] canOpenURL:url]) {
       [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
           
       }];
   }
   else {
       [self showMessage:@"没有该应用"];
   }
}
  1. 在 DemoB的appdelegatete中实现application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    // 1.获取导航栏控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 2.获得主控制器
    UIViewController *mainVc = [rootNav.childViewControllers firstObject];
    
    // 3.每次跳转前必须是在跟控制器(细节)
    [rootNav popToRootViewControllerAnimated:NO];
    
    if ([url.absoluteString containsString:@"page1"]) {//与DemoA约定好的字符
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else if ([url.absoluteString containsString:@"page2"]) {
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"打开啦"
                                                            message:[NSString stringWithFormat:@"scheme - %@,\n host -- %@,\n  query -- %@",url.scheme,url.host,url.query]
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
        NSLog(@"query -- %@", url.query);
        [alertView show];
    }
    return YES;
}

这样就实现了DemoA跳转到DemoB中某个特定页面

iOS 9.0之前应在- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 方法中设置

3. 从DemoB返回到DemoA

上面讲了从DemoA跳转到DemoB,有的时候在跳转完之后需要再跳回到原本的app,比如分享完成之后会让选择返回到原来的app还是留在微信

  1. 从某个应用跳转到另一个应用上面已经讲过了,现在要从DemoB回到DemoA的话首先也是为DemoA注册URL Scheme,然后再DemoB的info.plist中设置白名单,把DemoA的Scheme添加进去
  2. 在我们从DemoA跳转到DemoB的时候,我们应该顺便把DemoA的Scheme传递过去
#pragma mark - 跳转到pageOne页面
- (IBAction)jumpToPageOne:(id)sender {
    //我们想要从应用B再跳转回应用A,那么在跳转到应用B的时候,还应将应用A的URL Schemes传递过来。这样我们才能判断应该跳转回哪个应用程序。
//    这样我们指定一个传递URL的规则:协议头://应用B的URL Schemes?应用A的URL Schemes。即:AppB://Page1?AppA。
//是DemoB应用的scheme page1是与DemoB约定好的跳转到PageOne页面的标识符 ?是分割符(当然也可以用其他符号作分割),在DemoB中通过分隔符来截取DemoA的scheme, DemoAScheme是自己的scheme,用来从DemoB跳转回来
    NSString *urlString = @"DemoBScheme://page1?DemoAScheme";// DemoBScheme:
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
            
        }];
    }
    else {
        [self showMessage:@"没有该应用"];
    }
}
  1. 在 DemoB中的- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options 方法中我们把收到的url传递给PageOne页面
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    // 1.获取导航栏控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 2.获得主控制器
    UIViewController *mainVc = [rootNav.childViewControllers firstObject];
    
    // 3.每次跳转前必须是在跟控制器(细节)
    [rootNav popToRootViewControllerAnimated:NO];

    if ([url.absoluteString containsString:@"page1"]) {//与DemoA约定好的字符
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else if ([url.absoluteString containsString:@"page2"]) {
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"打开啦"
                                                            message:[NSString stringWithFormat:@"scheme - %@,\n host -- %@,\n  query -- %@",url.scheme,url.host,url.query]
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
        NSLog(@"query -- %@", url.query);
        [alertView show];
    }
    return YES;
}
  1. 在DemoB的pageOne页面的点击事件中通过约定好的切割符号截取DemoA的Scheme
#pragma mark - 返回DemoA
- (IBAction)backDemoA:(id)sender {
    // 1.拿到对应应用程序的URL Scheme 通过约定好的分割符?切割
    NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
    NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
    
    // 2.获取对应应用程序的URL
    NSURL *url = [NSURL URLWithString:urlString];
    
    // 3.判断是否可以打开
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    }
}

4. 通过URL传参

. 有时候我们跳转另一个APP的时候需要传递一些参数,让另一个APP根据我们传递的参数做出相应的行为

传参格式:

“DemoBScheme://?name=lwy&phone=110”
和平时的get请求传参是一样的

  1. 跳转的时候传参
#pragma mark - DemoA -> DemoB
- (IBAction)jumpToDemoB:(id)sender {
//    NSString *urlString = @"DemoBScheme://";//没有参数
    NSString *urlString = @"DemoBScheme://?name=lwy&phone=110";//后面拼接参数
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
            
        }];
    }
    else {
        [self showMessage:@"没有该应用"];
    }
}
  1. 在demoB中的- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options方法可以获取到参数
 NSString *query = url.query;

5. 通过网址打开APP

网页打开app也是根据app的协议头(URL scheme)来区分打开的是哪一个app的,我们直接在浏览器上复制粘贴我们的url scheme ,系统会自动弹框提醒是否打开本应用,跟DemoA跳转到DemoB的跳转是一样的, 当然网页传参跟app跳转传参都是一样的格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值