我有一个现有的iOS应用程序,想添加一大块代码,我一直在开发的另一个项目,只是为了便于测试。新的块主要处理将图像保存到各种共享服务等。因为共享代码需要大量的测试和未来的更新,所以我想知道将这些代码块整合到现有应用程序中的最佳方法是什么。
我不知道它应该是静态库,动态库还是框架,老实说,我不确定有什么区别,或者我应该如何着手,在Xcode中设置它。
我所知道的是,我需要/想要保持一个单独的测试和更新应用程序的共享代码,并让主应用程序使用它。
我有一个现有的iOS应用程序,想添加一大块代码,我一直在开发的另一个项目,只是为了便于测试。新的块主要处理将图像保存到各种共享服务等。因为共享代码需要大量的测试和未来的更新,所以我想知道将这些代码块整合到现有应用程序中的最佳方法是什么。
我不知道它应该是静态库,动态库还是框架,老实说,我不确定有什么区别,或者我应该如何着手,在Xcode中设置它。
我所知道的是,我需要/想要保持一个单独的测试和更新应用程序的共享代码,并让主应用程序使用它。
首先,一些通用定义(针对iOS):
静态库-在编译时链接的代码单元,它不会改变。
然而,iOS静态库不允许包含图像/资产(只允许代码)。不过,你可以通过使用媒体包来解决这个问题。
一个更好、更正式的定义可以在维基百科上找到。
动态库——在运行时链接的代码和/或资产的单元,这些代码和/或资产可能会发生变化。
然而,只有Apple被允许为iOS创建动态库。你不允许创建这些,因为这会让你的应用程序被拒绝。(请参阅其他SO帖子来确认和推理)。
软件框架-一组完成任务的编译代码…因此,您实际上可以拥有一个静态框架或一个动态框架,它们通常只是上述框架的编译版本。
有关更多细节,请参阅软件框架Wiki。
因此,在iOS上,你唯一的选择基本上是使用静态库或静态框架(主要的区别是静态框架通常是作为编译后的.a文件分发的,而静态库可能只是作为子项目包含的——你可以看到所有的代码——它首先被编译,其生成的.a文件被项目用作依赖项)。
现在我们已经清楚了这些术语,为iOS设置一个静态库并支持媒体包并不太难,并且有很多教程教你如何做到这一点。我个人推荐这个:
https://github.com/jverkoey/iOS-Framework
这是一个非常直接的指南,并且没有处理“伪静态库”的缺点……查看更多信息…
一旦创建了静态库,就可以将其作为子模块包含在Git中,以便在不同的项目中使用。
祝你好运。
EDIT
关于项目中的子项目,据我所知,要让它正确地工作/编译,你本质上必须建立一个编译链,首先编译子项目,这将创建一个静态框架.a文件,该文件被项目用作依赖项。
下面是另一个关于这个问题的有用教程:
http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/
编辑2
从iOS 8开始,苹果现在允许开发者创建动态框架!(注意:你的应用必须有iOS 8的最低目标,以包括一个动态框架…不允许反向移植。)
这已被添加为一个新的项目模板。在Xcode 6.1中,可以在以下位置找到:
New Project -> iOS -> Framework & Library -> Cocoa Touch Framework
你也可以为CocoaPods创建.podspec文件(http://guides.cocoapods.org/making/private-cocoapods.html#1.-create-a-private-spec-repo),并像使用任何其他pod一样使用它,唯一的区别是它是你的私人pod,外部世界不可见(我不确定如果你的pod应该创建CoreData模型会发生什么,但据我所知,情况并非如此)。
Mach- o文件格式(Mach Object - .o)
在iOS世界中,每个源文件都转换为目标文件- ABI[About] Mach-O文件[About],它将被打包成最终可执行的包(应用程序,框架),文件(库),其行为由Mach-O类型[About]决定
包是一个目录,它的行为本身作为一个文件不透明的文件。它是为了用户体验而创建的,以便对内部结构进行一些复杂的更改,从而导致不可预测的程序行为。包在文档包中使用,或与包一起使用。您可以在查找器中使用显示包内容
Bundle是一个具有特定结构的目录,用于组织二进制(可执行代码)和该代码的资源(例如。图像、上司……资产。汽车文件[对])。 Bundle包含Info。plist文件(有关)。Bundle是为开发人员体验而创建的。也可以包装。有几种类型的捆绑包:
应用程序包-应用程序目标 框架包和版本化的包作为子类型-框架目标 可加载包(又名插件包)- '…Bundle' (UI测试包,单元测试包)-可以在运行时加载。. Bundle扩展Mac OS XPC服务-跨进程通信是一种进程间通信(Inter Process Communication, IPC)。它可以作为不同进程的模块使用(由launchd根进程管理)[关于] 其他(dSYM[对]包)
应用程序- .ipa, .app[关于]-打包应用程序包-可启动程序。
应用程序扩展[关于]-来自iOS v8 -扩展应用程序的功能,当用户与其他应用程序交互时可用。应用程序扩展作为一个包是包含应用程序的一部分,但它是在自己的沙箱上运行(处理器,内存…),试图使用应用程序扩展的应用程序被称为主机应用程序。
行动 分享 照片编辑 今天又名小部件 ...
共享公共代码和资源。当部署目标是iOS 8+时可用。
测试-打包的可加载包,用于测试二进制文件。插件体系结构允许我们将新功能(测试用例)作为单独的模块添加到现有的二进制文件中
库和框架
[库vs框架]
Martin Fowler谈InversionOfControl
A Library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client. A Framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework's code then calls your code at these points. The main control of the program is inverted, moved away from you to the framework. This phenomenon is Inversion of Control (also known as the Hollywood Principle - "Don't call us, we'll call you"
iOS上的库和框架
它们可以帮助您解决:模块化、重用、封装、改进构建时间
库是为一个或多个架构编译的Mach-O对象文件的集合[检查静态或动态]。
静态库- .a(又名静态归档库,静态链接共享库[doc]) -当你将它添加到应用程序中时,在编译期间静态链接器将合并库中的目标文件,并将它们与应用程序的目标文件打包成一个可执行文件。缺点是输出文件很大
从Xcode 9.0开始支持Swift静态库。
动态库- .dylib(又名动态共享库,共享对象,动态链接库[doc])在加载或运行时与应用程序的可执行文件动态链接,但不复制到其中。在实践应用程序的包将包含框架文件夹。dylib文件。所有iOS和macOS系统库都是动态的。缺点是启动时间较慢,因为应该复制和链接所有动态库。
[iOS静态库vs动态库] [静态与动态链接]
基于文本的存根库- .tbd[About],它是动态库的文本存根,位于目标设备上。因此,您不应该将动态库打包到您的包中。它有一个大小效应。
框架又名二进制框架- . Framework是一个未打包的框架包(允许开发人员轻松查看头文件和资源),其中包含编译过的静态或动态库、头文件和资源。
静态框架包含一个用其资源打包的静态库。
动态框架又名嵌入式框架-来自iOS v8 -包含动态库和资源。除此之外,动态框架可以在一个捆绑包(版本化捆绑包)中包含同一个动态库的不同版本。应用扩展采用嵌入式框架
[静态框架vs动态框架]
Umbrella framework [Aggregate target] is a framework that contains other frameworks. It is not officially supported on iOS and that is why it is not recommended for developers to create them[Official doc]. In actuality it's a set of sub-frameworks(or Nested Frameworks). When you create a framework which has a dependency, a consumer (such as an app) is responsible for adding this dependency along with your framework into the project. As a developer, it's natural to try to find a way to transfer this duty from consumer to your's. As a result you think that Umbrella framework is the rescue but usually it leads to a serious issues with managing versions and complexity of creating and supporting it.
Fake Framework -是在静态库下创建带有. Framework扩展名的捆绑包的特定操作的结果,它将表现为一个动态框架。当Xcode因为没有框架模板而不支持创建框架时,就会使用这种技术。一个虚假框架的实现。在Xcode 6中,苹果增加了iOS框架支持。
模块框架[关于]- @import它是一个框架,其中包含一个.modulemap文件。模块可以包含子模块。使用模块化框架的主要优点是节省了构建时间。
通用库或框架(又名Fat) [lipo][聚合目标]包含多个架构。例如,你的发布版本应该支持某个arch,你可以通过build Active Architecture Only来调节它
XCFramework是由Xcode 11引入的,它是一个包含多个架构(arm, x86_64…)和平台(iOS, MacOS…)的包。它应该取代通用框架
依赖关系[关于]您可以使用第三方代码作为目标的一部分。它允许您重用来自许多来源的代码,如另一个项目,同一工作区中的项目,另一个目标,库,框架等。
如何构建和使用静态库:
[Swift消费者-> Swift静态库] [Swift消费者-> Objective-C静态库] [Objective-C consumer -> Swift静态库] [Objective-C consumer -> Objective-C静态库]
如何构建和使用动态框架[变为静态]
[Swift消费者-> Swift动态框架] [Swift消费者-> Objective-C动态框架] [Objective-C consumer -> Swift动态框架] [Objective-C consumer -> Objective-C动态框架]
[Xcode构建系统] (Xcode组件) (动态链接器)