(转)应用间通信——iOS 的孤岛困境

[核心提示] 和 Android 相比,iOS 的应用间通信机制显得十分薄弱。这一原始的应用间调用方式给开发者和用户都带来了种种负担和不便。打破这种孤岛状态,从系统层面使应用可以相互通信是 iOS 迟早需要迈出的一步。

拍一张照片上传到 Instagram 需要几步?

Android 用户:

  1. 打开相机
  2. 拍照
  3. 将照片分享给 Instagram
  4. 添加滤镜并发布


iOS 用户:

  1. 打开相机
  2. 拍照
  3. 按 Home 键退回主屏幕
  4. 启动 Instagram
  5. 从相册选择照片
  6. 添加滤镜并发布

在这个使用场景中,Android 的应用间通信机制直接把照片从相机传到了 Instagram,成功地提高了效率,用比 iOS 更优化的流程,更短的时间完成了拍照和上传的任务。

或许你会说,这样的比较不公平,iOS 用户其实有更快的方法:

  1. 打开 Instagram
  2. 进入 Instagram 内置相机
  3. 加滤镜并拍照
  4. 发布

在这种情况下,iOS 用户规避了退回主屏幕的累赘步骤,达到了与 Android 类似的效率,然而这样的做法导致了另一个问题:在这种情况下,不管你捕捉到的瞬间有多么精彩,它都只能在 Instagram 中使用一次。而通过成熟的应用间通信机制, Android 相机拍下的这个精彩瞬间日后还可以一键分享给微博、人人、Twitter、可以蓝牙传给室友,还可以彩信发给父母……

从这样一个简单的使用场景比较中我们可以看到,薄弱的应用间通信机制在很大程度上降低了 iOS 用户的操作效率,使 iOS 的各个应用之间如同一个个孤岛般缺乏联系,由此引发的不必要步骤和各种尴尬场景在很多使用场合损害了 iOS 的用户体验。

iOS 与 Android 的应用间通信方式

iOS:单任务时代的尴尬遗产

iOS 的应用间通信方式,主要表现为应用间的互相调用,苹果公司在官方文档 Apple URL Scheme Reference 中介绍了 iOS 支持的应用间调用方式,即通过一定格式的 URL 来在一个应用中调用另一个应用。你可以在 Mobile Safari 浏览器中输入"Instagram://“自动调用 Instagram 来直观地体验一下这个做法。

从这篇文档的修改记录来看,这种应用间调用方法从 2009 年 6 月到现在基本没有进行什么改动。而从 09 年 6 月到现在,不管是智能手机市场的大环境还是 iOS 本身的各种特性都发生了近乎翻天覆地的改变。这样的应用间调用方法本身是与 08、09 年 iOS 单任务的基本特征紧密结合的,在很多方面都已经不能适应今天的系统特性和用户需求。

例如,在绝大多数情况下,当用户在应用 A 中调用应用 B 时,他将完全离开应用 A,即如果在使用应用 B 完成步骤之后想要回到应用 A 中继续操作的话,只能按下 Home 键退出应用 B,再从主屏幕或多任务界面上找到应用 A 并重新进入。

在单任务时代,这样的操作流程是天经地义理所当然的,因为很显然应用 B 启动时应用 A 一定会被关掉。然而在 iOS 4 开始基本支持多任务之后,这样的操作流程便开始显得累赘和繁琐。在多任务系统中,如果一个用户操作应用 A 时调用了应用 B,那么最合理的做法应该是当操作完应用 B 之后直接回到应用 A 中继续进行离开前的操作,而不是回到主屏幕或者多任务界面,重新找到并启动应用 A,再重新进入离开前界面进行操作。

Android:完善的应用间通信

Android 的应用间通信机制与 Unix 的开放式工具链哲学一脉相承,是一个完整的体系。Google 官方提供详尽的 Intent 机制文档,以鼓励开发者理解和使用这样的机制,用更少的工作量达成更好的用户体验。

在 Android 中,所有的应用都向系统注册其所持有的组件和每个组件能够处理的任务。这样系统对于每个应用的每个组件能完成何种任务都了如指掌。当一个应用需要启动其它组件完成任务时,只需向系统发送一个消息,即可调用系统中可以完成该项任务的组件,而应用本身无需关心具体哪个应用的哪个组件最终处理了这个消息。

