ios打包IPA的各种问题和解决方法

最近做了一个东西,在打包ipa文件时遇到了各种问题,纠结了我好几天。


由于我一直是做android的,在打包时以为ios打包也和android一样:用IDE(eclipse)生成一个签名证书,然后打包。事实证明ios的打包比这复杂多了。下面介绍一下我遇到的各种问题。


1.证书问题

要打包ipa首先需要设置code sign identity,一个应用需要打包至少需要三个要素:证书,APP ID,还有一个容易被忽略的provisioning profile。

证书的申请流程到处都可以找到,这里只简单介绍一下,首先使用钥匙串创建一个certSigningRequest文件,然后登录apple developer的ios developer申请证书,将certSigningRequest文件上传,生成一个证书,将它下载下来即可。

接着是APP ID,仍然是到apple developer创建,一般是公司域名的倒写加应用名。

我之前一直以为到这里就结束了,就archive,结果每次都悲剧。问题出在provisioning profile上,之前一直不理解为什么要这个东西,当我创建之后就知道它存在的理由了。大家知道应用在发布之前,要在没有越狱的真机上测试的话,就要将机器UDID添加到你的开发者帐号中去,而一个应用如何知道你的开发者帐号里面添加了哪些UDID呢?就是通过provisioning profile,它也是通过apple developer官网创建,在创建时会让你选择类型,打包ipa测试的话就选择AD HOC,记得添加UDID,创建后下载下来生成mobileprovision文件,双击运行即添加到资源库中去,而xcode在读取你的系统里的证书时实际上是在查找资源库里面的provisioning profile。provisioning profile包含了证书,APP ID和UDID列表,archive后这些信息会被加入ipa中。


2."file not found"

在archive时会碰到一个蛋疼的问题,就是明明在模拟器编译运行都正常,但是打包ipa时却报一个找不到头文件的错,这是由于直接编译时使用的是你的系统的头文件目录,而archive时使用的时SDK下的头文件目录,一般情况下这两者时一致的,但是有些特殊库的头文件,如libxml,在系统下/usr/include/libxml2是包含在头文件自动搜索范围内的,而SDK中这个目录不在自动搜索范围内,所以就会报一个"file not found"。

解决方式就是在编译参数里面添加一个头文件搜索目录,工程->build setting,搜索header search paths,添加你需要手动添加的头文件目录,如/usr/include/libxml2。


3.显示archive success,但是organizer不能自动弹出,手动打开也看不到刚刚打的包,或者没有share按钮可点

遇到这种问题可能有各种不同的原因,但是我敢说90%以上都是因为同一个原因,而这个问题的解决方法也超简单,工程->build setting,搜索deployment,找到skip install项,将其改成NO,target->build setting,搜索deployment,找到skip install项,将其改成NO,网上找到一些资料说target下要改成YES,但是我真实操作下却是改成NO才生成ipa的,说实话,我并不理解它的原理,各位看官可以YES和NO都试一下。


4.运行时出现unrecognized selector sent to instance

编译通过,archive完成,但这并不代表成功了,如果运行的话,可能会报出unrecognized selector sent to instance错,查看错误是标准SDK方法找不到,像UIImage的

initWithContentsOfResolutionIndependentFile:(NSString *)path。

这种问题这往往是链接时缺少参数所致,在编译链接时不会报错,但是运行时就会暴露出来,在build setting搜索other linker flags,加上一条"-ObjC",问题解决。


5.两个工程存在引用关系时,模拟器可以编译通过,但是archive失败

一个应用可能是一个主工程和一个或多个静态库工程组成,主工程引用静态库工程,开发者往往简单得在build phases项的link binary with libraries中将同一个workspace的静态库工程的.a文件应用到主工程,在模拟器编译运行都没有问题,但是在archive时要么报头文件找不到,要么报库找不到。

