URL整套的设计思路就是在整体的互联网中解决信息孤岛,让各个信息孤岛之间能够进行资源发现和资源调用而设计。而我们目前所要处理的模块间通信问题,其实是这个宏大问题域的一个子集。因而选用URL协议,是一个非常顺理成章的事情。
URL协议解决了模块发现的问题,但是是个静态的txt,并不具备exe的能力。我们可以通过定义一个类似于:
yoho://innerfuction/viewcontroller/showuserinfo?uid=22&xx=33
来让一个模块对外宣称支持显示用户详细信息的服务。但是我们要如何使用这个服务呢?很多Route的实现是通过URL直接将对应的ViewController返回,然后由调用方再去调用接口配置ViewController,而后调用方进行push或者present。而我认为这种方式不是很合理,做为调用发应该尽可能少的知道服务提供方的信息。服务怎么被弹起,应该是由服务方自己决定的,而不是调用方。最好只知道一个URL还有支持什么样的服务就好了,最好能把交互接口精简、精简、再精简。
而思考了一下很多route库之所以没能够做到模块只对外暴漏URL就可以的一个很重要的原因,就是在ViewController被弹出的时候,iOS需要一个调起的ViewController
UIViewController* aVC = [UIViewController new];
//配置aVC需要参数
....
[self.navigationController pushViewController:aVC animated:YES];
就是必须知道当前界面是在哪里,你才能去push下一个界面。只有知道这个self.navigationController上下文信息才行。所以很多事情只能在调用方来处理。我觉得这种方式制约着被调用方需要拿到服务提供方的一个实例才行。每一个问题背后都有一个解决方案。于是我在自己造的轮子中使用了全局UI堆栈的方式解决了这个问题。
通过构造了被调用的上下文信息类DZURLRequestContext,用于携带调用方的上下文信息来解决这个问题。上下文信息中携带了当前UI的堆栈信息,能够方便定位用哪个VC做为起点,来弹出下一个页面。当然使用这个context还有另外一个原因就是因为URL中能够传输的参数类型是受限的,只能传输NSString类型,对于一个实例则不能传输。为了传输实例参数也需要这样的一个context环境。
这样在调用一个页面的服务的时候,就能够做到如下所示极致简单:
[[DZURLRoute defaultRoute] routeURL:DZURLRouteQueryLink(kYHURLSacnQRCode, @{})];
当然该库首先是解决了通过URL调用的问题,而后才是上面说的这些优化问题。同时,也针对很多不同的应用场景提供了解决方案。
github地址:https://github.com/yishuiliunian/DZURLRoute
BY:yishuiliunian