在 iOS 里,程序之间都是相互隔离,目前并没有一个有效的方式来做程序间通信,幸好 iOS 程序可以很方便的注册自己的 URL Scheme,这样就可以通过打开特定 URL 的方式来传递参数给另外一个程序。

例如在 iPad 上浏览网页,并且 iPad 已经安装了 淘宝 HD,那么就打开下面这个链接就会在淘宝 HD 中查看这个商品的详细信息,也可以方便的使用淘宝 HD 进行购买、收藏等操作。

在淘宝 HD 中查看商品“2012西藏卓明谷方舟登舰卡(船票)”

当然,如果你在 Mac OS X 中打开这个链接,或者在没有安装 淘宝 HD 的 iPad 中打开这个链接,会提示没有程序来打开这个链接。

配置

要为 iOS 程序添加自定义协议的支持是一件很方便的事,只需要在程序的 Info.plist 添加一个 URL types 节点就可以了。在这个节点里,可以设置这个程序所支持的自定义协议名称,像 http、ftp 这种,一般我们可以设置为程序英文名称,像淘宝客户端中就设置了 taobao,这样 taobao:// 这个形式的 URL 就会关联到淘宝客户端的 App。

实现

在 Info.plist 里面设置完 URL types 之后,就可以在程序中处理这类 URL 的打开请求了。

在外部程序中,如果打开了指定自定义协议的 URL,程序中 application delegate 的 application:handleOpenURL: 方法就会被调用,在这个方法里,可以获取到触发这个方法的 URL,可以通过对这个 URL 进行判断,例如根据不同的 Host,不同的 Query String 来执行不同的动作。

  • (void)application:(UIApplication *)application handleOpenURL:(NSURL *)url {

    NSLog(@"%@", [url absoluteString]);

    // 在 host 等于 item.taobao.com 时,说明一个宝贝详情的 url,

    // 那么就使用本地的 TBItemDetailViewController 来显示

    if ([[url host] isEqualToString:@"item.taobao.com"]) {

      // 这里只是简单地假设 url 形式为 taobao://item.taobao.com/item.htm?id=12345678
    
      // 先获取要查看的宝贝详情的 itemId
    
      NSString *itemId = [[url query] substringFromIndex:[[url query] rangeOfString:@"id="].location+3];
    
      // 使用本地 ViewController 来显示淘宝商品详情
    
      TBItemDetailViewController *controller = [[TBItemDetailViewController alloc] initWithItemId:itemId];
    
      [self.navigationController pushViewController:controller animated:YES];
    
      [controller release];

    }

}

淘宝 for iOS

现在,淘宝 和 淘宝 HD 两个客户端都支持 taobao:// 协议,来打开特定的链接。目前已经支持的有:

宝贝详情 taobao://item.taobao.com/item.htm?id=12688928896

宝贝搜索 taobao://s.taobao.com/?q=iphone

店铺搜索 taobao://shopsearch.taobao.com/browse/shop_search.htm?q=iphone

例如,想要在自己的程序中,使用淘宝客户端来显示一个淘宝商品的详情,以支持用户可以直接在 iPhone 上购买,收藏等,就可以使用下面的代码:

  • (void)showItemInTaobao4iOS:(NSString *)itemId {

    // 构建淘宝客户端协议的 URL

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"taobao://item.taobao.com/item.htm?id=%@", itemId]];

    // 判断当前系统是否有安装淘宝客户端

    if ([[UIApplication sharedApplication] canOpenURL:url]) {

      // 如果已经安装淘宝客户端,就使用客户端打开链接
    
      [[UIApplication sharedApplication] openURL:url];

    } else {

      // 否则使用 Mobile Safari 或者内嵌 WebView 来显示
    
      url = [NSURL URLWithString:[NSString stringWithFormat:@"http://item.taobao.com/item.htm?id=%@", itemId]];
    
      [[UIApplication sharedApplication] openURL:url];

    }

}

使用淘宝客户端来打开淘宝链接的好处就是可以让用户更加方便的去购买商品,而不需要再重新登录,或者把用户名密码给了第三方的网站而导致安全隐患。

扩展性

在淘宝客户端中,支持的 URL 往往是淘宝网站已经有的链接,这些链接的 QueryString 中所带的参数往往已经满足了使用本地代码显示内容的需要,但是为了扩展性考虑,就需要添加一些额外的参数,并且与原有 QueryString 中不冲突的参数名称。通过这些额外的参数,再实现客户端打开链接时更多的自定义行为。

例如,如果在打开特定 URL,进行一些操作后需要再返回原来的程序,就会需要在 URL 中添加类似于 callback 这样的参数,这样在客户端处理完用户的操作后,可以将用户操作的结果返回给原来的程序,从而实现程序间的通信。

示例:

  • (void)buyItemInTaobao4iOS:(NSString *)itemId {

    // 构建淘宝客户端协议的 URL

    NSString *format = @"taobao://item.taobao.com/item.htm?id=%@&_action=buy&_callback=myapp://taobaobuysuccess";

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:format, itemId]];

    // 使用淘宝客户端打开链接

    [[UIApplication sharedApplication] openURL:url];

}

