项目模块化, 模块之间的依赖方式首选cocoapods, 通过pod直接导入模块方便快捷, cocoapods仓库存放在Git上, Git现在又可以免费创建私有仓库, 爽不爽...
本篇文章主要介绍cocoapods创建私有仓库的方式.
名词介绍:
podspec
: podspec文件是私有库的配置索引文件, 每一个库都对应一个podspec文件, 可以去Git上查看AFNetworking Masonry等的podspec, 每次更新发布版本都需要编辑此文件, 此文件主要包括库的描述、版本、需要暴露的文件等等...repo
: 是存放podspec文件的Git仓库,当你使用了cocoapods后会被clone到本地~/.cocoapods/repos目录下,文件中的master就是官方的repo. 把podspec提交到自己repo仓库上就是私有库, 提交到官方的repo上就是公开的, 别人就可以搜到使用。
创建私有库共分一下几步,以创建自己创建的LBMusicPlayer私有库为例, 分的步骤较细.
第一步
先在自己的Git创建两个仓库:
- 存放podspec文件的repo仓库,比如叫XYRepo,以后不管创建多少私有库,都可以把podspec文件提交到这里。
- 存放自己私有库的仓库,比如叫LBMusicPlayer。
第二步
创建Repo, 创建后在~/.cocoapods/repos目录下可以看到XYRepo文件
# pod repo add [Private Repo Name] [第一步创建的repo仓库地址]
$ pod repo add XYRepo https://github.com/huangxianyu/XYRepo.git
第三步
创建一个项目, 以私有库的名字命名,比如叫LBMusicPlayer,用于测试代码,在项目目录下创建文件夹, 一般命名为Classes, 存放私有库代码。
第四步
在项目目录下创建.podspec文件, 名字和项目名一致.
$ pod spec create LBMusicPlayer
第五步
修改你的podspec文件, 删除没用的注释和命令,这里列举部分常用的属性,详情看Demo。
Pod::Spec.new do |s|
[s.name](http://s.name/) = "LBMusicPlayer" #名称
s.version = "0.0.1" #版本号
s.summary = "LBMusicPlayer" #简短介绍,下面是详细介绍
s.description = <<-DESC #详细介绍
LBMusicPlayer
DESC
s.homepage = "[https://github.com/huangxianyu/LBMusicPlayer](https://github.com/huangxianyu/LBMusicPlayer)"#主页,这里要填写可以访问到的地址,不然验证不通过
# s.screenshots = "[www.example.com/screenshots_1](http://www.example.com/screenshots_1)", "[www.example.com/screenshots_2](http://www.example.com/screenshots_2)" #截图
s.license = 'MIT' #开源协议
s.author = { "huangxianyu"=> "[[email protected]](mailto:[email protected])"} #作者信息
s.source = { :git => "[https://github.com/huangxianyu/LBMusicPlayer.git](https://github.com/huangxianyu/LBMusicPlayer.git)", :tag => "#{s.version}"} #项目地址,这里不支持ssh的地址,验证不通过,只支持HTTP和HTTPS,最好使用HTTPS
# s.social_media_url = '[https://twitter.com/](https://twitter.com/)' #多媒体介绍地址
s.platform = :ios, '9.0' #支持的平台及版本
s.requires_arc = true #是否使用ARC,如果指定具体文件,则具体的问题使用ARC
s.source_files = "Classes", "Classes/**/*.{h,m}" #代码源文件地址,表示Classes目录及其子目录下所有文件,如果有多个目录下则用逗号分开,如果需要在项目中分组显示,这里也要做相应的设置
s.resource_bundles = {
'LBMusicPlayer'=> ['LBMusicPlayer/Assets/*.png']
} #资源文件地址
s.public_header_files = '../Classes/**/*.h' #公开头文件地址
s.frameworks = 'UIKit' #所需的framework,多个用逗号隔开
s.dependency 'AFNetworking', '~> 2.3' #依赖关系,该项目所依赖的其他库,如果有多个需要填写多个s.dependency
end
第五步
可以先本地测试修改代码。
私有库的代码,在pod install后,在Development Pods文件夹下, 可以直接修改代码运行测试, 不用每次修改完代码都pod install, 直接运行就可以
podfile内添加一下代码, 参考第9步
pod 'LBMusicPlayer', :path => '../LBMusicPlayer’
然后执行命令
$ pod install
第六步
测试无误后, 推送本地代码到git, 并打tag推送到git,podspec文件的s.version一定要和tag一致。
$ git add .
$ git commit -m "描述"
$ git remote add origin https://github.com/huangxianyu/LBMusicPlayer.git #添加远端仓库, 第一步创建的
$ git push -u origin master #提交到远端仓库
$ git tag -m "first release" 0.0.1 #版本号需要和.podspec文件的s.version一致
$ git push —tags
第七步
验证仓库配置是否正确, 验证之前一定要把所有修改代码push到git, 一般会加上这个命令 --allow-warnings:允许警告
#验证书写格式 --verbose:详细信息 --use-libraries:使用了静态库 --allow-warnings:允许警告
$ pod spec lint LBMusicPlayer.podspec --allow-warnings
#验证库编译
$ pod lib lint --allow-warnings
第八步
验证通过后,将.podspec文件推送到第一步创建的Repo上
$ pod repo push XYRepo LBMusicPlayer.podspec --allow-warnings
第九步
到此已经成功配置好私有仓库
# 更新repo
$ pod repo update XYRepo
$ pod serach LBMusicPlayer
# 如果搜索不到执行命令
$ rm ~/Library/Caches/CocoaPods/search_index.json
第十步
使用私有库
在.podfile文件内添加一下内容, 后 pod install
导入头文件: #import
source '[https://github.com/huangxianyu/XYRepo.git](https://github.com/huangxianyu/XYRepo.git)'# 自己的repo存放位置
source '[https://github.com/CocoaPods/Specs.git](https://github.com/CocoaPods/Specs.git)' # 官方的repo
platform :ios, '9.0'
use_frameworks!
target 'LBMusicPlayer'do
# 本地依赖
#pod 'LBMusicPlayer', :path => '../LBMusicPlayer'#指定路径
#pod 'LBMusicPlayer', :podspec => '../LBMusicPlayer.podspec' #指定podspec文件
# 远程仓库依赖
pod 'LBMusicPlayer'
end
第十一步
更新版本
再从第五步开始就可以,一定不要忘了打tag。
到此结束
注意: 如果本地调试成功,但推送到私有仓库失败时,请执行以下步骤:
1.which pod: 输出 cocoapods 在本地路径.
2.进入到 ruby 的文件夹,找到 gems/cocoapods-(版本号)/lib/cocoapods/validator.rb 文件.
3.以 sudo 用户权限打开该文件.
4.找到 validate 函数做如下修改就可以了:
def validate
@results = []
# 修改的地方
return true
# Replace default spec with a subspec if asked for
a_spec = spec
if spec && @only_subspec
subspec_name = @only_subspec.start_with?(spec.root.name) ? @only_subspec : "#{spec.root.name}/#{@only_subspec}"
a_spec = spec.subspec_by_name(subspec_name, true, true)
@subspec_name = a_spec.name
end
UI.print " -> #{a_spec ? a_spec.name : file.basename}\r" unless config.silent?
$stdout.flush
perform_linting
perform_extensive_analysis(a_spec) if a_spec && !quick
UI.puts ' -> '.send(result_color) << (a_spec ? a_spec.to_s : file.basename.to_s)
print_results
validated?
end
有关podspec文件的属性
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
version = package["version"]
source = { :git => "https://github.com/facebook/react-native.git" }
if version == "1000.0.0"
# This is an unpublished version, use the latest commit hash of the react-native
repo, which we’re presumably in.
source[:commit] = `git rev-parse HEAD`.strip
else
source[:tag] = "v#{version}"
end
folly_compiler_flags = "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"
Pod::Spec.new do |s|
s.name = "LBMusicPlayer" # 必须和⽂文件名保持⼀一致
s.version = "0.0.1" #版本号
s.summary = "LLBPayManager" # 简单描述
s.description = <<-DESC # 详细描述
LLBPayManager
DESC
s.homepage = "https://github.com/huangxianyu/LBMusicPlayer" #主页
s.license = "MIT" #许可协议
s.author = { "huangxianyu" => "[email protected]" }
s.platform = :ios, "9.0"
s.ios.deployment_target = '8.0' # 与platform 中的版本号相同
s.source = { :git => "https://github.com/huangxianyu/LBMusicPlayer.git", :tag => "#{s.version}" } # # 源⽂文件存放地址 git, http, svn ,⽀支持 tag, commit, sha1 算法匹配
s.documentation_url =
"http://gitlab.langlib.io/clientlib_ios/LLBPayManager.git/LLBPayManager/docs/index.html" # 文档
s.requires_arc = true # 是否是 ARC
# s.requires_arc = "Classes/Arc" # arc 的⽂文件
# s.requires_arc = ["Classes/Arc","Classes/Arc.mm"] # arc ⽂文件数组
s.default_subspec = "Default" # 默认⼦子模块
s.default_subspecs = "Default" # 默认⼦子模块
s.static_framework = true # 是否使⽤用静态 framework
s.swift_version = "4.2" # swift 版本号
s.cocoapods_version = ">= 1.5.3" # cocoapods 版本号
s.social_media_url = "https://twitter.com/cocoapods" # 视频
s.screenshot = "http://dl.dropbox.com/u/378729/MBProgressHUD/1.png" # 截图
# s.screenshots = [ "http://dl.dropbox.com/u/378729/MBProgressHUD/1.png"] # 截图 s.prepare_command = "ruby build_files.rb" # 安装该库之前执⾏行行的脚本
s.deprecated = false # 是否已经废弃
s.ios.framework = "CFNetwork" # 依赖系统 framework ,可以指定平台
# s.frameworks = "CoreData" # 依赖系统framework,全部平台
s.weak_framework = "UserNotifications" # 弱链接,⽐比如说⼀一个项⽬目同时兼容iOS6和iOS7,但某⼀一个
framework只在iOS7上有,这时候如果⽤用强链接,那么在iOS7上运⾏行行就会crash,使⽤用weak_frameworks可以避免 这种情况。
# s.weak_frameworks = ["UserNotifications", "SafariServices"] s.ios.vendored_frameworks = "A.framework" # ⾃自定义framework 只针对iOS平台
# s.vendored_frameworks = "A.framework", "B.framework" # ⾃自定义framework ,全部平台
s.ios.library = "xml2" # 系统静态库,可以指定平台
# s.libraries = "xml2", 'z' # 系统静态库数组,全部平台
s.ios.vendored_library = "libTest.a" # ⾃自定义静态库 只针对iOS平台
# s.vendored_libraries = "libTest1.a", "libTest2.a" # 自定义静态库,全部
s.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format' # 编译参数,在BuildSetting 中可设置
s.xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' } # 针对整个项⽬目
s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' } # pod 的 target 项⽬目配置
s.user_target_xcconfig = { 'MY_SUBSPEC' => 'YES' } # 主⼯工程的 target 配置
s.prefix_header_contents = "#import ", "#import" # pch ⽂文件内容
s.prefix_header_file = 'iphone/include/prefix.pch' # pch ⽂文件
s.module_name = 'Demo' # swift 模块名
s.header_dir = 'Header' # 头⽂文件存放位置,主要⽬的是为项⽬目中引⽤用头⽂文件时使⽤用 <> 找不不到报错,React 中就有用到
s.header_mappings_dir = 'src/include' # 头⽂文件⽂文件夹目录结构
s.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' } # 编译时执行的脚本
# s.script_phases = [ { :name => 'Hello World', :script => 'echo "Hello World"' } ]
s.source_files = "Classes/**/*.{h,m}" # 源⽂文件路路径,是只相对 podspec ⽂文件所在⽂文件夹的路路径,匹配正则
s.public_header_files = "Headers/Plublic/*.h" # 公开头⽂件
s.private_header_files = "Headers/Private/*.h" # 私有头⽂件,不会对外暴暴露露
s.ios.resource_bundle = {"Box" => "Image/*.png"} # bundle 资源⽂文件
# s.resource_bundles = {"Box" => ["Image/*.png","Text/*.txt"], "OtherBox" => ["Image1/*.png"]} # bundle 资源⽂文件
s.resource = "Resources/HockeySDK.bundle" # 资源⽂文件,⽀支持所有⽂文件,bundle,imageasset,png, jpg, gif, ttf 等
s.resources = ["image/*.png","font/*.ttf"]
s.ios.exclude_files = 'Classes/osx' # 不不包含⽂文件,多⽤用于跨平台
# s.exclude_files = 'Classes/**/unused.{h,m}'
s.preserve_path = "aa.txt" # 受保护的⽂文件,下载以后,不会被删除, Cocoapods 默认会删除 podspec 没有引⽤用到的⽂文件, 多用与静态库,framework,资源⽂文件等
s.module_map = 'source/module.modulemap' # modulemap 文件,Cocoapods 默认会⾃己创建
s.subspec "Demo1" do |ss| # 上述属性⼤大多数子模块都可使⽤用
ss.dependency "JSONKit" # 依赖,此处可以是公开库,私有库,本地库(前提是在主⼯工程安装)
ss.subspec "Demo11" do |sss|
ss.dependency "AFNetworking", "~> 1.0.0"
end
end
end
Demo
Cocoapods官网
本文参考资料
都撸到这里了, 还不给个 !