iOS Release 版本开启调试功能
在 iOS
开发中,对外发布的 TestFlight
版或者正式版都是以 Relase
方式构建。而我们一般会在 Debug
模式下开启某些调试功能或打印日志,但是这些操作在 Release
无效。
当我们需要在 Release
版本中启用调试功能时,就不太方便了。而解决这个问题似乎没有很优雅的方式。
在读过 https://andrewking.ca/2020/04/how-to-enable-custom-debugging-in-release-builds/?utm_campaign=iOS%2BDev%2BWeekly&utm_medium=email&utm_source=iOS%2BDev%2BWeekly%2BIssue%2B454 这篇文章后,发现一个比较新奇的方法。
常规方式
文章前半部分提供了几种可能的方式,比如:
使用一个新的配置定义
TESTFLIGHT
。
在发版本的时候打两个包,一个是开启 TESTFLIGHT
配置,另一个关闭 TESTFLIGHT
。但这并不能很好的区分哪个包对应的是什么配置。
硬编码
userId
。
代码中维护 userId
列表,只对指定的 userId
生效。但添加/删除需要修改代码,且有些功能并不需要登录。这种方式可以进一步延伸到使用 deviceId
,通过服务端下发列表。
检查安装来源。
区分 TestFlight/App Store/本地 build
几种安装方式。而苹果并没提供官方 API
来获取来源,作者提供了一个 hack
的方式,但可靠性有待确定,因为这种方式极大的依赖苹果实现。
使用秘密的手势。
使用某种复杂的手势来作为开关。但是如果有用户知道了这个手势,也可以调起调试功能。
这种方式让我想起上家公司有关某个功能调试开关的实现,思路比较好玩。
在 app 的某个页面,比如「设置 - 关于我们」(最好是无额外点击事件的页面)。把当前页面按照数字 0-9
分为 10
个虚拟区域,类似拨号键盘排布。如下图所示:
而密码就是当前的手机时间,以 4
位数字表示,不足补 0
。在页面上按照预设区域输入当前时间(当前实际上看不到任何分隔线的,估摸大致区域),即可打开调试开关。
使用秘密的
url scheme
。
通过特定 url scheme
来唤起 app
,以开启调试功能。但它有几个弊端:
为了防止被破解,
url
不能太简单,而且开发者需要记住该url
,调试不便。由于需要在浏览器中输入
url
,那么意味着需要离开app
进行操作,增加调试成本。如果有其他人意外知道了
url
,同样也可以调试。
重头戏
下面重头戏来了,其方式是通过检测一个特殊的描述文件 Debug Profile
是否在机器上安装,来确定是否开启调试功能。
这种方式有如下好处:
如果想要调试就必须有描述文件,而普通用户无法获取。
只需安装一次描述文件。
一个描述文件 可以被多个
app
使用,不同优先级的功能可以使用不同的描述文件。从
App Store
安装的app
也可以使用,因为只需要有描述文件。不需要特殊的环境和用户。
但是也有其坏处:
需要创建存储证书、 描述文件。
需要根据检查证书信任结果来确定是否安装了描述文件,并且作者承认,检查方式有一点
hack
。需要将描述文件存起来,不能丢失。
原理
这种方式是基于 SecTrustEvaluate
方法来验证证书是否受信任。
使用 SecTrustEvaluate
来确定用户是否安装且信任了证书(通过安装描述文件),还是仅仅打包在 app
中未受信任的证书。
因此我们需要做的事情如下:
创建证书
创建和安装描述文件
检查证书是否被信任
下面我们来一步步的操作。
1. 创建证书
打开证书助理,选择创建证书颁发机构。
填入名称和邮箱,反选
Make this CA the default
,并勾选Let me override defaults
。
点击继续,修改有效期为
7300
天,即为20
年。
下一步,选择证书。这里我选择的是自己账号的证书。
接下来,一直下一步,直至创建完成。
点击 Show CA Certificate
可以看到成功创建的证书。
2. 创建叶子证书
打开证书助理,选择创建证书颁发机构
填入名称和邮箱,反选
Make this CA the default
,并勾选Let me override defaults
。
注意这里跟第一步有所不同:
Identity Type
选择intermediate CA
。User Certificate
选择custom
,找到第一步中创建的xx.certAuthorityConfig
文件。其目录在~/Library/Application Support/Certificate Authority/<your CA name>/<your CA name>.certAuthorityConfig
修改有效期,同第一步中对应的操作
。
选择证书,同第一步中对应的操作
。
选择发行者。
这里选择第一步中创建的证书,我的证书名是 summer
。
一路下一步,直至完成
3. 导出叶子证书
在 Keychain Access
中,选中第 2
步创建的 leaf certificate
,右键导出为 cer
格式,并加入到自己的工程中。
4. 导出 CA 证书
在 Keychain Access
中,选中第 1
步创建的 root certificate
,右键导出为 cer
格式。不需要添加到工程。
5. 创建 Debug 描述文件
下载
Apple Configurator 2
点击
File -> New Profile
在
General
中填入描述文件名称。在
Certificates
一栏中选择在第4
步中导出的root.cer
。cmd+s
保存Profile
,取个合适的文件名,这里我将其命名为custom-debug.mobileconfig
。
6. 编写检测代码
这里我将原文中的 SecTrustEvaluate
替换为了SecTrustEvaluateWithError
,因为 SecTrustEvaluate
在 iOS 13
上不再推荐使用。
SecTrustEvaluateWithError
的返回值为 bool
。若为 true
,则表示信任;若为 false
,则表示不受信任。
代码如下:
7. 在需要调试的机器上安装描述文件
将手机用
USB
连上电脑,选择对应的设备。点击添加,选择
Profiles
,再选择第5
步中创建的描述文件。
此时,在手机上会出现描述文件已经下载的提示。如下图所示:
同时 Apple Configurator
是下图状态,等安装完成会自动消失。
安装描述文件。打开
手机设置 -> 通用 -> 描述文件与设备管理
,选择对应的描述文件进行安装。
8. 运行工程
运行工程,会发现此时 SecTrustEvaluateWithError
返回的 result
为 YES
。
另外可以自行测试一下,如果移除了描述文件 Debug Profile
,该结果则为 NO
。
版权声明: 本文为 InfoQ 作者【liu_liu】的原创文章。
原文链接:【http://xie.infoq.cn/article/ba40bc882f9f4377c723cf929】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论