原文链接:http://blog.csdn.net/hherima/article/details/50827363
【仅用于技术交流,未经允许禁止转载】
通常APP-Server使用http协议,告诉APP需要的展示内容图片,文字。这是一种最为常见的协议了。另外一种客户端内协议,比如新闻APP,点击一个焦点新闻,APP跳到相应的频道或专题。不难发现:前者是Server->APP通信,主要是内容类型的,后者是APP<—>APP内通信,主要是命令、动作类型的。
如何更好的处理APP内通信,这里有必要先介绍一下iOS平台进程间通信。
进程间通信
以iOS平台为例,进程间通信IPC,可以通过自定义URL Schema,然后APP实现-(BOOL) application:(UIApplication *) openURL:(NSURL *) sourceApplication:(NSString *) annotation:(id) 方法,可以处理一些命令和参数。其中sourceApplication即调用者的bundleIdentifier。比如下面这条URL,会调起twitter客户端,并拉起发送推文的界面。
URL Scheme完美解决了同一个操作系统中,调用APP和传输消息和命令的问题。URL Schema机制,给开发者提供了很好的思路,可以解决APP内通信问题。CPMessage应运而生。
什么是CPMessage
CPMessage(Cross Platform Message跨平台消息)可以当做服务器/客户端(让客户端处理一些命令),或者客户端内部通信的桥梁。通信的发起者可能是服务器、Push、用户操作、HTML5或者是别的APP。客户端根据具体命令和相应参数,执行相应动作。总之,CPMessage思路源于iOS平台的URL Schema机制。
CPMessage的机制
为了确保多平台的一致性,使用协议名称CPM作为开头,只是传递协议的方式不同。在iOS上,向客户端通信的方式是scheme+protocol,例如:
cpm://message.cmd?messageID=MsgID&urls=EncodedURLStrings&uid=uid&ex1=ex1&ex2=ex2&ex3=ex3。
下面将各部分标注一下:
一般来说:命令名称都是message.cmd,经常改变的是messageID(下面详细介绍)。参数列表中,messageID表明是那种动作,比如,打开一个webview、打开新的页面、还是调起登录框等。参数列表后面是一些辅助参数。下面的表格给出了一些示例。
参数 | 用途 | 格式 | 示例 |
MessageID | 用来指定客户端做出的响应 | string | 1.1 |
url | 需跳转的网址 | string | www.baidu.com |
ex1 | 额外参数 | string | “03” |
另外,如果ex1、ex2和ex3不够用。还可以使用more参数。比如:more = {"title":"helloworld","name":"jack"};more参数格式为json格式。方便客户端解析字段。
MessageID
MessageID根据可分为mainID和subID,比如MessageID=2.1。那么mainID是2,subID是1。一般来说mainID是操作类型的区分,比如:
mainID=1表示打开页面。
mainID=2是传递数据。
mainID=3 是打开其他sdk等等。
subID则是一些操作的细分类型,比如:打开那个页面等等。
APP都是跨平台的,至少有iPhone,Android客户端,那么URL Schema头部将是不同的。举例:Server给的H页面中,某个链接是个CPM消息,URL Scheme配合CPM的使用,如下格式:
myapp://cpm://xxxxxx。操作系统级别会读取到“myapp://”从而拉起客户端,客户端内部读取到“cpm://”
CPMessage的使用
开发者如何应用CPMessage到自己的APP中呢?你需要做三件事:第一,提前注册一些UIViewController和方法,封装成一个个CPMessageItem。
第二,当CPMessage过来的时候,将其解析成CPMessageCommand,其中CPMessageCommand包含了参数。
第三,使用一个CPMManager类,将command 和 item对应到某一个UIViewController,并使用NSInvocation,调用之前注册好的方法。
那么,回到刚才一开始的问题,我们假设MessageID = 1.1 即跳转频道,ex1即频道的index。那么,Server将下面的URL消息,封装到焦点新闻里
cpm://message.cmd?messageID=1.1&ex1=03
客户端TabViewController注册一个调转频道的method -(void) switchToChannel:(int)index,执行CPMManager,TabViewController 执行switchToChannel方法。可以很优雅的解决新闻APP,调转到任意频道的问题。
CPMManager的UML图+流程图
CPMManger 的几个关键函数
prepareProcessor 事先注册好一些类和类方法
handleUrl:接收url,带有cpm schema的url
onCPMIsComing:参数是CPMCommand
handleCPM:参数CPMCommand。最终通过[NSInvocation invoke]实现回调。
CPMManger的实现
这里只列出部分代码,即CPMManger的关键代码: