(转)Cocoa包管理器之Carthage详解及CocoaPods中心化+Carthage的二进制化

323 阅读8分钟
原文链接: www.cnblogs.com

上篇博客详细的聊了CocoaPods 的相关内容,今天我们就来介绍另一个Cocoa的包管理器Carthage。在上家公司用Swift开发工程时,用的就是Carthage。Carthage诞生于14年11月份,是用Swift语言开发的,相对于CocoaPods来说是一个新生事物。本篇博客主要介绍一下Carthage的使用姿势,接下来几篇博客会介绍一下Carthage的源代码,看一下其工作原理。本篇博客我们会先介绍Carthage的按照和使用,然后再看一下Carthage额工作原理,然后再将自己的库关联到Carthage,最后来对比一下CocoaPods。

首先我们来看一下Carthage的官方介绍:Carthage的初衷是以最简单的方式来为你的Cocoa应用添加framework。Carthage将你依赖的三方库编译成二进制的framework,然后再提供给你使用。但是对你的工程结构有着完整的控制权。Carthage不会自动的修改你的工程文件或者编译设置。

Carthage is intended to be the simplest way to add frameworks to your Cocoa application.Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings.

 

 

一、Carthage的安装和使用

1、Carthage的安装

Carthage的安装是比较简单的,通过brew就可以直接安装,命令如下:

brew install carthage

  

 

 

2、Carthage的使用-carthage update

 Carthage中管理依赖的文件为Carfile,我们可以创建一个名为Cartfile的文件来容纳我们工程中所依赖的三方库。如下所示下方的Cartfile中依赖了一个AFNetWorking库和一个并没有支持Carthage的私有库。在Cartfile文件中,我们以github来直接指定该库在github上的域名path。添加完Cartfile文件后,接下来我们通过下方的命令进行安装即可。

carthage update

在执行上述命令时我们看到,对于“MyCocoaPodsTestProject”这个依赖仓库提示“该仓库没有被分享的framework schemes”, 稍后我们将会对“MyCocoaPodsTestProject”这个仓库添加shared framerwork schemes。

  

 

执行完carthage update命令后,会生成一个Cartfile.resoved的文件和一个Carthage的文件夹。这个.resolved的文件与CocoaPods中的lock文件功能一致,都是用来锁版本的。而这个Carthage文件夹下存放的就是Carthage为我们提供的动态库framework。 

  

 

3、工程中引入framework

接下来要做的就是把Carthage生成的相应依赖库的framework引入到我们的工程中。首先找到我们工程对应的Targets, 然后找到Build Phases下方的 ➕号下方的New Run Script Phase, 来添加引入framework的相关脚本。

  

 

下方是刚刚添加的Run Script,稍后会进行配置。

  

 

在Shell下方配置上carthage的命令路径以及相关的运行命令的参数,如下所示:

/usr/local/bin/carthage copy-frameworks

  

  

配置完相关的运行脚本后,在Link Binary With Libraries中添加或者拖入生成的三方库即可。 

  

 

  

 

 拖入完毕后,接下来我们就可以直接使用了。

  

 

 

二、自己的仓库关联Carthage

从上面Carthage update时提示的错误我们不难发现要想支持Carthage, 我们的git仓库中必须有一个可以生成framework的Project,并且该Project开启了Scheme的分享功能。接下来我们就让上述的 MyCocoaPodsTestProject工程支持Carthage的update。

 

1、创建 framework project

首先在我们工程所对应的github目录下方创建一个Cocoa Touche Framework的工程。如下所示:

  

 

2、引入源代码

然后在这个framework工程中引入相关的源文件。

  

 

在引入相关的源文件后,在Build Phasea中的Header中的Public中添加对外暴露的头文件,如下所示:

  

 在相关的.h文件中引入该framework所提供的相关头文件,此处类似pch文件的设置。

  

 

如果你创建的framework的Project的名字与你预期的不同,可以在Build Settings中的Product Name中进行设置,如下所示: 

  

 

2、shared schemes

接下来就该设置Scheme的Share了,首先打开Manager Schemes…如下所示:

  

  

 然后在Shared后方打钩即可。

  

 

