万神劫

万物天地为剑,神鬼妖邪为剑
劫波万渡,宇宙苍穹尽为剑
是为万神劫!

1条评论 2015-12-17

使用Charles Proxy提升iOS开发效率

以前做前端开发的时候,使用最多的工具就是 Fiddler ,用来定位问题、模拟特定场景非常方便,极大提升了开发效率。
而转做 iOS 开发以后,一大头疼的问题是 Fiddler 没有 Mac 版,幸亏找到了 Charles Proxy 这个还不错的替代工具,不过使用上与 Fiddler 还是有不少区别
另外据我不完全的观察,不少 iOS 开发工程师并不习惯于使用 HTTP 抓包工具……因此我觉得还是有必要写一篇文章介绍下 Charles

购买授权

首先,别把时间浪费在寻找破解或者忍受那10秒钟启动时间上,iOS 程序员的时间成本都很高的好吗?
淘宝一家叫做『荔枝正版』的店铺代理的授权码只需要199人民币,请到这里购买(店家看到能给点广告费么……)

使用与配置

鉴于 Charles 的使用教程非常多,本文不打算写成入门教程,而是针对常见的开发场景,介绍如何使用 Charles 提高开发效率
基础的使用,可以参考 iOS开发工具——网络封包分析工具Charles
Charles 本质上是一个 HTTP 代理服务器,因此需要在 iOS 设备上配置代理,不过这也意味着 Charles 只能抓取手机连接 WIFI 时的 HTTP 包,而 3G/4G 则不行
另外强烈建议使用之前先简单了解一下 HTTP 协议,Charles 毕竟只是个工具而已

使用场景

快速定位 BUG 原因

App 开发中最常见的问题是,某个界面需要通过后端 HTTP 接口获取数据并展示,而测试妹子给你提了个 BUG,告诉你这个界面没数据或者数据有误
初级工程师常犯的错误是:一开始就打断点 Debug 或者一口咬定是后端问题,这常常会造成时间的浪费
正确的做法是先缩小 BUG 原因范围,再准确定位,通常我会按照这样的顺序来诊断:
1. Charles 抓到相应的 HTTP 包了吗?没抓到请 debug App 代码
2. 抓到的包 HTTP 响应正确吗?
* 如果无响应,或者 HTTP status 是4xx/5xx/,责任果断推给后端
* 响应是否符合接口文档定义?完全不符合或者多了/少了JSON 字段,责任果断推给后端
* 响应符合定义,但是是报错信息,那么可能是 HTTP 请求不正确,对照请求与文档定义,如果无误,说明文档有错漏……责任依然推给后端
3. 以上都正确,那么问题应该在 App 端,请开始 debug 代码

记得拿着 Charles 的抓包结果截图去找后端,这比 Xcode 控制台打出来的信息更容易说服他们

禁用响应缓存

关于查看响应的部分,有一点需要注意的是,现在不少后端服务都会开启 Etag (不了解的请看维基百科
而如果你使用了 AFNetworking ,那么可能在 Charles 中看不到响应内容(304响应没有 body)
解决方法是点击菜单Tools → No caching,在界面中开启全局或针对特定域名的缓存禁用模式

快速构造请求中、请求失败

通常 App 在发起请求时会有过渡效果(比如转菊花⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄),在请求失败时会有错误提示
不过在开发过程中由于同在一个局域网请求过程通常非常短,一般也不会失败,那怎么去调试这两种界面呢?
一种方式是使用 OHHTTPStubs 这个库通过 Mock 来构造响应,缺点是要写代码,另一种就是使用 Charles 了
先启动 App 发起一次请求,然后在 Charles 中找到相应的请求,点击右键勾选『Breakpoints』

这样,下次 App 再发起同样 URL 的请求时,Charles 会给你一个断点界面,你可以选择 Excute 或者 Abort

如果要调试请求失败的界面,那就点 Abort,App 会进入 HTTP 请求失败的处理流程
如果要调试请求中的界面,那就停在这个断点界面即可,调试完了再点 Abort 或者 Excute

实际操作过程中会发现 Excute 需要点击两次才能完成一次 HTTP 请求,这是为什么呢?请看下节

构造期望的响应数据

App 中常有一些界面会根据后端数据的不同而展现不同的样式,那么在开发过程中就期望后端接口能返回一些特定的数据。如果巴望着后端同学替你『造数据』那就不太现实了,可行的方式依然是上面提到的两种,通过 OHHTTPStubs mock,或者使用 Charles
而 Charles 里要构造数据又有两种方式

实时修改响应

前面提到需要点击两次 Excute 才能完成一次 HTTP 请求,原因是,Charles 的断点功能分别提供了修改 HTTP Request 和 Response 的机会
在点击第二次 Excute 之前,我们可以实时修改响应的内容,点击『Edit Response』,然后选一种合适的展示面板修改即可,比如如果是 JSON 响应的话,推荐使用 JSON 面板

映射本地文件

另外一种方式就类似于 OHTTPStubs 了,可以将本地文件指定为特定 URL 的响应
首先依然需要先让 Charles 抓取到相应的 HTTP 请求,然后在请求上点右键,选择最下面的『Map Local』

然后在弹出界面中选择本地文件

这种方式最大的用处是,当后端接口开发尚未完毕时,App 端可以『自给自足』地完成完整的界面流程。
另外 Charles 还提供了对已有 Map 规则的导入导出功能,这样就可以将编好的整套规则共享给其他同事了,方法是点击菜单 Tools → Map Local,在弹出界面中点击 Export

最后剧透下,我正在考虑如何通过工具将 Map Local 与后端开发流程连接,更高效地实现 App 开发,至于时间点嘛……哈哈

comments powered by Disqus