URL Scheme 是什么?

iOS有个特性就是应用将其自身”绑定”到一个自定义 URL scheme 上,该 scheme用于从浏览器或其他应用中启动本应用。常见的分享到第三方之间的跳转都是基于Scheme的。

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

  • URL,我们都很清楚,http://www.apple.com就是个URL,我们也叫它链接或网址;
  • Schemes,表示的是一个 URL 中的一个位置——最初始的位置,即 ://之前的那段字符。比如 http://www.apple.com这个网址的Schemes是
    http

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

你可以完全按照理解一个网页的 URL ——也就是它的网址——的方式来理解一个 iOS 应用的 URL,拿苹果的网站和 iOS 上的微信来做个简单对比:

  网页(苹果) iOS 应用(微信)
网站首页/打开应用 http://www.apple.com weixin://
子页面/具体功能 http://www.apple.com/mac/(Mac页面) weixin://dl/moments(朋友圈)

关于基础概念性的就讲这么多

项目中关键的配置

在项目Info的Url Type中配置(被唤起端

  • 说明

    • URL identifier只是一个标示符,随意填写,建议写成:com.*.*反转域名的方法保证该名字的唯一性。
    • URL Scheme就是你用来通信的命令前缀,用来定位一个应用。

在Plist文件中配置

  • 注意:URL Schemes 是一个数组,允许应用定义多个 URL schemes。

接收到唤起如何处理

在代理方法- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication annotation:(id)annotation中判断唤起的来源source app,根据Url所携带的参数进行不同的操作。比如跳转到制定的页面,相关的逻辑处理等等.

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
        sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
  NSLog(@"URL scheme:%@", [url scheme]);
  NSLog(@"URL query: %@", [url query]); 

// Customer Code
  return YES;
}

以上配置是在被唤起应用中配置的。

唤起端

一般情况下,唤起端可以直接调用appDelegate的代理方法去唤醒其他应用。

- (void)awakeOtherApp
{
  NSString *customURL = @"otherApp://"; 

  if ([[UIApplication sharedApplication]
    canOpenURL:[NSURL URLWithString:customURL]])
  {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
  }
  else
  {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL error"
                          message:[NSString stringWithFormat:
                            @"No custom URL defined for %@", customURL]
                          delegate:self cancelButtonTitle:@"Ok"
                          otherButtonTitles:nil];
    [alert show];
  }
}
  • 这里需要注意一下在iOS9以后,唤起端需要配置一下

LSApplicationQueriesSchemes.iOS9之后需要,iOS9之后提高了app的安全性,需要给出一个类似白名单的东西,在白名单里面的才能打开app。不然报错:
-canOpenURL: failed for URL: “OpenAppTest://mark?id=007” – error: “This app is not allowed to query for scheme OpenAppTest”

1.新建一个app1,在Info.plist文件的信息属性列表里新建一组,类型是URL types    设置如下

这里最关键的部分在于URL Schemes数组里的Item 0,后面的填写的字符串就是你用来通信的命令前缀“achao”,URL identifier只是一个标示符,随意填写
然后再AppDelegate里处理重载下面的回调方法

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

{

if ([[url scheme] isEqualToString:@"achao"])

{

NSLog(@"%@",url);

}

return YES;

}

可以看见[url scheme]这个命令是为了拿到url的scheme,就是命令前缀“achao”
2.新建app2,这个app什么都不用操作,只需要去唤醒app1即可,于是我们在viewDidLoad里写上这一句

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"achao://hello"]];

"achao"就是app1里的url scheme,我叫它命令前缀(我怀疑apple的应用程序装上过后有个像通知中心一样的应用程序来统一管理,而每个应用程序的url
scheme都会在那里被记录,以供其他app来调用该app,至于url scheme属于哪个应用程序,当然是和app的Bundle identifier相关的),格式采用“前缀://..."
3.我们关闭app1,app2,然后再启动app2,发现app2启动过后唤醒了app1,并且成功跳转;我们再关闭app1,app2,然后我们打开app1进行监测,发现app1被启动后,进入了,这就实现了两个app之间的唤醒和通信
4.当然这时候你可能才想到,那不是很多应用程序都会被其他垃圾程序调用了,查找资料过后,原来还有后续
我们重载这个方法

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

if ([sourceApplication isEqualToString:@"AC.achao.com"])

{

NSLog(@"%@", sourceApplication);    //来源于哪个app(Bundle
identifier)

NSLog(@"scheme:%@", [url scheme]);  //url
scheme

NSLog(@"query: %@", [url query]);
  //查询串  用“?...”格式访问

return YES;

}

else

return NO;

}

这就满足我们的需求了,我们可以通过sourceApplication来判断来自哪个app以决定要不要唤醒自己的app,也可以通过[url query]来获得查询串,这个时候我们需要更改app2的访问方式才能获得这个参数

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"achao://hello?name=achao-AC"]];