就我自己的经验而言,我觉得这种错往往出现在从java转过来的人,java开发大多是在eclipse上进行的,工程引用只需要设置一下在当前workspace下导入的工程就可以。这容易形成惯性思维,认为只需要有工程引用就可以编译运行,这在xcode的模拟器可行,但是archive却是行不通的。

C的引用不外乎两个东西:头文件和库文件。在xcode中一个静态库工程的头文件需要被外部引用,就需要在编译时将它拷贝到工程的目标目录,而一个工程需要引用静态库的头文件,就需要在它的头文件搜索目录中添加静态库工程拷贝头文件的目标目录,至于如果添加头文件搜索目录,可以看第二条。库文件也是如此,静态库工程的目标编译文件往往是.a文件,它不需要设置目标目录,而是在编译后生成在静态库工程的build目录中(并不是直接放在下面)。但是不要高兴太早,如果认为问题就此明朗就错了。

iPhone编译通常分为三种模式:Debug,Release和Distribute,它会在编译时分别在build目录中生成对应的xxx-iphonesimulator或者xxx-iphoneos目录,前者是模拟器方式编译,后者是device方式编译。这并不意味着我们需要在头文件搜索目录中添加六条,在编译环境下存在一些环境变量,如SRCROOT,它代表工程源码的根目录,取值方式和linux中的makefile是一样的:$(SRCROOT)。上面的编译模式也有一个环境变量指定:CONFIGURATION,它在三种模式下指定对应模式的值,当archive时,添加头文件搜索目录可以指定:静态库工程根目录相对$(SRCROOT)的目录/build/模式-iphoneos/include。库文件搜索目录也是如此,它会直接生成在:静态库工程根目录相对$(SRCROOT)的目录/build/模式-iphoneos目录下。还有一个很有用的环境变量EFFECTIVE_PLATFORM_NAME,它指的时编译时的device,可能是iphoneos,也可能时iphonesimulator,另外使用这个不需要特别加上一个"-",也就是说$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)就表示编译的目标目录。

这样会有一个问题,就是编译时需要一个顺序,即先编译静态库,再编译主工程。在运行/停止按钮旁边选择edit schema,选择build,把parallelize build项的钩去掉,它表示并行编译,在下面的编译目标中把静态库放在主工程之前,编译时就会先编译静态库,再编译主工程。到此,这个问题算是解决了。


6.提交审核时说找不到"icon.png"

往往老工程的plist会有一项配置指向"icon.png",但是新的icon发布策略已经改成json配置,所以我们往往会把icon文件直接移动到Image.xcassets里面,这时,原本的引用位置没有文件,编译时不会报错,因为不是在.xproj文件配置的,测试运行也不会报错,但是发布时苹果会检查"icon.png"这个配置,发现没有文件,就报错了。解决的办法是在原本引用的位置拷贝一份,或者干脆把这个配置去掉(这个我没试过,各位慎选)。


7.使用Hybrid的同学注意啦

现在很多项目会使用Hybrid的方式开发,一来不容易动不动就崩溃,二来节省发布成本。苹果现在貌似开始关注Hybrid对它的影响了,因为高度HTML5化的Hybrid应用完全可以绕过AppStore,其结果是苹果为打造开发者平台所做的努力会大打折扣,无论从应用质量考虑,还是从dollar上考虑,都苹果容忍不了的。你最好把HTML界面做得尽量看不出时HTML做出来的,更不要在任何界面显示的诸如HTML版本等信息(简称作死)。目前苹果没有明确禁止,但是未来会不会禁止,或者会不会在你发布时需要选择是否使用了Hybrid呢?


8. 找不到armv64

当关联静态库工程打包测试的时候,静态库工程会生成.a文件,但是用lipo -info xxx.a查看支持的CPU架构时会发现只生成了一种架构,这是因为Xcode在编译时会识别当前连接到电脑的手机CPU架构,生成的.a文件只支持这个架构,这个可以在Build Active Architecture Only中配置,YES表示只会生成识别到的架构,NO表示生成Architectures配置的所有架构。


目前遇到的比较头疼的问题就这几个,以后遇到新的会再更新。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值