背景

蘑菇直播小程序在上线前爆发了一系列兼容性问题, 比如 Video 控件在某些安卓手机的布局会跳来跳去, SKU组件在 iOS8 上显示不出来等等兼容性问题. 然而微信并没有一个真机调试的方法, 我们只能用不断打log, 删代码然后一行行加回去之类的原始方法去排查问题, 比如为了解决 SKU 组件在 iOS8 上显示不出来的问题, 我曾经反复打了三十几个包才找到问题.

作为一个高贵的iOS工程师, 我相信这个问题一定有更好的解决办法, 就开始了我的探索.

引用微信文档的一段介绍:

在 iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中,是由 WKWebView 来渲染的,环境有 iOS8、iOS9、iOS10

在 Android 上,小程序的 javascript 代码是通过 X5 JSCore来解析,是由 X5 基于 Mobile Chrome 53 内核来渲染的

所以我们要做的就是想办法通过调试 Webview 来调试页面布局, 通过调试 JSCore 来调试逻辑代码.

结论

经过探索, 目前 iOS 上可以达到和开发者工具一样的效果, 即调试 JavaScriptCore 中的代码, 以及 inspect WKWebView 中的 DOM tree.

而 Android 上, 目前只可以做到 inspect X5 中的 DOM tree, 还没有找到调试 X5 JSCore 中的代码的方法.

效果图如下:

图1 iOS 上 inspect DOM tree

Inspect DOM tree on iOS

图2 甚至可以用 Reveal 看 Native Layout (可以看到一个Native的VideoView盖在了Webview上)

Reveal

图3 iOS 上给代码打断点

Set Breakpoints on iOS

图4 Andriod 上 inspect DOM tree

Inspect DOM tree on Android

iOS真机调试的原理

iOS因为有严格的权限, 只能调试被你自己的开发者证书签名的 App. 所以真机调试的原理就是欺骗 iOS 系统我们是 WeChat 这个 App 的开发者, 对 Wechat 用自己的开发者证书重签名, 然后我们就能对 WeChat 中的 Webview 进行调试了.

重签名的操作过程比较复杂, 具体原理大家可以移步这篇文章进行了解.

不过, 我们有IPAPatch, 将这个流程自动化了, 缩减到只要添加一个砸过壳的ipa进去, 就能对这个ipa重签名.

重签名之后, 就可以对 WeChat 里的 Webview 进行调试了, 然而 JSCore 里的代码还是无法调试, 死活找不到对应的脚本.

经过多次尝试后, 这篇文章启发了我, 只有当给 evaluateScript 传一个 source 参数, 这个 script 才会出现在 Safari DevTools 里的脚本列表里. 所以我们通过 method swizzling 给它加一个 source 参数就好.

JSCore Debug

iOS真机调试的教程

流程虽然比较复杂, 但是我会提供一个整合好的工程, 只需要下载一个iOS工程, build & run, 就能用了.

Step By Step:

  1. 下载工程IPAPatch.zip, 用 Xcode 打开 IPAPatch.xcodeproj

  2. 配置开发者证书, 从 Xcode7 之后, 不需要开发者账号, 一个普通的 AppleID 即可

  3. 设置 -> 通用 -> 描述文件 -> 信任你的证书

  4. 设置 -> Safari -> 高级 -> Web检查器打开

  5. 调试页面的方法

    1. 先使用重签名版的微信, 随便打开一个小程序

    2. 打开Mac上的Safari, 找到你的设备, 选择要调试的页面Find page

    3. 打开选中元素开关Enable Inspect

    4. 手机上随便点一个元素, 就可以 inspect 了.Inspect DOM tree on iOS

  6. 调试逻辑代码的方法

    1. 找到你的设备, 选择JSContextFind JSContext

    2. 在资源tab, 选中所有资源里面的 Script_wxAppData 这脚本, 就是我们的业务代码的 bundle 了, 使用 cmd+f 查找一个方法名, 比如 onTapImage, 然后设置断点即可. 注意这里不可以用 debugger 来设置断点, 因为 debugger 会在打包时被去掉.Scripts

Android真机调试的教程

相比 iOS, Andorid 的方法比较简单. 使用腾讯 X5 的调试工具 TBS 即可.

  1. 首先安装adb https://stackoverflow.com/questions/31374085/installing-adb-on-mac-os-x

  2. Andorid手机需打开USB调试开发

  3. 确保使用命令 adb devices 可以看到你的设备

  4. 安装TBS, 打开TBS, 按照提示的步骤开启调试

最后在TBS中, 在Devices找到对应设备中的页面, 点击inspect, 即可调试页面

不过我找了很久, 始终找不到调试X5的JSCore的办法, 只能放弃.

TBS Devices

Inspect DOM tree on Android

Android真机调试逻辑代码的备注

安卓端的小程序逻辑代码是运行在 X5 JSCore 中的, 底层是v8, 根据官网上的版本号推算应该是5.3版本.

而想要v8的5.6版本之前的版本实现调试, 必须由开发者自行实现它的调试协议, 才能被inspect, 和iOS的JSCore不一样.

而实现调试协议成本应该挺大, 参考这篇分享, 所以看起来只能由微信官方来支持了. 咨询过微信的同学, 那边也在计划开发一套真机调试工具, 不过要打通两端的JSCore协议成本比较大, 时间可能会比较久.

END

最后希望微信官方可以加紧抹平两端差异, 从底层解决各种奇奇怪怪的兼容性问题, 以及提供一个官方的真机调试方法.

本文链接地址: http://jichaowu.com/2017/07/25/remote_debug/, 转载请标明出处.