3、framework的编译

使用终端进入到该工程目录中,使用carthage进行编译:

carthage build -no-skip-current

  

 

在我编译的时候遇到了上述的错误,不过Carthage的github主页给出了相关的解决方案,即使用xcodebuild进行编译,如下所示:

  

 使用上述命令编译 结果如下所示:

   

 

使用xcodebuild编译后,我们又使用carhage build --no-skip-current试了一次,可以正常编译

  

 

进行编译后,创建相关的tag然后push到远端即可。 

  

 

然后我们就可以在Carthage中正常使用我们的库了。

   

 

在引用相关库的时候需要添加上其库名,如下所示:

   

 

 

 

三、carthage编译

因为Carthage工程是Swift编写的,并且是使用Carthage进行的依赖管理。 我们可以从github上Clone相关的代码,然后执行carthage update进行依赖库的加载,如下所示:

  

 

加载完毕后,我们就可以正常编译运行了,下篇博客会介绍Chathage的相关源代码的设计结构。

  

 

 

 

四、Carthage VS CocoaPods

两者各有各的好处,也各有各的缺点,下方是Carthage的README中给出的与CocoaPods的不同之处。

  

下边是根据上面的英文自己翻译了一下:

CocoaPods是一个长期在Cocoa项目中使用的包管理工具,但为什么还要去创建一个Carthage呢?

 

首先,CocoaPods默认是会为你的工程自动创建和更新一个Xcode工作空间,并且还会创建和更新所有的依赖(备注:安装pod后会创建一个xxxxxx.xcworkspec的文件,通过该文件可以打开Xcode工作空间,该工作空间除了你自己的project外,在Pods中还会引入其依赖的三方库的源代码)。而Carthage与其不同,其会使用xcodebuild工具将依赖的库编译成二进制的framework, 但是整合这个framework的责任就落到了用户的身上。浸入式的CocoaPods使用起来会更为容易一些,而非浸入式的Carthage使用起来则更为灵活。

 

下方是CocoaPods的README中列举的目标之一:

  • 通过创建更集中的生态系统,提高第三方开源库的可发现性和参与度。

 

相比之下,Chathages是分散式依赖管理器。没有集中的依赖清单(就是内个CocoaPods中的SPEC仓库),这减少了维护工作,避免了任何中心故障点。然而,开源项目的发现变得更加困难,用户必须在github等开源网站上进行自行搜索。

 

CocoaPods的工程目录中必须有一个叫做podspec的这么一个文件,其中包含有关项目的元数据并指定了工程的的编译方式。Carthage使用了xcodebuild工具来构建依赖关系,而不是将这些依赖集成到单个工作区域中。它没有类似podspec这样的文件,但你的依赖项必须包括它们自己的XCODE项目,在这些项目中提供了依赖库的编译规则。

 

最终,我们创建了Carthage,因为我们想要最简单的工具——该依赖性管理器,它在不承担Xcode所做的工作的的情况下完成自己依赖管理的工作,并且不为框架作者创建额外的工作。虽然CocoaPods提供了许多令人惊喜的特性,但Carthage将永远不会有,因为这样会以增加工具的复杂度为代价。

 

 

五、CocoaPods结合Cathage进行二进制化。

不过我们可以将两者结合起来,比如一个浩大的工程中引入了成百上千个依赖库,如果都以源码的形式加载的话,编译成本难免会比较大。我们可以在CocoaPods中加载Carthage生成的framework, 来达到CocoaPods的二进制化的目的。

我们可以在CocoaPods的Podfile中添加相关的定义,具体如下所示。在else的语句块中就是加载Carthage编译的framework。

  

 

添加完相关Pod配置后,我们可以pod install看医生相关的库是否顺利的加载进来了。

  

 

下方就是我们pod install后相关的内容,可以看到依赖的仓库通过了framework的形式被引入到了我们的CocoaPods中,并且可以正常使用。

  

 

我们可以通过指定SOURCE条件来切换源码加载。

  

 

下方是切换源码加载后的工程文件,可以看出是与之前一致的:

  

 

今天的博客就先到这儿吧,以后有机会的话再一起看一下Carthage的源码。