iOS URL Schemes实现APP之间的跳转

作者: phzean | 来源:发表于2016-04-07 11:24 被阅读2903次

一、应用场景

我们的APP有时候想直接去到设置页面,程序退到后台进入设置页面然后又重新打开,这样子总是感觉多做了很多事情。有一个比较常见的例子就是一开始的时候用户关闭了APP的通知功能,APP就需要加个直接去到自己APP打开通知开关的页面。APP之前的跳转也是很常见的。以此知道这个知识点还是比较需要的。

二、URL Schemes 配置

配置

说明:

  1. prefs“实现跳转至苹果内置程序的url scheme,不可改变
  2. phzAppJumpDemo: 标识该应用程序的url scheme,尽量保持它的唯一性
ios9之后需要添加跳转白名单

Source Code模式打开info.plist文件,添加一下这个LSApplicationQueriesSchemes,里面的数组就是需要跳转的APP

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weibosdk</string>
        <string>pcbabybrowserbeta</string>
        <string>pcbabybrowserpub</string>
        <string>tencentopenapi</string>
        <string>mqzone</string>
        <string>wtloginmqq2</string>
        <string>mqqbrowser</string>
        <string>mqqwpa</string>
        <string>mqqapi</string>
        <string>mqq</string>
        <string>mqqopensdkapiV3</string>
        <string>mqqOpensdkSSoLogin</string>
        <string>mqqopensdkapiV2</string>
        <string>qqplugin</string>
        <string>sinaweibo</string>
        <string>weixin</string>
        <string>taobao</string>
        <string>tmall</string>
        <string>openApp.jdMobile</string>
    </array>

另外一种配置 URL types

三、代码解释

我们用到的是UIApplicationopenURL方法

  1. 跳转到内置程序:prefs:root=General。重点是root的值,具体的可以看下后面提供的一些值,如果有不能用的替换成正确的就ok了

  2. 跳转到对应app的某个系统位置:比如定位、通知位置等.prefs:root=NOTIFICATIONS_ID&&path=com.tencent.mqq后面的path就是需要打开的APP的bundle id (程序的后面有给出获取bundle id的代码),root的值跟第一点提到的是一致的

  3. 跳转到某个app里面:需要用到的就是上面提到的phzAppJumpDemo ,如果发现有两个相同的url scheme,会打开最近一次启动过的app

  4. openUrl还可以实现打开mail、电话、sms、Safari等

     调用自带mail:
     [[UIApplicationsharedApplication] openURL [NSURLURLWithString:@"mailto://邮箱"]];
    
     调用电话phone:
     [[UIApplication sharedApplication] openURL:[NSURLURLWithString:@"tel://电话"]];
    
     调用SMS:[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:@"sms://号码"]];
    
     调用自带浏览器safari:
     [[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"http://www.baidu.com"]];
    
     调用Remote:[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:@"remote://***"]]; 
    

四、代码块

1、跳转到系统应用,ios11之后只能跳转到设置首页以及对应APP的权限详情页

如何检测iOS里安装的其它软件?
iOS 获取手机上已经安装的应用
介绍runtime方法的一个demo

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray *nameArr = @[@"setting",@"general",@"location",@"tencentqq",@"safari",@"anApp"];
    for (int i = 0; i < nameArr.count; i ++) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectMake(100, 60 + 35 * i, 100, 30);
        NSString *nameS = nameArr[i];
        [button setTitle:nameS forState:UIControlStateNormal];
        button.tag = nameS.hash;
        button.backgroundColor = [UIColor cyanColor];
        [button addTarget:self action:@selector(entrePage:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    [self getAllBundleIdInDevice];
}
/**
 prefs这个前缀是固定的
 */
- (void)entrePage:(UIButton *)button {
    NSInteger tag = button.tag;
    if (tag == @"setting".hash) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    } else if (tag == @"general".hash) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=General"]];
    } else if (tag == @"location".hash) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
    } else if (tag == @"tencentqq".hash) {
        // 跳转到对应app的某个系统位置:比如定位、通知位置等
        //root的值是可以改变的(参见location_prefs文件中的root值) , path 就是app的bundle id
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=NOTIFICATIONS_ID&&path=com.tencent.mqq"]];
    } else if (tag == @"safari".hash) {
        // 跳转到safari
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://blog.csdn.net/likendsl/article/details/7553605"]];
    } else if (tag == @"anApp".hash) {
        // 跳转到某个app里面:其实是相当于打开推送消息
        // 这样有个问题,跳转过去后设备左上角没有返回到上个页面的按钮?iPhone6s ios9.2.1
        //如果有两个一样的Url Schemes 跳转的最近一次启动的app
        NSURL *myURL = [NSURL URLWithString:@"phzAppJumpDemo://"];
        [[UIApplication sharedApplication] openURL:myURL];
    }
}


//获取设备上的bundle id 需要引入这个类 #import <objc/runtime.h>
- (void)getAllBundleIdInDevice {
    Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
    NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
    NSLog(@"apps: %@", [workspace performSelector:@selector(allApplications)]);
}
2、一个跳转到淘宝的示例

