学会使用cocoapods+workspace管理多个工程和组件化framework

本文主要内容

  • 使用workspace对多个项目进行管理
  • 工作空间中使用cocoapods管理不同项目的依赖
  • workspace共用自己写的framework

Let us rock and roll!

使用workspace对多个项目进行管理

首先创建一个新的工作空间

创建xcworkspace

命名为MYProjects

命名

我们获得了一个空的MYProjects.xcworkspace文件

MYProjects.xcworkspac

假设我们有两个工程 TestATestB

创建TestA

创建TestB

在我们目录下创建了两个工程文件和一个 MYProjects.xcworkspace 文件

目录一览

打开MYProjects.xcworkspace 如图所示将两个工程(选中TestA.xcodeprojTestB.xcodeproj导入)导入进来

导入工程

我们工作空间便同时存在了两个不同的工程

工作空间

以后我们只需要打开 MYProjects.xcworkspace 便可以管理我们的工作空间了

工作空间中使用cocoapods管理不同项目的依赖

我们需要在目录里面手动创建一个Podfile

# Uncomment the next line to define a global platform for your project
# platform :ios, '8.0'
#xcodeproj 'Portfolio/Portfolio.xcodeproj'
#source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

##设置workspace文件
workspace 'MYProjects.xcworkspace'

cd进入工作空间目录,执行pod install, 进行pod 初始化

pod install

重头戏来了,下面我们要为针对每个项目配置Podfile

在此之前,大多情况下,我们开发中可能会存在两个版本的App,例如 开发版正式版,如下图我们复制一个Target,并命名为TestADevTestBDev作为开发版本,

复制Targe

Xcode会为我们复制的Target自动生成了一个plist文件(一个target对应一个plist文件),名称为 TestA copy-Info.plist, 之后我们开发版target的属性便在这个文件中设置了

为了能够在代码中区分,我们只需要如下设置, TestBDev设置DEV=1, TestB设置DEV=0

区分开发版和正式版

在代码中我们只需要简单地判断下 DEV 便能够区分是开发版还是正式版本了

if (DEV == 1){
        // 测试开发环境
        requestURL = "127.0.0.1"
}else{
        // 正式开发环境
        requestURL = "213.23.43.12"
}

到现在为止,我们工作空间有了两个工程,两个工程分别对应了两个版本

工作空间 开发版本target 正式版本target
TestA TestADev TestA
TestB TestBDev TestB

我们要在Podfile中为每个target做配置
首先我们看下项目 TestA 如何配置

############################################# TestA
#需要添加添加依赖的target数组
targetsArray = ['TestA', 'TestADev'] 
# 遍历数组,分别添加依赖
for index in 0..targetsArray.length - 1 do
    # 数组中获取元素
    proj = targetsArray[index]
    target proj do
        # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
        use_frameworks!
        # 辨识是哪个项目
        project 'TestA/TestA.xcodeproj'
        # Pods for TestA
        # 键入需要添加的依赖
        pod 'AFNetworking', '~> 3.1.0'
        
        # end Pods for TestA
        # 如果 target 下标为1, 即只为开发板做 单元测试 和 UI测试
        if index == 0
            target proj + 'Tests' do
                inherit! :search_paths
                # Pods for testing
            end
            
            target proj + 'UITests' do
                inherit! :search_paths
                # Pods for testing
            end
        end
    end
end

TestB 配置也是一样的,最终我们得到的 Podfile 文件

# Uncomment the next line to define a global platform for your project
# platform :ios, '8.0'
#xcodeproj 'Portfolio/Portfolio.xcodeproj'
#source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'


##设置workspace文件
workspace 'MYProjects.xcworkspace'


