iOS私有库实现方案

iOS项目组件化架构方案中,需要把每个组件以独立工程的形式存储在远程仓库
Image text

远程私有库实现

创建远程索引库

1、在第三方代码托管网站coding创建私有的远程索引仓库,命名为PjPodspecs
2、使用终端命令生成ssh对称密码对

1
ssh-keygen

在/Users/xianrong/.ssh 路径可以查看到id_rsa和id_rsa.pub这两个文件,它们分别为私钥和公钥
3、使用公钥在coding网站上的(账户 –> SSH公钥)上进行设置。
4、把远程索引库拉取到本地,取名为“ProjectPodspecs”

1
pod repo add ProjectPodspecs git@git.coding.net:Captain-XR/PjPodspecs.git

可在/Users/xianrong/.cocoapods/repos/路径下查看到ProjectPodspecs,也可以使用终端命令pod repo查看

创建远程代码库,并提交代码

1、在第三方代码托管网站coding创建私有远程仓库,命名为PjBase
2、克隆pod模板库
在自定义的/Users/xianrong/Desktop/Component/路径下

1
pod lib create ProjectBase

3、把要上传的代码拷贝到ProjectBase/ProjectBase/Classes/路径下,并把ReplaceMe文件删除。
4、进入ProjectBase/Example/路径下进行安装

1
pod install

5、把本地代码提交到远程代码库PjBase
在/Users/xianrong/Desktop/Component/ProjectBase/路径下

1
2
git add .
git commit -m "初始化基础组件"

修改ProjectBase.podspec文件内容

1
2
3
4
5
6
7
s.summary = 'ProjectBase.'
s.description = <<-DESC
ProjectBase.包含了基本的配置,分类,宏文件,工具类等等
DESC
s.homepage = 'https://coding.net/u/Captain-XR/p/PjBase'
s.source = { :git => 'https://git.coding.net/Captain-XR/PjBase.git', :tag => s.version.to_s }
s.dependency 'AFNetworking' #依赖库

提交更改

1
2
git add .
git commit -m "配置spec文件"

对刚才修改的spec进行本地验证

1
pod lib lint

注意:如果创建的是swift项目,提示.swift-version报错,执行

1
echo "3.2" > .swift-version

添加远程仓库地址

1
2
3
4
git remote #查看有无origin
git remote -v #查看现有远程仓库的地址
git remote rm origin #移除
git remote add origin git@git.coding.net:Captain-XR/PjBase.git #添加远程仓库,url或ssh

提交代码到远程

1
git push origin master

小插曲:push提交失败使用了强制提交命令git push -u origin master -f
这样会使远程修改丢失,慎用!

本地打标签

1
2
git tag '0.1.0'
# git tag -d 0.1.0 #移除本地标签

远程打标签

1
2
git push --tags
# git push origin :0.1.0 #移除远程标签

远程验证

1
pod spec lint

本地spec提交到远程私有spec仓库

进入/Users/xianrong/Desktop/Component/ProjectBase/路径下

1
pod repo push ProjectPodspecs ProjectBase.podspec

这时本地.cocoapods子路径下和远程仓库PjPodspecs都能看到了ProjectBase.podspec了
这个提交过程其实是:把本地代码里的spec提交到本地私有spec库(即/Users/xianrong/.cocoapods/repos/ProjectPodspecs),它会自动将本地私有spec库提交到关联的远程spec库

把创建好的远程私有库引入宿主工程

查看源

1
pod repo

在Podfile文件里添加源,举例:

1
2
3
4
5
6
7
8
9
10
source 'https://github.com/CocoaPods/Specs.git'
source 'git@git.coding.net:Captain-XR/PjPodspecs.git'
platform :ios, '9.0'
use_frameworks!
target 'mainProj' do
pod 'ProjectBase'
pod 'MJExtension'
end

远程私有库升级版本

1、在ProjectBase/ProjectBase/Classes/路径下添加新代码
2、修改ProjectBase.podspec文件内容

1
s.version = '0.2.0'

3、进入ProjectBase/Example/路径下进行安装

1
pod install

4、把本地代码提交到远程代码库PrivateLib
在/Users/xianrong/Desktop/Component/ProjectBase/路径下

1
2
git add .
git commit -m "新增0.2.0版本,XXX功能"

