iPhone / iOS SDK 最酷的特性之一就是应用将其自身”绑定”到一个自定义 URL scheme 上,该 scheme 用于从浏览器或其他应用中启动本应用。

注册自定义 URL Scheme

注册自定义 URL Scheme 的第一步是创建 URL Scheme — 在 Xcode Project Navigator 中找到并点击工程 info.plist 文件。当该文件显示在右边窗口,在列表上点击鼠标右键,选择 Add Row:

向下滚动弹出的列表并选择 URL types。

点击左边剪头打开列表,可以看到 Item 0,一个字典实体。展开 Item 0,可以看到 URL Identifier,一个字符串对象。该字符串是你自定义的 URL scheme 的名字。建议采用反转域名的方法保证该名字的唯一性,比如com.yourCompany.yourApp。

点击 Item 0 新增一行,从下拉列表中选择 URL Schemes,敲击键盘回车键完成插入。

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

展开该数据并点击 Item 0。你将在这里定义自定义 URL scheme 的名字。只需要名字,不要在后面追加 :// — 比如,如果你输入 iOSDevApp,你的自定义 url 就是 iOSDevApp://

此时,整个定义如下图:

虽然我赞同 Xcode 使用描述性的名字的目的,不过看到创建的实际的 key 也是非常有用的。这里有一个方便的技巧,右键点击 plist 并选择 Show Raw Keys/Values,就能看到以下效果:

还有另一种有用的输出格式,XML,因为可以非常容易的看到字典和原始数组及其包括的实体的结构。点击 plist 并选择 Open As – Source Code:

从 Safari 中调用自定义 URL Scheme

定义了 URL scheme,我们可以运行一个快速测试来验证应用是否如我们所期望的被调用。在这之前,我创建了一个准 UI 以辨别带有自定义 URL 的应用。该应用只有一个 UILabel,带有文本 “App With Custom URL”。下载源代码(http://iosdevelopertips.com/downloads/#customURLScheme)

使用模拟器调用应用的步骤:

  • 在 Xcode 中运行应用

  • 一旦应用被安装,自定义 URL scheme 就会被注册

  • 通过模拟器的硬件菜单中选择 Home 来关闭应用

  • 启动 Safari

  • 在浏览器地址栏输入之前定义的 URL scheme(如下)

此时 Safari 将会关闭,应用会被带回到前台。祝贺你刚刚使用自定义 URL scheme 调用了一个 iPhone 应用。

从另一个 iPhone 应用中调用自定义 URL Scheme

让我们看看如何从另一个应用中调用自定义 URL scheme。我又创建了一个非常简单的 iPhone 应用,它只有一个 UILabel 和一个 UIButton — 前者显示了一段信息,告诉你这个应用将要通过自定义 URL scheme 来调用另一个应用,按钮则开始这个行为。下载源代码(http://iosdevelopertips.com/downloads/#customURLScheme)

buttonPressed 方法中的代码处理 URL 调用:

- (void)buttonPressed:(UIButton *)button

{

NSString *customURL = @"iOSDevTips://";

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];

}

}

第5行代码检查自定义 URL 是否被定义,如果定义了,则使用 shared application 实例来打开 URL (第 8 行)。openURL:方法启动应用并将 URL 传入应用。在此过程中,当前的应用被退出。

通过自定义 URL Scheme 向应用传递参数

有时你需要通过自定义 URL 向应用中传递参数。让我们看看该如何完成这个工作。

NSURL 作为从一个应用调用另一个的基础,遵循 RFC 1808(https://tools.ietf.org/html/rfc1808) (Relative Uniform Resource Locators) 标准。 因此你所熟悉的基于网页内容的 URL 格式在这里也适用。

在自定义了 URL scheme 的应用中,app delegate 必须实现以下方法:

- (BOOL)application:(UIApplication *)application

openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation

从一个应用传递参数到另一个的诀窍是通过 URL。例如,假设我们使用以下的 URL scheme,想传递一个名为 “token”的参数和一个标识注册状态的标志,我们可以像这样创建一个 URL:

NSString *customURL = @"iOSDevTips://?token=123abct&registered=1";

在 web 开发中,字符串 ?token=123abct&registered=1 被称作查询询串(query string)。

在被调用(设置了自定义 URL)的应用的 app delegate 中,获取参数的代码如下:

- (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]);

return YES;

}

以上代码在应用被调用时的输出为:

Calling Application Bundle ID: com.3Sixty.CallCustomURL

URL scheme:iOSDevTips

URL query: token=123abct&registered=1

注意 “Calling Application Bundle ID”,你可以用这个来确保只有你定义的应用可以与你的应用直接交互。

让我们改变一下代码,来验证发起调用的应用的 Bundle ID 是否合法:

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

sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

// Check the calling application Bundle ID

if ([sourceApplication isEqualToString:@"com.3Sixty.CallCustomURL"])

{

NSLog(@"Calling Application Bundle ID: %@", sourceApplication);

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

NSLog(@"URL query: %@", [url query]);

return YES;

}

else

return NO;

}

有一点要特别注意,你不能阻止其他应用通过自定义 URL scheme 调用你的应用,然而你可以跳过后续的操作并返回 NO,就像上面的代码那样。也就是说,如果你想阻止其它应用调用你的应用,创建一个与众不同的 URL scheme。尽管这不能保证你的应用不会被调用,但至少大大降低了这种可能性。

自定义 URL Scheme 示例工程

我意识到按照本文的每一步做下来还是有一点复杂的。我做好了两个非常基础的 iOS 应用,一个自定义了 URL scheme,另一个则去调用它,并传递了一个比较短的参数列表(query string)。这些是体验自定义 URL 的很好的入门点。

最新文章

  1. 使用ENode框架前您需要了解的东西(初稿)
  2. 微信小程序 不在以下合法域名列表中,请参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html
  3. visual studio快捷键
  4. LCD内核自带驱动分析
  5. Java基础之在窗口中绘图——填充星型(StarApplet 2 filled stars)
  6. Uva 10007 / HDU 1131 - Count the Trees (卡特兰数)
  7. 【Groovy】入门布道ppt
  8. jQuery iframe 自适应高宽度
  9. OC中的野指针(僵尸指针)
  10. UISearchDisplayController UISearchBar
  11. 黑马程序员:Java基础总结----GUI&网络&IO综合开发
  12. Windows使用Gitblit搭建Git服务器
  13. JS 多选文件或者选择文件夹
  14. 20175211 2017-2018-2 《Java程序设计》第六周学习记录(2)
  15. java设计模式之动态代理的概述和实现
  16. OpenVPN相同证书不同客户端设置不同静态IP的问题
  17. 36氪首发 | 「myShape」完成千万级人民币 Pre-A轮融资,推出 AI 智能健身私教
  18. ABBYY FineReader 14助力2017,正式进入新纪元
  19. jboos下载地址记录
  20. hdoj1043 Eight(逆向BFS+打表+康拓展开)

热门文章

  1. crtmpserver系列之一:流媒体概述
  2. 关于fastclick.js
  3. uva 11646 - Athletics Track
  4. logstash gsub替换
  5. (Deep) Neural Networks (Deep Learning) , NLP and Text Mining
  6. v2ex上100个话题
  7. BZOJ_1613_ [Usaco2007_Jan]_Running_贝茜的晨练计划_(动态规划)
  8. 六月计划#1A(6.1-6.8)
  9. D 系列性能预期
  10. 场解决方案添加webpart(Create Webpart to page using code)