############################################# TestA
targetsArray = ['TestA', 'TestADev']
for index in 0..targetsArray.length - 1 do
    proj = targetsArray[index]
    target proj do
        # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
        use_frameworks!
        project 'TestA/TestA.xcodeproj'
        # Pods for TestA
        pod 'AFNetworking', '~> 3.1.0'
        
        # end Pods for TestA
        # 如果 target 下标为0, 即只为正式版做 单元测试 和 UI测试
        if index == 0
            target proj + 'Tests' do
                inherit! :search_paths
                # Pods for testing
            end
            
            target proj + 'UITests' do
                inherit! :search_paths
                # Pods for testing
            end
        end
    end
end

############################################# TestB
targetsArray = ['TestB', 'TestBDev']
for index in 0..targetsArray.length - 1 do
    proj = targetsArray[index]
    target proj do
        # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
        use_frameworks!
        project 'TestB/TestB.xcodeproj'
        # Pods for TestA
        pod 'AFNetworking', '~> 3.1.0'
        
        # end Pods for TestA
        # 如果 target 下标为0, 即只为正式版做 单元测试 和 UI测试
        if index == 0
            target proj + 'Tests' do
                inherit! :search_paths
                # Pods for testing
            end
            
            target proj + 'UITests' do
                inherit! :search_paths
                # Pods for testing
            end
        end
    end
end

但是这样做会有个缺陷,不同工程使用同一个不同版本的三方库将会报错,因为这样会导致podfile中的版本冲突,如下所示

Analyzing dependencies
[!] Unable to satisfy the following requirements:

- `AFNetworking (~> 3.1.0)` required by `Podfile`
- `AFNetworking (~> 3.1.0)` required by `Podfile`
- `AFNetworking (= 2.6.3)` required by `Podfile`
- `AFNetworking (= 2.6.3)` required by `Podfile`

最后我们要做的就是pod install下即可了

workspace共用自己写的framework

如法炮制,我们创建一个framework,命名为 MADFramework

创建framework

build一下,加入工作空间,现在我们有四个蓝色的图标了


工作空间

值得注意的是,我们添加的framework默认是动态库,苹果是不允许上架的 (更正下,现在是允许上架的),我们需要如下图进行更改,将framework设置为静态库

更改为静态库

接着在framework中新建一个类MADAlert.h

#import "MADAlert.h"
#import <UIKit/UIKit.h>

@implementation MADAlert

+ (void)alert
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello ☺☺☺☺☺☺☺☺" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"done", nil];
    [alert show];
}
@end

如下如将需要暴露的header放入public

暴露header

为了我们其他的工程能识别我们的framework,做如下图设置

链接库

设置

ViewController代码中添加调用代码

#import "MADAlert.h"
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [MADAlert alert];
}

运行下:


运行

That all


补充 静态动态库区别:

静态库:链接阶段导入,完整地被复制到可执行文件,使用了多少次,就会被拷贝多少次
动态库:运行时动态加载,多个程序共用, 例如系统的UIKit.framwork等,能够节省内存,减少应用包体积

静态库:以.a.framework为文件后缀名。
动态库:以.tbd(之前叫.dylib).framework为文件后缀名。

静态库:不可以单独使用,需要依赖.h文件调用,表现为二进制文件
动态库:可以单独使用, 表现为可执行文件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一. CocoaPods的介绍 什么是CocoaPods?CocoaPods是一个负责管理iOS项目中第三方开源库...
    辉712阅读 3,973评论 0 7
  • 项目组件化、平台化是技术公司的共同目标,越来越多的技术公司推崇使用pod管理第三方库以及私有组件,一方面使项目架构...
    swu_luo阅读 22,161评论 0 39
  • CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具。利用 CocoaPods,...
    宝山潇洒哥阅读 4,080评论 0 1
  • 最幸福的就是我了 最近我喜欢上了塑身瑜伽 孩子睡着了我就跟电视上的瑜伽老师学 老师一步一步教的好详细 练了一会觉得...
    幸福魔法师阅读 159评论 0 0
  • 暑假因为各方面的原因,没能带娃出行,心里总觉得有个遗憾。为了弥补遗憾,想利用国庆长假前的某个周末,全家来个亲子自驾...
    俞小鱼A朵朵阅读 486评论 0 0