这样的做法给 Android 用户带来了良好的体验和巨大的便利。使用户可以根据自己的需求来自由选择各种服务的组合。此外,在这样的机制下,应用间的配合也显得相当无缝和平滑,用户在应用 A 中可以根据特定需求灵活选择 B、C、D、E 等各种相关应用来完成某个特定任务,而完成之后也可以很自然地退回应用 A 中继续进行操作。

iOS 应用间调用方式的弊端

从单任务时代遗留下来的 iOS 应用间互相调用的方式存在很多弊端,既给用户带来了很多不便,也加重了开发者的负担。

给用户带来不便

打断正常操作流程

对于用户来说,iOS 应用间调用方式最大的弊端在于,每次切换一个程序都要退回主界面或多任务界面手工开启。在需要多个应用相互配合完成工作的时候显得尤为不便。本文开头所举的用 Instagram 拍照上传的例子就是一个明显的体现,而类似这样的使用场景在生活中相当常见。

限制用户选择权

iOS 应用的调用和注册方式在很大程度上限制了用户的选择权。继续以 Instagram 为例:

点击一条 Instagram 链接,在 iOS 上只有一种打开方法:在 Mobile Safari 中打开。

同样点击一条 Instagram 链接,在 Android 上会出现下面这样的选择界面:

两种做法对比之下,iOS 处理方式的缺陷就变得非常明显了,如果我是一名 iPhone 用户——

  • 今天月末,手机流量不够了,但我真的很想立刻看到这张图,能不能用省流量的 Opera mini 浏览器打开?不能。
  • 我在地铁上信号不好,但我真的很想看到这张图,能不能用对网络要求更低的 UC 浏览器打开?不能。
  • 拍这照片的人是我哥们,看完照片直接给他 Like 一下再留个评论呗,能不能直接用 Instagram 打开?不能。

Android 的应用间通信方式很好地满足了用户在各种不同条件下对打开 Instagram 链接的不同需求,而 iOS 的做法,则在很多场合给用户带来了不便。

给开发者带来负担

无法完整满足用户需求

iOS 薄弱的的应用间调用机制导致开发者必须自行确定和实现调用对象。而不管开发者进行怎样的周全考虑,都无法完全覆盖用户对于调用对象的种种千差万别的需求。例如著名的稍后阅读应用 Pocket (原名 Read it later),勤奋的作者在应用中实现了二十多种分享服务,然而对于中国用户来说其中却缺少了最常用的分享到新浪微博和腾讯微博等服务。作为一个精力有限且并不十分了解中国的开发者,要让其在应用中追加对中国国内服务的支持显得勉为其难。

而在 Android 中,由于应用间通信体系的存在,系统会自动根据用户安装应用的实际情况接管并提供相关分享服务的选项,不管用户对应用的选择多么小众,只要安装了对应的应用,这样的需求就能得到满足。Pocket 的 Android 版本中,iOS 版分享菜单里由作者添加的各种国内用户并不需要的服务没有踪影,而中国用户需要的各种微博服务赫然在列。

重复实现多种已有功能

由于 iOS 的应用间调用机制给应用的调用行为带来了巨大的限制,开发者必须额外实现多种系统中已经存在的功能才能为用户理顺操作流程,基本满足用户的需求。在 iOS 上,我们可以看到 Twitter 和微博客户端自行实现浏览器,新闻阅读客户端自行实现分享选项,甚至文件阅读器自行实现 HTTP 服务器这样的怪异现象。这种额外的功能追加给开发者带来了很大的负担。而在 Android 系统中,由于系统间通信机制的存在,开发者并不需要进行这样的额外重复劳动。

以网易新闻客户端为例,如下图所示,网易新闻客户端的 iOS 版本自行实现了邮件发送界面,以便用户在邮件分享一则新闻后可以直接退回应用中继续阅读,而其 Android 版本则可以简单地直接调用 Gmail 客户端,用户在邮件分享完毕后 Gmail 客户端会自然退出,用户也可以自然回到应用中继续阅读。

