本节书摘来自异步社区《iOS 6高级开发手册(第4版)》一书中的第2章,第2.9节秘诀:创建基于URL的服务,作者 【美】Erica Sadun,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.9 秘诀:创建基于URL的服务
iOS 6高级开发手册(第4版)
Apple的内置应用程序提供了多种可以通过URL调用访问的服务。可以要求Safari打开Web页面,让Maps显示一幅地图,或者使用mailto:风格的URL开始在Mail中撰写一封信件。URL模式指出现在冒号之前的URL的第一部分,比如http或ftp。
这些服务可以工作,因为iOS知道如何将URL模式匹配到应用程序。以http:开头的URL将在Mobile Safari中打开。mailto:URL总会链接到Mail。你可能不知道的是:你可以定义自己的URL模式,并在应用程序中实现它们。并非所有标准的模式都在iOS上受支持,FTP模式就不能使用。
无论何时Mobile Safari或另一个应用程序打开那种类型的URL,自定义的模式都将允许应用程序启动。例如,如果应用程序注册xyz,那么任何xyz:链接都会直接到达应用程序以进行处理,其中将把它们传递给应用程序委托的URL打开方法。你不必在那里添加任何特殊的编码。如果你只想运行应用程序,添加模式和打开URL就支持跨应用程序的启动。
处理程序扩展了启动,以允许应用程序利用传递给它的URL做某件事情。它们可能打开特定的数据文件,获取特定的名称,显示某一幅图像,或者处理调用中包括的信息。
2.9.1 声明模式
要声明URL模式,可以编辑Target > Info编辑器的URL Types区域(参见图2-10),并列出你将使用的URL模式。由该声明创建的Info.plist区域看起来将如下所示:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.sadun.urlSchemeDemonstration</string>
<key>CFBundleURLSchemes</key>
<array>
<string>xyz</string>
</array>
</dict>
</array>
CFBundleURLTypes条目包括一个字典数组,描述了应用程序可以打开和处理的URL类型。每个字典都相当简单,它们包含两个键:CFBundleURLName(定义任意的标识符)和CFBundleURLSchemes的数组。
模式数组提供了一个前缀列表,它们属于抽象的名称。可以添加一种或多种模式,下面的示例只描述了其中一种。你可能想利用“x”给名称加前缀(例如,x-sadun-services)。尽管iOS家族不是任何标准化组织的一部分,“x”前缀还是指示这是一个未注册的名称。x-callback-url的草案规范正在开发过程中,参见http://x-callback-url.com。
以前的iOS开发人员(以及当前的Apple雇员)Emanuele Vulcano在CocoaDev Web站点(http://cocoadev.com/index.pl?ChooseYourOwniPhoneURLScheme)上开启了正式的注册。iOS开发人员可以在核心名单中共享他们的模式,以便你可以发现想要使用的服务,并且宣传你自己提供的服务。注册表将列出服务和它们的URL模式,并将描述这些服务可以怎样被其他开发人员使用。其他的注册表包括http://handleopenurl.com、http://wiki.akosma.com/IPhone_URL_Schemes 和http://applookup.com/Home 。
2.9.2 测试URL
可以测试一种URL服务是否可用。如果UIApplication的canOpenURL:方法返回YES,就保证openURL:可以启动另一个应用程序打开那个URL。但是不保证该URL是有效的,而只能保证它的模式被正确地注册到现有的应用程序:
if ([[UIApplication sharedApplication] canOpenURL:aURL])
[[UIApplication sharedApplication] openURL:aURL];
2.9.3 添加处理程序方法
要处理URL请求,可以实现特定于URL的应用程序委托方法,如秘诀2-9所示。不幸的是,仅当应用程序已经在运行时,才可以保证将会触发该方法。如果它没有触发,并且URL请求启动了应用程序,控制首先会转到启动方法(将要完成和确实完成)。
你想确保正常的application:didFinishLaunchingWithOptions:返回YES。这允许控制传递给application:openURL:sourceApplication:annotation:,以便可以处理传入的URL。
秘诀2-9 提供URL模式支持
// Called if the app is open or if the launch returns YES
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSString *logString = [NSString stringWithFormat:
@"DID OPEN: URL[%@] App[%@] Annotation[%@]\n",
url, sourceApplication, annotation];
tbvc.textView.text =
[logString stringByAppendingString:tbvc.textView.text];
return YES;
}
// Make sure to return YES
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
tbvc = [[TestBedViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc]
initWithRootViewController:tbvc];
window.rootViewController = nav;
[window makeKeyAndVisible];
return YES;
}