“hey,我们这里数据不一样,把接口发我对一下”
前两天在琢磨一个问题,本以为可以专心死磕的,不料安卓那边突然跟我说“hey,我们这里数据不一样,把接口发我看看”。因为种种原因(其实只是因为他是移动组老大),我只好打开项目,编译,运行,找到特定页面,刷新,在控制台拿到接口,打开QQ,找到他,发给了他。如果是大项目,想想编译运行的时间也是酸爽的。完了之后,我继续回到我死磕的问题上,发现思路已经被打断了。。。更有甚者,你可能得耗一天的时间发接口给安卓,给后台调试。
我们需要做个了结
不知道前面提到的场景大家有没遇到过,反正我是不少的,而且有时候我也会是那个向别人拿接口的那个人。接手了个年代久远的项目,接口文档不齐全,甚至没有;接口文档不详细,接口文档不是最新;接口文档太大,查找起来麻烦等等原因,这时候很多人估计会是直接找另一端请求数据拿接口。但是事情总是向着好的方向发展的,Let's get this thing done!
拦截请求
其实解决的办法很简单,也很容易想到,就是拦截请求——展示接口数据。那好,怎么拦截请求呢,以AFNetworking为例,构造Request的地方是集中在 AFURLRequestSerialization 这个类里面的,
知道了request是在这里统一构造的,接下来就好办了,新建一个view用于展示,在 AFURLRequestSerialization 里导入这个view,然后每次捕获到请求就把view加载keyWindow上。Things get done!等等,好像有什么奇怪的事情发生了,要在Pod上面添加内容,需要unlock,如果要导入类,因为不是同一个target还会提示file not found,而且下次更新Pod,之前的内容也都会不见,虽然有办法解决,不过显然我们不想而且不应该在Pod里面导入自己的东西。
与暴力对应的就是优雅
既然不能暴力解决,那就采用优雅的黑魔法吧,Runtime大法:Method Swizzling。我们可以拦截request的构造方法,在替代的方法上加上展示的逻辑,这样就不会对第三方Pod上造成污染了。这里推荐一个拦截方法的第三方库 Aspects 。以下是处理逻辑。
只实现Aspects的一个方法就能到达拦截效果,简单便捷。
这里是交换方法的逻辑,可以拿到request的参数,URLString,其他参数可以按需获取。最后可以通过一个全局变量来决定是否采取拦截措施,一般app 都有搜索功能,我个人喜好是在搜索框输入特定字段来开启关闭某些隐藏功能。Everything is done!效果图:
总结
整个下来并没有涉及到什么难的事情,只是简单的采用Method Swizzling来拦截请求展示数据,而这恰恰是一件用简单的方式解决繁琐问题的例子,以后可以直接在测试机打个包,然后让后台或安卓自己玩去了。如果有错误的地方或者有其他更好的办法,还请指教。最后附上简单的demo YNTRequestInterception。
PS:关于这个问题我问过一朋友,他是这样回答的:
我相信他没有冒犯的意思。。。