额外实现系统中的已有功能只是 iOS 应用间调用机制给开发者带来的不便之一。为了实现类似于 Android 的自由调用和数据传递,Instapaper、Drafts 等部分著名 iOS 应用的开发者甚至开始联合开发一套新的应用间通信机制 X-callback-url,这样的做法固然可以实现比官方的应用间调用方式更多的功能,但是其对开发者带来的额外负担也更为巨大。

iOS 开发者的应用间通信尝试

强大的应用间分享机制是 Android 用户享受到的各种独特便利之一,在iOS 平台应用间通信机制并不完善的情况下,一些 iOS 开发者已经开始尝试在 iOS 平台上为用户带来应用间通信机制的便利。

Drafts

Drafts 是最近广受好评的一款新 iOS 应用,用户可以在 Drafts 中记录和保存文字,并在需要的时候将它们传递给 Tweetbot、Twitter for iPhone、Omnifocus、Things 和 Dropbox 等多个其它应用。

Drafts 的分享界面非常类似于 Android,其功能和思想也与 Android 的应用间通信方式非常接近,在文字内容的处理上,Drafts 实现了一部分 Android 应用间通信的行为,即将文字数据传递给系统中的其它应用来执行,而不是自行实现这些应用。

此外,Drafts 与同一开发商旗下的同义词典软件 Terminology 之间通过上文提到的 X-callback-url 这一第三方机制互相传递和使用数据,实现了类似于 Android 的较为方便的数据传递功能,当用户调用 Terminology 查词完毕后,Terminology 会自动退出,数据会直接回传到 Drafts 当中,而无需用户按 Home 键退回主屏幕或多任务界面重新启动 Drafts。

然而,由于 iOS 本身应用间调用机制的限制,Drafts 依然无法达到完全类似 Android 应用间通信机制的良好体验,例如虽然它可以将数据传递给外部应用执行,传递的对象依然是需要开发者手工添加的,无法满足用户较为小众的需求,将文字传递给微博客户端这样的需求在开发者决定加入之前依然是无法满足的。

Launch

Launch 在年初的 Macworld 展会上获得了科技媒体的关注和好评,它巧妙地实现了直接调用相关应用完成任务的功能。例如“调用 Tweetbot 查看苍井空的推文”、“调用 Instagram 查看陈冠希的照片”等等,并且可以通过苹果官方的应用调用机制自行添加需要调用的应用程序,例如通过设置运行“BussinessValue://”的启动器可以调用《商业价值》客户端。

Launch 在不违反苹果严格的应用间调用机制的前提下实现了 Android 应用间通讯机制中让用户自定义调用各种应用完成相关任务的功能。虽然与 Android 原生应用间通讯机制相比还存在很多缺陷,例如需要用户手动设置调用对象,可供调用的对象也并不十分全面,但是 Launch 在苹果官方的种种限制下最大限度地满足了用户选择自定义应用的需求。

应用间通信机制的未来

iOS:孤岛状态何时终结

从单任务时代遗留下来的应用间调用方式已经成为降低用户体验的重要因素,处于孤岛状态缺乏联系的应用状况也为开发者带来了很多不便和负担。iOS 需要进一步发展,打破这种孤岛状态,从系统层面使应用可以相互通信是迟早需要迈出的一步。iOS 会在何时用什么样的实现形式来彻底打通应用之间互通信息、传递数据的渠道,十分值得期待。

Android:选择权与秩序之辩

流畅而便捷的应用间通信机制是 Android 胜出其它智能手机操作系统的显著优势。而随着越来越多的应用开始利用这一机制,分享菜单变得越来越长,在一些时候甚至显得比较混乱,用户要在长长的分享菜单中找到需要的条目有一定的困难。在充分满足用户选择权和分享需求的同时,用什么样的方式让用户可以自行定义和排列每个协议的分享内容,以达到更高的效率,是一个值得关注的改进方向。

除非特别声明,极客观察均为极客公园原创报道,转载请注明作者及原文链接。

原文地址:http://www.geekpark.net/read/view/156827

(转)应用间通信——iOS 的孤岛困境

时间: 2024-10-09 06:11:12

(转)应用间通信——iOS 的孤岛困境的相关文章

