分享

iOS自动打包的若干坑

 Tornador 2016-09-12

公司这边为了统一管理应用证书跟应用发布,搭建了一个iOS自动打包平台。iOS应用打包使用了脚本来完成,核心是使用了苹果提供的xcodebuild命令。使用脚本打包的确带来了很大的方便,但在各个不同项目组使用的过程,就发现了各种各样的坑,其中的原因包括脚本本身的缺陷、各个项目组形形色色的设置,当然还包括苹果公司。本文将不会对xcodebuild命令的使用进行说明,xcodbuild的使用可以参考网络其它资料,本文主要对项目组使用打包平台所遇到的各种问题进行总结,所有的故事汇集在一起,会让你对苹果公司应用打包机制了解的更透澈。

 

1.狸猫换太子

有一天,项目组A给我打了个电话,说他们的项目在打包平台打出的ipa有问题。具体情况是打包没有报错,ipa也下载下来了,但发现除了测试手机外其它手机装不了。现象有点像是用了开发证书一样,他也是这样怀疑的,问我证书是不是弄错了。我登了打包电脑看了下,页面上配置的证书是对的,又查看了一下打包的log,打印出来的证书配置也是对的。实在想不通,然后登录了开发者账号看看,证书没问题,也是有效的,确认不是配置跟证书有问题之后,我把ipa下载下来,ipa其实就是一个zip文件,可以直接把它解压查看其中的内容。我打开里面的证书,双击安装了下,会提示覆盖已有的证书,这时问题就来了,竟然提示覆盖另外一个证书,一个Ad命名带通配符的证书。当时我就无语了:这证书哪来的?我又在打包的log搜了下,没有发现跟这证书相关的任何内容。这时“狸猫换太子”这出戏闪现在脑边,想想这换的还真是天衣无缝,中间怎么没有看到任何破绽,有些像完美犯罪一样。但又想想,肯定会留下蛛丝马迹的,于是查了起来。首先这个证书是Ad命名的,说明这是一个xcode自动创建的证书,然后又是一个带通配符的开发证书,说明xcode在某个时候偷偷创建的,打包的时候把它给打到ipa里面了。然后我就把本地的证书通配证书给删除了,再用脚本跑了一下,果然报错:找不到证书。我就想着好好给你指定了一个证书不用,非要找一些乱七八糟的。仔细看了下log,发现archive竟然成功了,在第二步打ipa的时候报错了。我想着证书不是在arichive的时候就用了吗,然后打开了生成的archive,里面也有一个证书,安装一下,竟然是我指定的正确的证书,一下就颠覆我三观了。前面都没问题,怎么在打ipa那一步错了,把证书给换了。这里突然想起前些天刚好把苹果打包命令升级了,用了带plist参数的打包命令,立马改了回去,发现一切都回归正常,打出的ipa也是对的了。苹果公司或许想把用户体验做到最好,尽量简化用户的操作,但这个在我已经配置好的情况下还自动创建、替换我的证书就有点过了,关键xcodebuild里面的细节你也不知道,也没有其它可以替换的命令,市面上其它的工具一般都是在xcodebuild上面再包装一下,冶标不治本。苹果的封闭所带来问题也显而易见了。资料简单、说明少、没有替换产品,以后只能多注意这种问题。

 

2.签名做了什么

苹果使用证书来对应用签名,保障了应用来源的合法性,在安全性上的确有很大提高。但另外一方面,由于iphone对应用签名的检查机制并不清晰,有时遇到因为签名不一致导致安装不了应用的情况。苹果在签名的时候到底做了什么事情呢?

ipa目录下有一个_CodeSignature目录,其中的CodeResources文件记录了当前应用所有的资源校验的信息,其中应该使用了数字签名及资源检验两种技术,每个资源文件会生成一个对应的字符串,如下图所示:

手机在安装应用的时候会根据codesignature进行检验,通过对比资源与校验结果来判断资源是否被修改。这个是在网上传的比较广的说法。在此之前,我也一直简单以为签名只是一个CodeResources的文件。当我遇到多target打包的时候,因为多个target只是BundleID跟签名的问题,然后通过一行命令无法实现设置两个BundleID与签名,就想通过一些方法来绕过,却行不通,才发现签名并没有之前想的那么简单,多了一步。

其实有一个办法可以非常简单地知道签名那一步做了什么,就想一个问题:如果我要替换一个证书,签名之后的结果有什么区别。在前面狸猫换太子那当中我已经知道在使用xcodebuild export那一步的时候可以替换证书。于是使用diffMerge来比较替换证书之后的两个文件夹,看看有什么区别。下面在export那一步替换了证书AB之后使用diffMerge查看的结果:

