我有一个现有的iOS应用程序,想要添加大量我作为另一个项目开发的代码,只是为了便于测试。新的块基本上是将图像保存到各种共享服务等。由于该共享代码需要进行大量测试和将来的更新,我想知道将这种代码块合并到现有应用程序中的最佳方法是什么。
我不知道它应该是静态库,动态库还是框架,老实说,我不太确定有什么区别,或者我应该如何处理并在Xcode中进行设置。
我所知道的是,我需要/想要为共享代码保留一个单独的测试和更新应用程序,并让主应用程序使用它。
我有一个现有的iOS应用程序,想要添加大量我作为另一个项目开发的代码,只是为了便于测试。新的块基本上是将图像保存到各种共享服务等。由于该共享代码需要进行大量测试和将来的更新,我想知道将这种代码块合并到现有应用程序中的最佳方法是什么。
我不知道它应该是静态库,动态库还是框架,老实说,我不太确定有什么区别,或者我应该如何处理并在Xcode中进行设置。
我所知道的是,我需要/想要为共享代码保留一个单独的测试和更新应用程序,并让主应用程序使用它。
Answers:
首先,一些一般定义(特定于iOS):
静态库 -编译时链接的代码单位,不会更改。
然而,iOS的静态库没有允许包含图像/资产(唯一的代码)。您可以通过使用媒体捆绑包来解决这一挑战。
一个更好的,更正式的定义可以在维基百科上找到这里。
动态库 -运行时链接的可能会更改的代码和/或资产的单位。
但是,仅允许Apple为iOS创建动态库。您无权创建这些文件,因为这会使您的应用程序被拒绝。(请参阅此确认和推理上的其他SO后)。
软件框架 -完成任务的一组编译代码...因此,您实际上可以拥有一个静态框架或一个动态框架,它们通常只是上述内容的编译版本。
因此,在iOS上,您唯一的选择基本上是使用静态库或静态框架(主要区别在于,静态框架.a
最常以编译文件的形式分发,而静态库可能只是作为子项目提供的,您可以看到所有代码-首先进行编译,其结果.a
文件用作项目的依赖项)。
既然我们对这些术语已经很清楚了,那么为iOS设置静态库和支持媒体包并不太困难,并且有很多关于如何执行此操作的教程。我个人会推荐这个:
https://github.com/jverkoey/iOS-Framework
这是一个非常简单明了的指南,没有处理“伪静态库”的缺点...请查看更多信息...
一旦创建了静态库,就可以像将它作为子模块包含在Git中一样轻松地用于不同的项目。
祝好运。
编辑
据我所知,关于项目中的子项目,要使其正常工作/编译,您必须从根本上建立一个编译链,在该编译链中首先编译子项目,这将创建一个.a
用作依赖项的静态框架文件。由项目。
这是另一个讨论此问题的有用教程:
http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/
编辑2
从iOS 8开始,Apple现在允许开发人员创建动态框架!(注意:您的应用必须具有iOS 8的最低目标才能包含动态框架...不允许反向移植。)
这已添加为新项目模板。在Xcode 6.1中,可以在以下位置找到它:
New Project -> iOS -> Framework & Library -> Cocoa Touch Framework
Mach-O文件格式(Mach对象- .o
)
在iOS世界中,每个源文件都转换为目标文件-ABI [关于] Mach-O文件[关于],该文件将打包到最终的可执行文件包(例如应用程序,框架...),文件(例如库...)中。它的行为由[关于]决定Mach-O type
Package
是一个本身表现为文件-的目录opaque file
。创建该文件是为了使用户体验变得复杂,从而可能对内部结构进行一些更改,从而导致程序行为无法预测。软件包用于Document Package
或与一起使用Bundle
。您可以Show Package Contents
在Finder中使用
Bundle
是具有特定结构的目录,用于组织二进制文件(可执行代码)和该代码的资源(例如图像,笔尖...)。捆绑包包含Info.plist
[关于]文件。捆绑软件是为开发人员的体验而创建的。也可以包装。捆绑包有几种类型:
application bundle
-- Application target
framework bundle
并versioned bundle
作为子类型-Framework Target
loadable bundle
(aka plug-in bundle
)- Bundle target
(UI测试包,单元测试包)dSYM
[关于]包)Application
- .ipa
,.app
[关于] - packaged
application bundle
-可发射程序。
Tests
- packaged
loadable bundle
用于测试二进制文件。插件体系结构允许我们确实将新功能(测试用例)作为单独的模块添加到现有二进制文件中
库和框架
Martin Fowler在InversionOfControl上
库本质上是您可以调用的一组函数,这些天通常组织成类。每个调用都会执行一些工作,并将控制权返回给客户端。
框架体现了一些抽象设计,并内置了更多的行为。要使用它,您需要通过子类化或插入自己的类将行为插入框架中的不同位置。然后,框架的代码在这些位置调用您的代码。程序的主控件被反转,从您移至框架。(控制反转)
iOS上的库和框架
Library
是为一个或多个体系结构编译的Mach-O目标文件的集合(检查静态还是动态)。
Static library
- .a
(又名静态档案库,静态链接的共享库[doc])- 在编译期间将其添加到应用程序时,静态链接器将合并库中的对象文件,并将它们与应用程序对象文件一起打包到一个可执行文件中文件。缺点是输出文件很大
从Xcode 9.0开始,支持静态Swift库。
Dynamic library
- .dylib
(又名动态共享库,共享库,动态链接库[doc])在加载或运行时与应用程序的可执行文件动态链接,但未复制到其中。在实践中,应用程序的软件包将包含带有文件的Frameworks文件夹。所有iOS和macOS 系统库均为。缺点是启动时间很慢,因为应该复制和链接所有动态库。.dylib
dynamic
Text-based stub library
- .tbd
[关于],它dynamic library
是位于目标设备上的文本存根。因此,您不应将动态库打包到包中。它具有尺寸效果。
Framework
- .framework
是not packaged
framework bundle
-使开发人员可以轻松查看标头和资源,并且包含static or dynamic
库,标头文件和资源。
Static framework
包含static library
打包的资源。
Dynamic framework
包含dynamic library
和资源。除此之外,动态框架还可以在一个包(versioned bundle
)中包含同一动态库的不同版本。
Embedded framework
是一种dynamic framework
生活在应用程序的沙箱。首先创建此类型是为了扩展以共享公共代码和资源。当“部署目标”为iOS 8+时可用。
Umbrella framework
[总体目标]是一个包含其他框架的框架。它在iOS上不受官方支持,因此不建议开发人员创建它们 [Official doc]。实际上,它是一组子框架(或嵌套框架)。当您创建具有依赖项的框架时,使用者(例如应用程序)负责将此依赖项与您的框架一起添加到项目中。作为开发人员,很自然地尝试找到一种方法来将这种责任从消费者转移到您的责任上。结果,您认为这Umbrella framework
是一种解决方法,但通常会导致版本管理以及创建和支持它的复杂性方面的严重问题。
Fake Framework
-是根据进行特定操作的结果,static library
以创建具有.framework
扩展名的捆绑包,该捆绑包将表现为dynamic framework
。由于Xcode由于没有框架模板而不支持创建框架时,才使用此技术。一种假框架的实现。苹果使用Xcode 6添加了iOS框架支持。
Modular Framework
[关于] -@import
这是一个.modulemap
内部包含文件的框架。模块可以包含子模块。主要优点是可以节省构建时间Modular Framework
。
Universal Library or Framework
(又称脂肪)[lipo] [聚集目标]包含多种架构。例如,您的发行版本应支持一些拱门,您可以通过[ONLY_ACTIVE_ARCH]进行调节Build Active Architecture Only
Dependency
[关于]您可以将第三方代码用作目标的一部分。它允许您重用来自许多来源的代码,例如-另一个项目,同一工作空间中的项目,另一个目标,库,框架等。
如何构建和使用静态库:
如何构建和使用动态框架[更改为静态]
您也可以为CocoaPods创建.podspec文件(http://guides.cocoapods.org/making/private-cocoapods.html#1.-create-a-private-spec-repo),并将其与唯一的区别是它是您的私有Pod,并且外界看不到(我不确定如果您的Pod应该创建CoreData模型会发生什么,但据我所知并非如此)。