OpenURL

目标

平常我们做iOS开发,会经常遇到打开其他的APP的功能。本篇文章讲的就是打开别人的APP的一些知识。我们的目标是:

打开别人的APP

让别人打开我们的APP

iOS9的适配问题

使用URL Schemes传递数据

准备工作

建立一个名为OpenApp的工作空间,用来存放我们的两个工程

建立这个工作空间主要是为了让我们后面建立的两个工程能在一个Xcode页面上管理,方便讲解和管理。挺简单的,不清楚的可以看我之前的文章【iOS开发】在一个Xcode页面建立多个工程

建立一个workspace来存放我们的工程

建立一个名为MyApp的iOS工程。这个MyApp是“我的app”,用来打开另一个APP的。

添加工程到我们刚才创建的OpenApp.xcworkspace。并且在工程的Main.storyboard添加一个button,待会儿我们会用来写方法。

MyApp工程

建立一个名为WXApp的iOS工程。这个工程是我们模拟的“微信APP”,是被人打开的那个APP。

为了区分两个应用,我们在Main.storyboard上加一个label,“我是微信App”。

在workspace建立WXApp工程

WXApp

好了,准备工作就这么简单。

打开别人的APP与让别人打开我们的APP

想要打开别人的APP或者让别人打开我们的APP,那就需要通过URL Schemes了。

什么是URL Schemes?

URL Schemes是苹果给出的用来跳转到系统应用或者跳转到别人的应用的一种机制。同时还可以在应用之间传数据。

通过对比网页链接来理解 iOS 上的 URL Schemes,应该就容易多了。

URL Schemes 有两个单词:

URL,我们都很清楚,http://www.apple.com

就是个 URL,我们也叫它链接或网址;

Schemes,表示的是一个 URL 中的一个位置——最初始的位置,即 ://

之前的那段字符。比如http://www.apple.com

这个网址的 Schemes是http

根据我们上面对 URL Schemes 的使用,我们可以很轻易地理解,在以本地应用为主的 iOS 上,我们可以像定位一个网页一样,用一种特殊的 URL 来定位一个应用甚至应用里某个具体的功能。而定位这个应用的,就应该是这个应用的 URL 的 Schemes 部分,也就是开头儿那部分。

在WXApp上设置一个URL Schemes

为了能让别的App(包括我们刚才创建的MyApp)能够打开WXApp,我们需要为WXApp添加一个URL Schemes。

步骤:选中WXApp工程->Info->URL Types->点击“+”->在URL Schemes栏填上weixin

添加一个URL Schemes

备注:一个应用是可以有多个URL Schemes的。你可以再次点击“+”来添加一个URL Schemes

我们看看info.plist文件里面是怎样的。

info.plist文件里面的URL Schemes

然后我们run一下WXApp。(注意一下你run的target是哪个)

在模拟器run一下WXApp

这样,WXApp就向系统“注册”了一个URL Schemes,其他的应用可以通过openurl:方法来打开WXApp了。

MyApp打开WXApp

现在我们在MyApp里面打开WXApp。方法非常简单。

在ViewController里面添加一个方法