我们也可以直接在safari离输入"achao://hello?name=achao-AC"来访问我们的app1,这个时候sourceApplication就是@"com.apple.mobilesafari"

总结:类似下面的方法

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://158********"]];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://158********"]];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://362****@qq.com"]];

我们用过很多,估计也是程序内部设置了类似的url scheme来供其他应用程序操作的

注意事项

通过上面的方法可以唤醒其他的应用,简单总结下一些注意事项。

  1. URL Scheme 其实就是一个app应用的唯一标志。通过它来确定打开那个应用。
  2. 一定要分清哪些配置在哪方配置,被唤醒与唤醒。
  3. iOS9之后需要在唤起端加入LSApplicationQueriesSchemes千万不能忘。
  4. 还有一个问题还没解决,如何再次回到唤醒应用的界面。这个需要参考下官方的XCallbackURL。听说有些复杂,有空再看看。

一个App与另一个App之间的交互,添加了自己的一些理解的更多相关文章

  1. 混合app开发--js和webview之间的交互总结

    使用场景:原生APP内嵌套H5页面,app使用的是webview框架进行嵌套 这样就存在两种情况 1.原生app调用H5的方法 2.H5调用app的方法 分别讲解下,其实app与H5之间的交互式非常简 ...

  2. 【如何快速的开发一个完整的iOS直播app】(采集篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,首先需要采集主 ...

  3. 【如何快速的开发一个完整的iOS直播app】(播放篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看上篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,集成ijkpl ...

  4. 【如何快速的开发一个完整的iOS直播app】(原理篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...

  5. 30 分钟开发一个简单的 watchOS 2 app <oneVcat>

    Apple Watch 和 watchOS 第一代产品只允许用户在 iPhone 设备上进行计算,然后将结果传输到手表上进行显示.在这个框架下,手表充当的功能在很大程度上只是手机的另一块小一些的显示器 ...

  6. 如何快速的开发一个完整的iOS直播app(原理篇)

    目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的iOS直播app](采集篇) 前言 大半年没写博客了,但 ...

  7. 【如何快速的开发一个完整的iOS直播app】(美颜篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重 ...

  8. Android项目实战(二十二):启动另一个APP or 重启本APP

    一.启动另一个APP 目前公司项目需求,一个主APP,需要打开某些小APP,这些小APP是整合了Unity的,但是还是android程序(所有小APP的包名是已知的). 以前没做过,查询了一下实现方法 ...

  9. Android 一个app启动另一个app

    最近,一个app启动另一个app,这个玩法挺火的嘛,有没有试过更新QQ到5.1版本,QQ的健康里面就可以添加其他app,实现从QQ跳转到其他app应用.这个挺好玩的,一下子带来了多少流量啊. 一.先来 ...

随机推荐

  1. ThreadLocal(线程绑定)

    为保证在DAO层里的操作都在同一事务里,我们曾使用以参数的形式将Connection向下传递的方式,而ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection ...

  2. Linux块设备加密之dm-crypt分析

    相关的分析工作一年前就做完了,一直懒得写下来.现在觉得还是写下来,以来怕自己忘记了,二来可以给大家分享一下自己的研究经验. 这篇文章算是<Device Mapper代码分析>的后续篇,因为 ...

  3. Windows Python requests 详细模块安装方法

    据说requests是一个很吊的处理网络问题的第三方库.我折腾了半天.终于在Win上安装好了. 网上找到的都不详细,我是反复尝试才成功的. 还是自己写一个傻瓜式的指南吧: 1.安装 Setuptool ...

  4. MySQL执行插入操作时报错1366 - Incorrect string value

    今天在测试mysql时,发现插入数据的问题,下面和大家分享下解决方法: 首先看问题原因: [Err] 1366 - Incorrect string value: '\xCF\xD6' for col ...

  5. sizeof(结构体)和内存对齐以及位域

    Win32平台下的微软C编译器的对齐策略: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该 ...

  6. github pages + Hexo + 域名绑定搭建个人博客

    环境 Windows 10(64 位) Git-2.7.4-64-bit node-v4.4.7-x64 如果上述软件已经安装的,跳过,没有安装的下载安装. 1,git下载安装(https://git ...

  7. Struts 2 标签库

    <s:if>标签 拥有一个test属性,其表达式的值用来决定标签里内容是否显示 <s:if test="#request.username=='clf'"> ...

  8. 利用ScrollView滑动属性实现点击查看更多

    利用ScrollView的滚动实现点击查看更多 效果图 更新内容布局 <ScrollView android:id="@+id/sv_des" android:layout_ ...

  9. 为何不能在viewDidLoad方法中显示其他视图

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 你可以使得当视图控制器(view controller)显示自 ...

  10. Spark技术内幕:究竟什么是RDD

    RDD是Spark最基本,也是最根本的数据抽象.http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf 是关于RDD的论文.如果觉得英 ...