1
2
3
5、对刚才修改的spec进行本地验证
``` bash
pod lib lint

6、提交代码到远程

1
git push origin master

本地打标签

1
git tag '0.1.0'

远程打标签

1
git push --tags

远程验证

1
pod spec lint

7、本地spec提交到远程私有spec仓库
进入/Users/xianrong/Desktop/Component/ProjectBase/路径下

1
pod repo push ProjectPodspecs ProjectBase.podspec

远程私有库划分子库

举例:把基础组件ProjectBase划分为Category、Network、Macro、Tool四个子库
1、修改ProjectBase.podspec文件内容
把source_files和dependency部分进行进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# s.source_files = 'ProjectBase/Classes/**/*'
# s.dependency 'AFNetworking', '~> 2.3'
s.subspec 'Category' do |a|
a.source_files = 'ProjectBase/Classes/Category/**/*'
end
s.subspec 'Network' do |b|
b.source_files = 'ProjectBase/Classes/Network/**/*'
b.dependency 'AFNetworking'
end
s.subspec 'Macro' do |c|
c.source_files = 'ProjectBase/Classes/Macro/**/*'
end
s.subspec 'Tool' do |d|
d.source_files = 'ProjectBase/Classes/Tool/**/*'
end
# 上面的a、b、c、d是自定义的别名

dependency部分可以根据具体情况进行设置,上面例子因为只有Network子库依赖用到AFNetworking,因此把依赖写进对应子库内部。
2、参照“远程私有库升级版本”步骤操作进行升级版本。
3、在引用项目Podfile文件里引用子库

1
2
pod 'ProjectBase/Category'
pod 'ProjectBase/Network'

或者

1
pod 'ProjectBase', :subspecs => ['Category','Network']

创建多个组件库

克隆pod模板库
在自定义的/Users/xianrong/Desktop/Component/路径下

1
pod lib create ProjectMain

在处理ProjectMain组件的Example(测试用例工程)时,注意点:
举例:ProjectMain组件依赖ProjectBase组件中的Category子库
1、在Example的Podfile文件里添加ProjectBase组件源和pod官方源

1
2
source 'https://github.com/CocoaPods/Specs.git'
source 'git@git.coding.net:Captain-XR/PjPodspecs.git'

2、修改ProjectMain.podspec文件内容

1
s.dependency 'ProjectBase/Category'

3、Example里如果涉及到加载bundle资源的问题
mainBundle是指测试项目的bundle,应该是调整为从组件的framework对应的bundle里找对应的资源

1
2
// NSBundle * mainBundle = [NSBundle mainBundle];
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];

4、组件内的资源图片放置在/…/ProjectMain/ProjectMain/Assets/路径下
打开ProjectMain.podspec文件里的图片引用路径

1
2
3
s.resource_bundles = {
'ProjectMain' => ['ProjectMain/Assets/*']
}

5、属于组件内部的xib中图片的路径需要调整为组件framework内部的资源文件路径ProjectMain.bundle/btn_imgName
6、属于组件内部的图片加载方式需要调整(不属于组件内部的图片则放在测试工程里可以使用imageNamed:的方式)

1
2
3
4
5
6
// UIImage * img = [UIImage imageNamed:@"tabbar_home"]; //这种方式加载不到图片,imageNamed:是从测试工程获取
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSString *bundleName = currentBundle.infoDictionary[@"CFBundleName"];
NSString * name = [NSString stringWithFormat:@"%@.bundle",bundleName];
NSString *imagePath = [currentBundle pathForResource:@"tabbar_home@2x.png" ofType:nil inDirectory:name];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

本地私有库实现

1、进入ProjectTest文件夹目录

1
2
3
4
git init
git add .
git commit -m "初始化本地私有库"
pod spec create ProjectTest

2、把代码文件添加到ProjectTest/Classes/路径下
3、修改.podspec文件内容:

1
2
3
s.description = "分类、工具类等"
s.license = "MIT"
s.source = { :git => "", :tag => "#{s.version}" }

4、在项目的Podfile文件中添加路径:

1
pod 'ProjectBase', :path =>'/Users/xianrong/Desktop/Component/ProjectTest'

注意:该路径为找得到.podspec的本地路径

1
pod install

附上.podspec文件内容含义:
s.name:名称,pod search 搜索的关键词
s.version:版本号
s.ios.deployment_target:支持的pod最低版本
s.summary: 简介
s.homepage:项目主页地址
s.license:许可证,例如s.license= { :type => “MIT”, :file => “LICENSE” }
s.author:作者
s.social_media_url:社交网址,这里我写的微博默认是Twitter,如果你写Twitter的话,你的podspec发布成功后会@你
s.source:项目的地址
s.source_files:需要包含的源文件,
s.resources: 资源文件
s.requires_arc: 是否支持ARC
s.dependency:依赖库,不能依赖未发布的库
s.dependency:依赖库,如有多个可以这样写s.dependency = ‘AFNetworking’

source_files:写法及含义

1
2
3
"Classes/*"
"Classes/**/*.{h,m}"
"Classes/**/*.h"

“ 表示匹配所有文件
.{h,m}” 表示匹配所有以.h和.m结尾的文件
“**” 表示匹配所有子目录

打赏支持一下呗!