iOS 跳转淘宝、天猫、京东商品详情页

+ (BOOL)jumpToTaobaoLink:(NSString *)toUri {
    if (0 == toUri.length) {
        return NO;
    }
    
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"taobao://"]] && ([toUri hasPrefix:@"http://"] || [toUri hasPrefix:@"https://"])) {
        NSURL *oriUrl = [NSURL URLWithString:toUri];
        if ([[oriUrl host] rangeOfString:@"taobao.com"].location != NSNotFound) {
            NSString *openUrl = nil;
            if ([toUri hasPrefix:@"http://"]) {
                openUrl = [toUri stringByReplacingCharactersInRange:NSMakeRange(0, @"http://".length) withString:@"taobao://"];
            } else if ([toUri hasPrefix:@"https://"]) {
                openUrl = [toUri stringByReplacingCharactersInRange:NSMakeRange(0, @"https://".length) withString:@"taobao://"];
            } else {
                openUrl = toUri;
            }
            
            if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:openUrl]]) {
                // 淘宝客户端打开
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:openUrl]];
                return YES;
            }
        }
    }
    return NO;
}

五、附

一些常见的调用系统应用url

About — prefs:root=General&path=About
Accessibility — prefs:root=General&path=ACCESSIBILITY
Airplane Mode On — prefs:root=AIRPLANE_MODE
Auto-Lock — prefs:root=General&path=AUTOLOCK
Brightness — prefs:root=Brightness
Bluetooth — prefs:root=General&path=Bluetooth
Date & Time — prefs:root=General&path=DATE_AND_TIME
FaceTime — prefs:root=FACETIME
General — prefs:root=General
Keyboard — prefs:root=General&path=Keyboard
iCloud — prefs:root=CASTLE
iCloud Storage & Backup — prefs:root=CASTLE&path=STORAGE_AND_BACKUP
International — prefs:root=General&path=INTERNATIONAL
Location Services — prefs:root=LOCATION_SERVICES
Music — prefs:root=MUSIC
Music Equalizer — prefs:root=MUSIC&path=EQ
Music Volume Limit — prefs:root=MUSIC&path=VolumeLimit
Network — prefs:root=General&path=Network
Nike + iPod — prefs:root=NIKE_PLUS_IPOD
Notes — prefs:root=NOTES
Notification — prefs:root=NOTIFICATIONS_ID
Phone — prefs:root=Phone
Photos — prefs:root=Photos
Profile — prefs:root=General&path=ManagedConfigurationList
Reset — prefs:root=General&path=Reset
Safari — prefs:root=Safari
Siri — prefs:root=General&path=Assistant
Sounds — prefs:root=Sounds
Software Update — prefs:root=General&path=SOFTWARE_UPDATE_LINK
Store — prefs:root=STORE
Twitter — prefs:root=TWITTER
Usage — prefs:root=General&path=USAGE
VPN — prefs:root=General&path=Network/VPN
Wallpaper — prefs:root=Wallpaper
Wi-Fi — prefs:root=WIFI

苹果官方链接:https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html

一篇很专业的分析文章
JailbreakHumhttp://sspai.com/31500

相关文章

网友评论

  • 33a231292dbe:还没解决的请加我QQ:691647860,秒解决
  • PaulPaulBoBo:大神,请问有没有方法打开Safari而不刷新Safari当前网址?也不新建标签展示。比如当前Safari当前网页是百度新闻,打开Safari后,Safari仍然停留在百度新闻页面。找了很多博客都没有实现这个需求。我也尝试了通过包名打开Safari,发现Safari的包名查不到。请大神赐教!
    phzean:@PaulPaulBoBo 看下这个 https://github.com/lanvsblue/AppBrowser 用模拟器运行,真机拿不到应用列表 ~
    PaulPaulBoBo:@phzean 查了很多资料发现openURL()方法不太能实现这个需求。我测试过已经实现这一功能的APP,他们的逻辑是通过推送进入APP时,会直接打开Safari,而不管Safari当前是什么页面,不刷新,不新建标签。其他的打开方式是会新建标签的。猜想他们的思路是通过包名打开APP,但是,现在找不到Safari的包名,大神,你知道Safari的包名是什么吗?
    phzean:链接通过openURL()方法在safari打开的行为找不到什么规律。一个url丢给safari,其实就已经脱离了app的控制了,safari怎么去处理这个url,就不得而知了。可以去深入了解下safari的逻辑。
  • 庞大不小:若有一个demo就更好了。
    colbert02:@庞大不小 求demo 392866541@qq.com
    庞大不小:@phzean 好的.fublog@qq.com 麻烦了。其实有Demo更容易学习。
    phzean:@庞大不小 代码其实全部贴出来了,需要的话可以发邮件给你

本文标题:iOS URL Schemes实现APP之间的跳转

本文链接:https://www.haomeiwen.com/subject/jtimlttx.html