archive包真机运行崩溃问题一则
1.问题描述
1.1.运行环境
- 模拟器版本:iPhone6 && 8.4||9.3
- 真机版本:iPhone6p && 8.4
- 签名证书:企业发布证书,个人开发证书
1.2.背景
APP功能大体完成之后,因为要用iOS版本给领导演示,所以早上急急忙忙地打包给需求。
1.3.问题
因为前两天出现了build打包导致5c手机安装失败的问题(architecture不符,/(ㄒoㄒ)/~~),所以便老老实实地用企业证书archive打包,打包后上传到蒲公英网站,然后用测试手机6p扫描安装。
安装成功后把所有功能点了一遍,但最后突然发现有个打开网页的功能报404错误,而另外一个页面的几个打开网页的功能则干脆崩溃闪退!我心中一紧之后连忙把URL拿到浏览器里打开,是正常的。然后用模拟器运行打断点,发现也是正常的。用个人开发者证书连真机调试,也是正常的!!
2.解决方法
2.1.思路
因为在模拟器中和真机调试模式下运行是正常的,所以开始怀疑问题出在企业证书或者archive打包上。
于是我又尝试了另一个企业证书archive打包,发现还是存在同样的问题。而使用企业证书build打包,问题是不存在的。所以感觉问题还是出在archive打包上。
在Xcode中查看了一下手机的崩溃日志,发现有一个Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘* setObjectForKey: object cannot be nil (key: nsrsbh)的错误信息。
而这个nsrsbh的信息只有在APP已登录的情况下才有值。但是出现崩溃问题的功能实际上是不需要登录操作就可以直接访问的。
所以最终的问题定位到了下面这段代码:
GDWebURLParseType parseType;
if ([extraInfo[@"parserType"] isEqualToString:@"tgc"]) {
parseType = GDWebURLParseTypeTGC;
} else if ([extraInfo[@"parserType"] isEqualToString:@"cl"]) {
parseType = GDWebURLParseTypeCL;
} else if ([extraInfo[@"parserType"] isEqualToString:@"lt"]) {
parseType = GDWebURLParseTypeLT;
}
webUrl = [GDUtil parseWebURL:webUrl parseType:parseType];
parseType变量是一个枚举变量,
typedef NS_ENUM(NSUInteger, GDWebURLParseType) {
GDWebURLParseTypeLT,
GDWebURLParseTypeCL,
GDWebURLParseTypeTGC
};
而+GDUtil parseWebURL:parseType:方法会根据parseType的不同组装url,其中当parseType为GDWebURLParseTypeLT时,会用到上面崩溃信息中的nsrsbh字段赋值。
那这样看来,问题是出在parseType的默认值上,在模拟器/调试模式下为随机数,而archive真机上则是0,所以在未登录状态下进入了需要登录才能够进入的代码逻辑,从而导致崩溃。
2.2.结论
问题既然已经定位,那么解决便容易了,只需要给枚举类型赋初始值即可。
GDWebURLParseType parseType = NSIntegerMax;
修改完后重新archive打包安装运行,一切OK。
3.原因
导致该问题的原因还未深入查找,不过从正常的语法规则来说,全局定义的枚举类型的初始值为0,在本例中也就是GDWebURLParseTypeLT。所以在编码时还是要保持良好的编码习惯,该做的变量初始化不能少。