注意:当前淘宝客户端并不支持这样的调用方式,这里仅是一个示例。

当然,在使用这种方式实现程序间通信的时候,需要考虑检查一下来源 URL 的合法性,防止一些非法的调用造成用户的损失。

结语

通过自定义协议地支持,可以将 iOS 程序的一些功能和服务提供给外部程序,也可以实现 Web 和本地应用之间的互相调用。

如果你的 iOS 程序有这些需求的话,那么就可以考虑在 iOS 程序中添加自定义协议的支持了。

参考资料

iOS Application Programming Guide: Implementing Custom URL Schemes

iOS调用另一个程序的更多相关文章

  1. ABAP 通过sumbit调用另外一个程序使用job形式执行-简单例子

    涉及到两个程序: ZTEST_ZUMA02 (主程序) ZTEST_ZUMA(被调用的程序,需要以后台job执行) "ztest_zuma 的代码 DATA col TYPE i VALUE ...

  2. 如果你恨一个程序员 忽悠他去做iOS开发(戏谑篇)

    .state { text-align: right; height: 16px; line-height: 16px; color: #999; padding-top: 5px; overflow ...

  3. 如果你恨一个程序员,忽悠他去做iOS开发

    如果你恨一个程序员,忽悠他去做iOS开发.不管他背景是cobel还是 java,送他一本iOS开发的书.这种书最好是国人写的,容易以偏概全一点,相比洋鬼子的书,更容易学到皮毛.这叫舍不得孩子套不着狼, ...

  4. 在C#中调用另一个应用程序或命令行(.exe 带参数)<zz>

    在.net中使用system.diaglostics.Process可以用来调用另一个命令行或程序. using   System.Diagnostics;     如果是dos     Proces ...

  5. 如果恨一个程序员,忽悠他去做iOS开发

    如果你恨一个程序员,忽悠他去做iOS开发.不管他背景是cobel还是 java,送他一本iOS开发的书.这种书最好是国人写的,容易以偏概全一点,相比洋鬼子的书,更容易学到皮毛.这叫舍不得孩子套不着狼, ...

  6. 在小程序中修改上一个页面里data中的数据调用上一个页面的方法

    //获取已经打开的页面的数组 var pages = getCurrentPages(); //获取上一个页面的所有的方法和data中的数据  var lastpage = pages[pages.l ...

  7. iOS开发:保持程序在后台长时间运行

    iOS开发:保持程序在后台长时间运行 2014 年 5 月 26 日 / NIVALXER / 0 COMMENTS iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式 ...

  8. iOS后台挂起程序 当程序到后台后,继续完成Long-Running Task 任务

    我们知道,到我们程序从前台退到后台(安home)键后,将执行程序的委托方法. // 当应用程序掉到后台时,执行该方法 - (void)applicationDidEnterBackground:(UI ...

  9. iOS开发UI篇—程序启动原理和UIApplication

    iOS开发UI篇—程序启动原理和UIApplication   一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...

随机推荐

  1. UIWebView & javascript

    http://blog.163.com/m_note/blog/static/208197045201293015844274/ UIWebView是IOS SDK中渲染网面的控件,在显示网页的时候, ...

  2. 在Activity之间使用Intent传值和Bundle传值的区别和方式

    两者本质上没有任何区别.Bundle只是一个信息的载体 将内部的内容以键值对组织 Intent负责Activity之间的交互 自己是带有一个Bundle的Intent.putExtras(Bundle ...

  3. HDU1171--Big Event in HDU(多重背包)

    Big Event in HDU   Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...

  4. pat L2-006. 树的遍历

    L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历 ...

  5. MyEclipse使用总结——修改MyEclipse默认的Servlet和jsp代码模板

    http://www.cnblogs.com/xdp-gacl/p/3769058.html   孤傲苍狼 只为成功找方法,不为失败找借口! MyEclipse使用总结——修改MyEclipse默认的 ...

  6. webpy

    url处理 对于一个站点来说,URL 的组织是最重要的一个部分,因为这是用户看得到的部分,而且直接影响到站点是如何工作的,在著名的站点如:del.icio.us ,其URLs 甚至是网页界面的一部分. ...

  7. Windows修改hosts文件及位置

    文件位置 C:\Windows\System32\drivers\etc 中的hosts文件 修改方式 指定IP 域名 192.168.66.7 www.baidu.com

  8. 转 Android中通过广播方式调起第三方App

    今天紧急的跟进一个百度视频App无法调起百度贴吧App的问题,当然,这个是只发现是在4.x的android系统下发生,在2.x版本下,一切正常,(其实是3.1及以上的版本都有问题)具体场景为: 1.贴 ...

  9. cakephp , the subquery

    Cakephp 框架帮我们做了很多的工作,的确省了我们很多工作,提高了效率. 但是,碰到一些比较复杂的查询时,还是有些问题,官方的cookbook api 有说明一些详细的用法,但感觉还是不太够,有些 ...

  10. 获取map中的一个value值以及遍历map获得map里所有key、value的值

    前言: 1.声明一个map: Map map = new HashMap();2.向map中放值,注意:map是key-value的形式存放的.如: map.put(”sa”,”dd”); 3.从ma ...