iOS 的设计思路是原则上禁止不同的应用程序之间相互访问彼此的数据。虽然对于像我这样的桌面应用开发人员而言,不能访问程序以外的数据是不能想象的。但是从安全角度来说不失为一个有效的策略。不过凡事总有例外,所以乔布斯还是为程序间通讯开放了几个接口。
URL Scheme
iOS 上的应用程序可以通过向其它应用程序发送一个URL 格式的字符串来向其发送数据。这个特性通常用于在应用程序中启动另外一个应用程序来打开一种特定格式的数据。例如:你的程序可以向Map 发送一个URL ,要求其打开指定的地图;或者在邮件程序里向Adobe Reader 发送一个URL ,要求其打开指定的PDF 文件。
iOS 预定义了如下几种URL Scheme 。
Mail: mailto:frank@wwdcdemo.example.com
Tel: tel:1-408-555-5555
SMS: 1-408-555-1212
Map: http://maps.google.com/maps?q=cupertino
YouTube: http://www.youtube.com/watch?v=VIDEO_IDENTIFIER
iTunes:
http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=156093464&id=156093462&s=143441
你也可以自定义URL Scheme 。需要注意的是:在多个应用程序注册了同一种URL Scheme 的时候,iOS 系统程序的优先级高于第三方开发程序。但是如果一种URL Scheme 的注册应用程序都是第三方开发的,那么这些程序的优先级关系是不确定的。
(1) 注册URL Scheme
在应用程序的Info.plist 中添加CFBundleURLTypes 项。
<key>CFBundleURLTypes </key>
<array>
<dict>
<key>CFBundleURLName </key>
<string>com.acme.todolist</string>
<key>CFBundleURLScheme </key>
<array>
<string>todolist</string>
</array>
</dict>
</array>
(2) 发送 URL Scheme
NSURL *myURL = [NSURL URLWithString:@"URL Scheme"];//注意这里的URL包含了不同程序间通信传入的参数
[[UIApplication sharedApplication ] openURL:myURL];
(3) 接收 URL Scheme
URL Schemes 由系统发送给 application delegate ,而 delegate 通常应该实现如下几个代理函数:
l application:didFinishLaunchingWithOptions:
判断是否应该启动程序来处理传入的 URL Scheme 。这个函数只在程序从 not running 到running 时被调用。如果程序在 URL Scheme 传入时处于 Background 或者 Suspending 状态,那么校验工作应该在下面两个代理函数中实现。
l application:openURL:sourceApplication:annotation
在 4.2 及之后版本的 iOS 中实现。
l application:handleOpenURL:
在 4.1 及之前版本的 iOS 中实现。
(4) 安全性
参考 Secure Coding Guide 中 Validating Input 部分。