CodeResources两者不一样,这在意料之中。惊奇发现二进制文件hello竟然也不一样,这是怎么回事?如果你使用过codesign –vvvv –d hello.app查看应用的签名信息,你会发现,如果你把传入的目录改成hello.app/hello二进制文件,上述的命令也能正确执行,可能某几项会缺失,但你却可以看到证书的信息。由此可以知道,签名在给每个资源计算签名值之前,会先将证书的信息写入到二进制文件当中,然后再进行签名。

3.傲娇的iphone 6 plus

使用打包命令在带来方便的同时,也带来了很多问题。脚本里面可以设置的参数是毕竟是有限的,很多参数是需要在项目工程里面来配置。当两者出现了冲突或者有不一致的时候,就有可能带来问题,再加上苹果公司给打包套了个黑盒子,内部细节不对外暴露,出现的问题更让人难以捉摸。傲娇的iphone 6 plus就是遇到的问题之一。某天A项目组给我发邮件了,说他们项目的ipaiphone 6 plus上无法安装,其它手机能够正常安装使用。我当时就懵了,xcode也没听说有什么配置会使得某个型号的手机无法安装啊。由于没有测试机,就去A项目组那边查看具体情况,负责人向我演示了一下,他那个iphone 6 plus在安装的时候就会失败,entitlement不一致什么的。虽然看到了结果,但还是没有头绪,也不可能把iphone给拆了,关键拆了你也不知道里面是怎么检查的。实在没办法,只能把他们的项目拉下来自己进行对比,检查了大半天,只发现他们在工程配置的bundleid跟打包平台上配置的不一样,在生成的ipa当中,info.plist当中的bundleid跟打包平台上配置的不一致。然后让他们先改了再打包一次,确认了ipainfo.plist没问题之后再让他们安装,结果奇了,安装上了。我当时以为是跟系统版本有关系,然后问了一下,是9.2的系统,但之前其它型号的手机也是9.2的,安装也没问题,但说明跟机型还是有很大关系。最后虽然解决了这个问题,但感觉还是挺无语的,因为没有各种型号的测试机,如果各种细节问题跟机型有关系那就很难处理了。不过另外一方面也要求打包平台上的项目配置尽可能规范,保持一致性,只能不断积累,尽量避免这类问题。

4.卡到天荒地老

打包平台在最初使用的时候会遇到有些项目在运行脚本的时候会卡住,刚执行到xcodebuild命令时就卡在那边没动静了,直到天荒地老。最初主要的原因是工程的scheme没有选中为sharedxcodebuild找不到scheme,但也不报错,然后就一直停在那边,这个问题在xcode旧版本上会出现,最新的7.X版本我测试了没有再发现这个问题。每次遇到这种问题的时候都会提醒项目组将shared选上就能解决。但某一天却遇到一个特别奇怪的现象,在提醒了项目组将shared选上之后,提交上来的代码依然不能打包,运行会卡住。我把他们的工程拉到自已电脑上,直接用脚本打包发现不行。然后打开他们的工程,确认是否选中shared,发现选上。然后再用脚本打包了下,竟然发现又能正常打包了。通过不断测试,发现这样的规律,工程直接拉下来,打包失败,卡住,用xcode打开工程后不做任何处理,再次打包就能成功。虽然从表面上看我只是用xcode打开了工程而已,什么也没有做,但实际上并没有这么简单。当时我就怀疑xcode在后面默默做了一些事情,只是没看到而已。为了印证自己的想法,就通过svn来查看打开工程之后文件的变化,最终发现打开工程后会在*.xcodeproj目录下创建xcshareddata/xcschemes目录,这个是在选中shared的时候会创建该目录及文件,项目组的svn上并没有将该文件上传上来。xcode默认应该有一套纠错机制,检测到缺失后自动创建了目录文件。而在xcode打开之前使用脚本打包的时候就会发现缺少的shared的信息,导致打包失败。然后就让项目组把缺少的目录及文件都提交到svn上也就解决了这个问题。注意,现在xcode7.X在打包时不会有这种问题了,我本来想重现下这个现象,却发现在最新的xcode7.X上没能做到。现在写在这里也是想提醒xcode本身有一套处理机制,打开工程并没有想像的简单,遇到这类问题就做文件比较吧,svn还有这种功用。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多