学会使用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文件调用,表现为二进制文件
动态库:可以单独使用, 表现为可执行文件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

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