- (IBAction)openWXApp:(UIButton*)sender {    [selfdemo1];}- (void)demo1 {//创建一个url,这个url就是WXApp的url,记得加上://NSURL*url = [NSURLURLWithString:@"weixin://"];//打开url[[UIApplicationsharedApplication] openURL:url];}

然后run一下MyApp

run MyApp

运行了之后点击“打开微信”button,会弹出“MyApp”想要打开“WXApp”提示框,点确认之后就可以跳转到WXApp了。

点击“打开微信”button

打开了WXApp

iOS9之后,在一个应用跳转到了另一个应用之后,左上角会有个返回到上一个应用的按钮。这样,我们在MyApp里面点击“打开微信”按钮,跳转到WXApp之后,再点击“Back to MyApp”,又回到MyApp了。闲着无聊就可以反复点击这两个按钮来两个应用间跳转了,哈哈。

值得一说的是,这个URL Schemes并不是唯一的。也就是说,多个应用之间设置的URL Schemes是可以相同的。

那么问题来了,假如两个应用的URL Schemes相同的话,使用openURL:方法会打开哪个应用呢?

楼主亲自用手机试了一下。

步骤是:

将MyApp安装到手机上,点击“打开微信”button,微信打开了。

然后将WXApp也安装到手机上。再次点击MyApp的“打开微信”button,结果打开的是WXApp。

结论:如果两个应用有URL Schemes是相同的,后安装的应用的URL Schemes会把早安装的应用的URL Schems覆盖掉。

在safari打开WXApp

没错,注册了URL Schemes的应用,用safari浏览器也是可以打开的。我就经常用这个来验证应用是否设置了我想要的URL Schemes

在safari打开WXApp,直接在safari的地址栏输入weixin://,enter就可以打开了

用safari打开WXApp

用safari打开WXApp

iOS9中的适配

配置URL Schemes白名单

其实在打开WXApp的时候,正常情况下,我们应该是先用canOpenURL:方法先判断能否打开这个url,然后再用openURL方法打开该URL的。这样可以带来更好的用户体验。因为用户不一定安装了WXApp。假如用户没有安装的话点击“打开微信”button是没有任何反应的。这时候我们应该先判断是否能够打开这个url(也就是判断用户有没有安装WXApp),没有安装的话就给个温馨提示,比如:“U四不四洒,没安装WXApp,怎么打开啊!”。

更重要的是,假如点击之后没效果,很有可能被苹果拒绝哦。

- (IBAction)openWXApp:(UIButton*)sender {//    [self demo1];[selfdemo2];}//先判断再打开WXApp- (void)demo2 {//创建一个url,这个url就是WXApp的url,记得加上://NSURL*url = [NSURLURLWithString:@"weixin://"];//先判断是否能打开该urlif([[UIApplicationsharedApplication] canOpenURL:url]) {//打开url[[UIApplicationsharedApplication] openURL:url];    }else{//给个提示或者做点别的事情NSLog(@"U四不四洒,没安装WXApp,怎么打开啊!");}

但是我们发现用了canOpenURL:方法之后,并没有如我们想像中打开了WXApp。一看,Xcode控制台提示:

Xcode控制台错误提示

为什么会这样呢?

因为iOS9的时候苹果加强了权限,只有在info.plist文件中加入了URL Schemes白名单才能使用canOpenURL:方法来判断是否能打开该url。该白名单的上限是50个。也就是说,你最多只能使用canOpenURL:方法判断50个URL Schemes。当然,平常我们都用不了那么多,就算是集成分享功能,50个肯定够了。

备注:只是对canOpenURL:方法有限制,openURL:方法是没有限制的。

言归正传,我们需要在MyApp的info.plist里面将weixin设置为白名单。

步骤:点击info.plist->右键->Open As->Source Code->添加下面的代码

LSApplicationQueriesSchemesweixin

这样就可以了。

使用URL Schems传递数据

URL Schemes除了可以用来打开APP之外,还可以用来在两个App之间传递少量的数据。

在百度上搜索“ios”,会生成一个url,下面来以这个url来大概介绍url的组成。

url为:https://www.baidu.com/s?ie=UTF-8&wd=ios

https就是协议,也就是scheme

www.baidu.com  是域名

/s是路径

?后面的是query,也就是查询参数。这个url有两个参数,分别是ie=UTF-8和wd=ios

我们iOS的URL Schemes中也是差不多的。

而且,在openURL的时候,如果url中带有参数,只要URL Schemes是正确的,那同样可以打开App,而且,后面的参数也会带到我们打开的App那里。

咱们做个Demo就一目了然了。

在MyApp中,写个demo3方法,url为weixin://www.shixueqian.com/abc?title=hello&content=helloworld

- (IBAction)openWXApp:(UIButton*)sender {//    [self demo1];//    [self demo2];[selfdemo3];}//使用URL Schemes传递数据- (void)demo3 {//创建一个url,这个url就是WXApp的url,记得加上://NSURL*url = [NSURLURLWithString:@"weixin://www.shixueqian.com/abc?title=hello&content=helloworld"];//打开url[[UIApplicationsharedApplication] openURL:url];  }

在WXApp的AppDelegate.m中,实现application: openURL:(NSURL *)url sourceApplication: annotation:回调

- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation {NSLog(@"url=====%@ \n  sourceApplication=======%@ \n  annotation======%@", url, sourceApplication, annotation);returnYES;}

run了之后,我们发现,我们依旧可以通过点击openURL:方法打开WXApp。而且在WXApp被打开的时候,会执行application: openURL:(NSURL *)url sourceApplication: annotation:回调方法。在这个回调方法中,我们可以得到MyApp传过来的url等信息。

控制台打印如下:

log结果

完整的url信息都传过来了,我们就可以利用这个url里面的路径和参数等信息了,想干嘛就干嘛。这就实现了从MyApp向WXApp传递数据了。

备注:

苹果一共给了3个openURL的回调。

分别是:

- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)urlNS_DEPRECATED_IOS(2_0,9_0,"Please use application:openURL:options:") __TVOS_PROHIBITED;- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(nullableNSString*)sourceApplication annotation:(id)annotationNS_DEPRECATED_IOS(4_2,9_0,"Please use application:openURL:options:") __TVOS_PROHIBITED;- (BOOL)application:(UIApplication*)app openURL:(NSURL*)url options:(NSDictionary *)optionsNS_AVAILABLE_IOS(9_0);// no equiv. notification. return NO if the application can't open for some reason

为什么会有3个呢?这3个回调又有什么区别?(为方面讲解,分别设置ABC3个回调)

3个回调的功能基本一样,都是在别人通过URL Schemes打开应用的时候会执行的。

不同之处:

A回调是在iOS2.0的时候推出的,参数只有url。

B回到是在iOS4.2的时候推出的,参数有urlsourceApplicationannotation.

C回调是iOS9.0的时候推出的,参数有urloptions。options有下面几个key

// Keys for application:openURL:options:UIKIT_EXTERNNSString*constUIApplicationOpenURLOptionsSourceApplicationKeyNS_AVAILABLE_IOS(9_0);// value is an NSString containing the bundle ID of the originating applicationUIKIT_EXTERNNSString*constUIApplicationOpenURLOptionsAnnotationKeyNS_AVAILABLE_IOS(9_0);// value is a property-list typed object corresponding to what the originating application passed in UIDocumentInteractionController's annotation propertyUIKIT_EXTERNNSString*constUIApplicationOpenURLOptionsOpenInPlaceKeyNS_AVAILABLE_IOS(9_0);// value is a bool NSNumber, set to YES if the file needs to be copied before use

这几个回调是有优先级的。C>B>A。也就是说,如果你3个回调都实现了,那么程序只会执行C回调。其他回调是不会执行的。(当然,iOS9以下只会执行B回调)。

参考

本篇文章的Demo已经上传到GitHub上了https://github.com/shixueqian/OpenApp

文/谦言忘语(简书作者)

原文链接://www.greatytc.com/p/0811ccd6a65d

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容