iOS开发NSOperation 三:操作依赖和监听以及线程间通信

一:操作依赖和监听 #import "ViewController.h" @interface ViewController () @end @implementation ViewController /** * 1:NSOperation的使用:1:先创建队列NSOperationQueue:若不创建队列直接封装任务则默认在当前线程中串行执行任务,其队列分为两种主队列和非主队列,主队列和GCD中的主队列一样[NSOperationQueue mainQueue],而alloc in

iOS中多线程_05_线程间通信NSThread/GCD

1.什么叫做线程间通信 在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 2.线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 3.线程间通信示例 UIImageView下载图片这个例子, 主线程中开启一个子线程去下载图片, 当图片下载完成之后再回到主线程中更新显示图片, 这样的一个过程就是线程间通信的一个过程. 4.NSThread线程间通信常用方法 // 第一种- (void)performSelectorOnMain

iOS开发————对象间通信之block

一.block的概念: 别称:代码段,块,闭包,是苹果公司添加到OC语言中的. 作用:在程序运行的过程中保存一段代码,并且这段代码可以进行传递. 应用:用于对象间的通信. 二.block的语法: 和函数指针的语法相似 要设定block的返回值和参数个数及类型. (1)定义: 无参无返回值的block变量:void (^myBlock)(void) 有参数有返回值的block变量 int (^sumBlock)(int, int); (2)赋值: myBlock = ^{ //block中的代码

线程间通信和线程互斥

线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后在主线程刷新UI界面 视图布局我就不写了,大家自己来吧,线程间通信代码如下: #pragma mark - 添加响应方法触发创建子线程并加载数据 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

线程同步--线程间通信

一.线程同步 线程的同步方法跟其他系统下类似,我们可以用原子操作,可以用 mutex,lock 等. iOS 的原子操作函数是以 OSAtomic 开头的,比如:OSAtomicAdd32, OSAtomicOr32 等等.这些函数可以直接使用,因为它 们是原子操作. iOS 中的 mutex 对应的是 NSLock,它遵循 NSLooking 协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用 unLock 来解锁.使用示例: BOOL moreToDo

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

架构设计:系统间通信(26)——ActiveMQ集群方案(下)

(接上文<架构设计:系统间通信(26)--ActiveMQ集群方案(上)>) 3.ActiveMQ热备方案 ActiveMQ热备方案,主要保证ActiveMQ的高可用性.这种方案并不像上节中我们主要讨论的ActiveMQ高性能方案那样,同时有多个节点都处于工作状态,也就是说这种方案并不提高ActiveMQ集群的性能:而是从集群中的多个节点选择一个,让其处于工作状态,集群中其它节点则处于待命状态.当主要的工作节点由于各种异常情况停止服务时,保证处于待命的节点能够无缝接替其工作. 3-1.Acti

三层交换机的路由功能实现VALN间通信

交换机是交换数据,只能识别MAC地址,而交换机可以转发数据包,能够识别IP地址,所以能够转发数据包.而三层交换机的也有路由功能,所以也能转发数据包.今天这堂课就有三层交换机实现不同vlan间通信来加以验证. 器材:三层交换机一台,二层交换机一台.电脑三台,带水晶头双绞线若干. 原理图: 过程: 1:连线,把PC1,PC2分别连到三层交换机的fa0/1,fa0/6.把PC3连到二层交换机fa0/1.再用一根线一端连到二层交换机的fa0/10,另一端连到三层交换机fa0/10. 2:对交换机进行配置

架构设计:系统间通信(32)——其他消息中间件及场景应用(下2)

(接上文<架构设计:系统间通信(31)--其他消息中间件及场景应用(下1)>) 5-3.解决方案二:改进半侵入式方案 5-3-1.解决方法一的问题所在 方案一并不是最好的半侵入式方案,却容易理解架构师的设计意图:至少做到业务级隔离.方案一最大的优点在于日志采集逻辑和业务处理逻辑彼此隔离,当业务逻辑发生变化的时候,并不会影响日志采集逻辑. 但是我们能为方案一列举的问题却可以远远多于方案一的优点: 需要为不同开发语言分别提供客户端API包.上文中我们介绍的示例使用JAVA语言,于是 事件/日志采集