CocoaPods 终于支持了
Swift,同时也发现Github团队的又一力作Carthage。它们都将包统一编译为Framework,但不同的是,
Carthage 仅支持 iOS 8 &
Xcode 6 Dynamic Framework
这一新特性。
Update 201504 CocoaPods 0.36 后也仅支持 Dynamic Framework
,放弃了之前的 Static Framework
形式。
那这个编译结果有什么区别?
Static Library & Dynamic Library
这两者属于标准的编译器知识,所以讲的会比较多。
简单的说,静态链接库是指模块被编译合并到应用中,应用程序本身比较大,但不再需要依赖第三方库。运行多个含有该库的应用时,就会有多个该库的Copy在内存中,冗余。
动态库可以分开发布,在运行时查找并载入到内存,如果有通用的库,可以共用,节省空间和内存。同时库也可以直接单独升级,或作为插件发布。
Library & Framework
在iOS中,Library 仅能包含编译后的代码,即 .a
文件。
但一般来说,一个完整的模块不仅有代码,还可能包含.h 头文修的
、.nib 视图文件
、图片资源文件
、说明文档
。(像 UMeng 提供的那些库,集成时,要把一堆的文件拖到Xcode中,配置起来真不是省心的事。)
Framework 作为 Cocoa/Cocoa Touch
中使用的一种资源打包方式,可以上述文件等集中打包在一起,方便开发者使用(就像Bundle),。
我们每天都要跟各种各样的Framework打交道。如Foundation.framework
/ UIKit.framework
等,这些都是Cocoa Touch开发框架本身提供的,而且这些 Framework 都是动态库。
但Apple对待第三方开发者使用动态库的态度却是极端的否定,所以在iOS 7之前如果使用动态库是肯定会被reject的,reason。但在2014年Xcode6和iOS 8发布时却开放了这个禁地,应该主要是为了App Extension
。
Framework 包含什么?
到底Framework中有什么,这里来看Alamofire编译后的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Alamofire.framework ├── Alamofire ├── Headers │ ├── Alamofire-Swift.h │ └── Alamofire.h ├── Info.plist ├── Modules │ ├── Alamofire.swiftmodule │ │ ├── arm.swiftdoc │ │ ├── arm.swiftmodule │ │ ├── arm64.swiftdoc │ │ ├── arm64.swiftmodule │ │ ├── i386.swiftdoc │ │ ├── i386.swiftmodule │ │ ├── x86_64.swiftdoc │ │ └── x86_64.swiftmodule │ └── module.modulemap └── _CodeSignature └── CodeResources
|
Framework 包括了二进制文件(可动态链接并且为每种处理器架构专属生成),这点和静态库并无区别,但不同的是,它包含其它资源:
- 头文件 - 也包含Swift symbols所生成的头文件,如
Alamofire-Swift.h
。 - 所有资源文件的签名 - Framework被嵌入应用前都会被重新签名。
- 资源文件 - 像图片等文件。
- Dynamic Frameworks and Libraries - 参见Umbrella Frameworks
- Clang Module Map 和 Swift modules - 对应处理器架构所编译出的Module文件
- Info.plist - 该文件中说明了作者,版本等信息。
Cocoa Touch Framework (实际内容为 Header + 动态链接库 + 资源文件)
Static Framework & Dynamic Framework
刚才也说明了Apple所创建的标准 Cocoa Touch Framework
里面包含的是动态链接库
。而Dynamic Framework
为 Xcode 6中引入的新特性,仅支持 iOS 8,因为Carthage使用的是该特性,所以仅支持iOS 8,说明上有提。
但新版CocoaPods中使用Framework是能够支持iOS 7的,这说明它不是Dynamic Framework。推断它仅是将Static Library封装入了Framework。还是静态库,伪Framework
。(v 0.36 正式版开始,仅提供 Dynamic Framework 的方式,不再支持 iOS7)。
关于Static Framework,见:
伪Framework
是指使用Xcode的Bundle来实现的。在使用时和Cocoa Touch Framework没有区别。但通过Framework,可以或者其中包含的资源文件(Image, Plist, Nib)。
Swift 与 Framework 的关系
在Xcode 6.0 Beta 4的 Release Notes 中,可以找到这句话:
1
| Xcode does not support building static libraries that include Swift code. (17181019)
|
在静态库中使用Swift语言开发,在build时会得到:
1 2 3
| error: /Applications/Xcode.app/Contents/Developer/Toolchains/ XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker
|
CocoaPods 将第三方都编译为Static Library。这导致Pod不支持Swift语言。所以新版Pod已将Static Library改为Framework。
Pods 0.36.0.beta.1
虽然已经支持Swift,但在编译时仍会给出下面警告:
1
| ld: warning: embedded dylibs/frameworks only run on iOS 8 or later
|
CocoaPods 0.36 rc 开始对Swift正式放弃旧的打包方式,使用Dynamic Framework,也就意味着不再支持 iOS 7。
Dynamic Framework
使用Dynamic 的优势:
- 模块化,相对于Static Library,Framework可以将模块中的函数代码外的资源文件打包在一起。
- 共享可执行文件 iOS 有沙箱机制,不能跨App间共享共态库,但Apple开放了App Extension,可以在App和Extension间共间动态库(这也许是Apple开放动态链接库的唯一原因了)。
iOS 8 Support only:
如果使用了动态链接库,在尝试编译到iOS 7设备上时,会出现在下错误:
1 2 3
| ld: warning: directory not found for option '-F/Volumes/Mactop BD/repos/SwiftWeather/Carthage.build/iOS' ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later (@rpath/Alamofire.framework/Alamofire) for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
|