Cocoapods创建私有库,模块/组件化首选, podspec介绍

项目模块化, 模块之间的依赖方式首选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创建两个仓库:

  1. 存放podspec文件的repo仓库,比如叫XYRepo,以后不管创建多少私有库,都可以把podspec文件提交到这里。
  2. 存放自己私有库的仓库,比如叫LBMusicPlayer。

第二步
创建Repo, 创建后在~/.cocoapods/repos目录下可以看到XYRepo文件

# pod repo add [Private Repo Name] [第一步创建的repo仓库地址]
$ pod repo add XYRepo https://github.com/huangxianyu/XYRepo.git
~/.cocoapods/repos

第三步
创建一个项目, 以私有库的名字命名,比如叫LBMusicPlayer,用于测试代码,在项目目录下创建文件夹, 一般命名为Classes, 存放私有库代码。

WX20190313-112436@2x.png

第四步
在项目目录下创建.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"=> "[huangxianyu@langlib.com](mailto:huangxianyu@langlib.com)"}  #作者信息
        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/)<TWITTER_USERNAME>'  #多媒体介绍地址
        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 <LBMusicPlayer/TPOAudioRecordManager.h> 或 #import “TPOPlayMusicManager.h"

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" => "huangxianyu@langlib.com" }
        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 <UIKit/UIKit.h>", "#import<Foundation/Foundation.h>" # 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官网
本文参考资料

都撸到这里了, 还不给个👍 !

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