前言】未来, Watch 应用必须包含 bitcode ,iOS不强制,Mac OS不支持。 但最坑的一点是: Xcode7 及以上版本会默认开启 bitcode 。
Bitcode是什么?
通俗解释:在线版安卓ART模式。
Apple 官方文档-- App Distribution Guide – App Thinning (iOS, watchOS) 是这样定义的:
Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the App Store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.
翻译过来就是:
bitcode 是被编译程序的一种中间形式的代码。包含 bitcode 配置的程序将会在 App Store 上被编译和链接。 bitcode 允许苹果在后期重新优化我们程序的二进制文件,而不需要我们重新提交一个新的版本到 App Store 上。
在 Xcode简介--- What’s New in Xcode-New Features in Xcode 7 中这样描述:
Bitcode. When you archive for submission to the App Store, Xcode will compile your app into an intermediate representation. The App Store will then compile the bitcode down into the 64 or 32 bit executables as necessary.
也就是
当我们提交程序到 App Store上时, Xcode 会将程序编译为一个中间表现形式( bitcode )。然后 App store 会再将这个 bitcode 编译为可执行的64位或32位程序。
再看看这两段描述都是放在App Thinning(App瘦身)一节中,可以看出其与包的优化有关了。
App Thinning 官方文档解释如下:
The App Store and operating system optimize the installation of iOS and watchOS apps by tailoring app delivery to the capabilities of the user’s particular device, with minimal footprint. This optimization, called app thinning, lets you create apps that use the most device features, occupy minimum disk space, and accommodate future updates that can be applied by Apple. Faster downloads and more space for other apps and content provides a better user experience.
开发者都知道,当前 iOS App 的编译打包方式是把适配兼容多个设备的执行文件及资源文件合并一个文件,上传和下载的文件则包含了所有的这些文件,导致占用较多的存储空间。
App Thinning是一个关于节省iOS设备存储空间的功能,它可以让iOS设备在安装、更新及运行App等场景中仅下载所需的资源,减少App的占用空间,从而节省设备的存储空间。
根据Apple官方文档的介绍,App Thinning主要有三个机制:
Slicing
开发者把App安装包上传到AppStore后,Apple服务会自动对安装包切割为不同的应用变体(App variant),当用户下载安装包时,系统会根据设备型号下载安装对应的单个应用变体。
On-Demand Resources
ORD(随需资源)是指开发者对资源添加标签上传后,系统会根据App运行的情况,动态下载并加载所需资源,而在存储空间不足时,自动删除这类资源。
Bitcode 开启Bitcode编译后,可以使得开发者上传App时只需上传Intermediate Representation(中间件),而非最终的可执行二进制文件。 在用户下载App之前,AppStore会自动编译中间件,产生设备所需的执行文件供用户下载安装。
其中,Bitcode的机制可以支持动态的进行App Slicing,而对于Apple未来进行硬件升级的措施,此机制可以保证在开发者不重新发布版本的情况下而兼容新的设备。
Bitcode 是一种中间代码,那它是什么格式的呢? LLVM 官方文档有介绍这种文件的格式: LLVM Bitcode File Format 。
如果你的应用也准备启用 Bitcode 编译机制,就需要注意以下几点:
.app
体积会变大(中间代码,不是用户下载的包),且 .dSYM
文件不能用来崩溃日志的符号化(用户下载的包是 Apple 服务重新编译产生的,有产生新的符号文件)Bitcode配置?
在上面的错误提示中,提到了如何处理我们遇到的问题:
You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
正如开头所说的:
未来, Watch 应用必须包含 Bitcode ,iOS不强制,Mac OS不支持。 但最坑的一点是: Xcode7 及以上版本会默认开启 Bitcode 。
Xcode 7 + 会开启 Bitcode。
也就是说,也两种方法适配:
方法一:更新 library 使包含 Bitcode ,否则会出现以下中的警告;
(null): URGENT: all bitcode will be dropped because '/Users/myname/Library/Mobile Documents/com~apple~CloudDocs/foldername/appname/GoogleMobileAds.framework/GoogleMobileAds(GADSlot+AdEvents.o)' was built without bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. Note: This will be an error in the future.
甚至有的会报错误,无法通过编译:
ld: ‘/Users//Framework/SDKs/PolymerPay/Library/mobStat/libSDK.a(**ForSDK.o)’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
或:
ld: -undefined and -bitcode_bundle (Xcode setting
ENABLE_BITCODE
=YES) cannot be used together clang: error: linker command failed with exit code 1 (use -v to see invocation)
无论是警告还是错误,得到的信息是:我们引入的一个第三方库不包含bitcode , 如果我们的工程需要支持bitcode,则必要要求所有的引入的第三方库都支持bitcode。要么让第三方库支持,要么关闭target的bitcode选项
方法二:关闭Bitcode。
不过,我们现在需要考虑的是三个平台:iOS,Mac OS,watchOS。
对应iOS,bitcode是可选的。
对于watchOS,bitcode是必须的。
Mac OS不支持bitcode。
我们可以在”Build Settings”->”Enable Bitcode”选项中看到:
用 Xcode 7+ 新建一个 iOS 程序时, bitcode 选项默认是设置为YES的。现在需要改成NO。
如果我们开启了 bitcode ,在提交包时,也会有个 bitcode 选项:
如果所依赖的第三方库不支持bitcode,暂时只能设置ENABLE_BITCODE为NO。