Cocoapods創(chuàng)建私有庫(kù),模塊/組件化首選, podspec介紹

項(xiàng)目模塊化, 模塊之間的依賴方式首選cocoapods, 通過pod直接導(dǎo)入模塊方便快捷, cocoapods倉(cāng)庫(kù)存放在Git上, Git現(xiàn)在又可以免費(fèi)創(chuàng)建私有倉(cāng)庫(kù), 爽不爽...

本篇文章主要介紹cocoapods創(chuàng)建私有倉(cāng)庫(kù)的方式.
名詞介紹:

  • podspec: podspec文件是私有庫(kù)的配置索引文件, 每一個(gè)庫(kù)都對(duì)應(yīng)一個(gè)podspec文件, 可以去Git上查看AFNetworking Masonry等的podspec, 每次更新發(fā)布版本都需要編輯此文件, 此文件主要包括庫(kù)的描述凰棉、版本醇蝴、需要暴露的文件等等...
  • repo: 是存放podspec文件的Git倉(cāng)庫(kù)脾猛,當(dāng)你使用了cocoapods后會(huì)被clone到本地~/.cocoapods/repos目錄下,文件中的master就是官方的repo. 把podspec提交到自己repo倉(cāng)庫(kù)上就是私有庫(kù), 提交到官方的repo上就是公開的, 別人就可以搜到使用。
創(chuàng)建私有庫(kù)共分一下幾步,以創(chuàng)建自己創(chuàng)建的LBMusicPlayer私有庫(kù)為例, 分的步驟較細(xì).

第一步
先在自己的Git創(chuàng)建兩個(gè)倉(cāng)庫(kù):

  1. 存放podspec文件的repo倉(cāng)庫(kù)钧惧,比如叫XYRepo,以后不管創(chuàng)建多少私有庫(kù)勾习,都可以把podspec文件提交到這里浓瞪。
  2. 存放自己私有庫(kù)的倉(cāng)庫(kù),比如叫LBMusicPlayer巧婶。

第二步
創(chuàng)建Repo, 創(chuàng)建后在~/.cocoapods/repos目錄下可以看到XYRepo文件

# pod repo add [Private Repo Name] [第一步創(chuàng)建的repo倉(cāng)庫(kù)地址]
$ pod repo add XYRepo https://github.com/huangxianyu/XYRepo.git
~/.cocoapods/repos

第三步
創(chuàng)建一個(gè)項(xiàng)目, 以私有庫(kù)的名字命名乾颁,比如叫LBMusicPlayer,用于測(cè)試代碼艺栈,在項(xiàng)目目錄下創(chuàng)建文件夾, 一般命名為Classes, 存放私有庫(kù)代碼英岭。

WX20190313-112436@2x.png

第四步
在項(xiàng)目目錄下創(chuàng)建.podspec文件, 名字和項(xiàng)目名一致.

$ pod spec create LBMusicPlayer

第五步
修改你的podspec文件, 刪除沒用的注釋和命令,這里列舉部分常用的屬性湿右,詳情看Demo诅妹。

    Pod::Spec.new do |s|
        [s.name](http://s.name/)            = "LBMusicPlayer"    #名稱
        s.version          = "0.0.1"            #版本號(hào)
        s.summary          = "LBMusicPlayer"    #簡(jiǎn)短介紹,下面是詳細(xì)介紹
        s.description      = <<-DESC            #詳細(xì)介紹
            LBMusicPlayer
        DESC
        s.homepage         = "[https://github.com/huangxianyu/LBMusicPlayer](https://github.com/huangxianyu/LBMusicPlayer)"#主頁(yè),這里要填寫可以訪問到的地址诅需,不然驗(yàn)證不通過
        # 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'              #開源協(xié)議
        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}"}  #項(xiàng)目地址漾唉,這里不支持ssh的地址,驗(yàn)證不通過堰塌,只支持HTTP和HTTPS赵刑,最好使用HTTPS
        # s.social_media_url = '[https://twitter.com/](https://twitter.com/)<TWITTER_USERNAME>'  #多媒體介紹地址
        s.platform     = :ios, '9.0'            #支持的平臺(tái)及版本
        s.requires_arc = true                   #是否使用ARC,如果指定具體文件场刑,則具體的問題使用ARC
        s.source_files = "Classes", "Classes/**/*.{h,m}"  #代碼源文件地址般此,表示Classes目錄及其子目錄下所有文件,如果有多個(gè)目錄下則用逗號(hào)分開牵现,如果需要在項(xiàng)目中分組顯示铐懊,這里也要做相應(yīng)的設(shè)置
        s.resource_bundles = {
             'LBMusicPlayer'=> ['LBMusicPlayer/Assets/*.png']
        }   #資源文件地址
        s.public_header_files = '../Classes/**/*.h'  #公開頭文件地址
        s.frameworks = 'UIKit'                  #所需的framework,多個(gè)用逗號(hào)隔開
        s.dependency 'AFNetworking', '~> 2.3'  #依賴關(guān)系瞎疼,該項(xiàng)目所依賴的其他庫(kù)科乎,如果有多個(gè)需要填寫多個(gè)s.dependency
    end

第五步
可以先本地測(cè)試修改代碼。
私有庫(kù)的代碼贼急,在pod install后茅茂,在Development Pods文件夾下, 可以直接修改代碼運(yùn)行測(cè)試, 不用每次修改完代碼都pod install, 直接運(yùn)行就可以
podfile內(nèi)添加一下代碼, 參考第9步

pod 'LBMusicPlayer', :path => '../LBMusicPlayer’

然后執(zhí)行命令

$ pod install

第六步
測(cè)試無誤后, 推送本地代碼到git, 并打tag推送到git捏萍,podspec文件的s.version一定要和tag一致。

$ git add .
$ git commit -m "描述"
$ git remote add origin https://github.com/huangxianyu/LBMusicPlayer.git  #添加遠(yuǎn)端倉(cāng)庫(kù), 第一步創(chuàng)建的
$ git push -u origin master                 #提交到遠(yuǎn)端倉(cāng)庫(kù)
$ git tag -m "first release" 0.0.1          #版本號(hào)需要和.podspec文件的s.version一致
$ git push —tags

第七步
驗(yàn)證倉(cāng)庫(kù)配置是否正確, 驗(yàn)證之前一定要把所有修改代碼push到git, 一般會(huì)加上這個(gè)命令 --allow-warnings:允許警告

#驗(yàn)證書寫格式 --verbose:詳細(xì)信息 --use-libraries:使用了靜態(tài)庫(kù) --allow-warnings:允許警告
$ pod spec lint LBMusicPlayer.podspec --allow-warnings
#驗(yàn)證庫(kù)編譯
$ pod lib lint --allow-warnings

第八步
驗(yàn)證通過后,將.podspec文件推送到第一步創(chuàng)建的Repo上

$ pod repo push XYRepo LBMusicPlayer.podspec --allow-warnings

第九步
到此已經(jīng)成功配置好私有倉(cāng)庫(kù)

# 更新repo
$ pod repo update XYRepo
$ pod serach LBMusicPlayer
# 如果搜索不到執(zhí)行命令
$ rm ~/Library/Caches/CocoaPods/search_index.json

第十步
使用私有庫(kù)
在.podfile文件內(nèi)添加一下內(nèi)容, 后 pod install
導(dǎo)入頭文件: #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文件
    # 遠(yuǎn)程倉(cāng)庫(kù)依賴
    pod 'LBMusicPlayer'
end

第十一步
更新版本
再?gòu)牡谖宀介_始就可以空闲,一定不要忘了打tag令杈。
到此結(jié)束??

注意: 如果本地調(diào)試成功,但推送到私有倉(cāng)庫(kù)失敗時(shí)碴倾,請(qǐng)執(zhí)行以下步驟:
1.which pod: 輸出 cocoapods 在本地路徑.
2.進(jìn)入到 ruby 的文件夾逗噩,找到 gems/cocoapods-(版本號(hào))/lib/cocoapods/validator.rb 文件.
3.以 sudo 用戶權(quán)限打開該文件.
4.找到 validate 函數(shù)做如下修改就可以了:

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

有關(guān)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" #版本號(hào)
        s.summary           = "LLBPayManager" # 簡(jiǎn)單描述
        s.description       = <<-DESC # 詳細(xì)描述
                                    LLBPayManager
                            DESC
        s.homepage         = "https://github.com/huangxianyu/LBMusicPlayer" #主頁(yè)
        s.license          = "MIT" #許可協(xié)議
        s.author           = { "huangxianyu" => "huangxianyu@langlib.com" }
        s.platform         = :ios, "9.0"
        s.ios.deployment_target = '8.0' # 與platform 中的版本號(hào)相同
        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 ?文件數(shù)組
        s.default_subspec   = "Default" # 默認(rèn)?子模塊
        s.default_subspecs  = "Default" # 默認(rèn)?子模塊
        s.static_framework  = true # 是否使?用靜態(tài) framework
        s.swift_version     = "4.2" # swift 版本號(hào)
        s.cocoapods_version = ">= 1.5.3" # cocoapods 版本號(hào)
        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" # 安裝該庫(kù)之前執(zhí)?行行的腳本
        s.deprecated        = false # 是否已經(jīng)廢棄
        s.ios.framework     = "CFNetwork" # 依賴系統(tǒng) framework ,可以指定平臺(tái)
        # s.frameworks      = "CoreData" # 依賴系統(tǒng)framework跌榔,全部平臺(tái)
        s.weak_framework    = "UserNotifications" # 弱鏈接异雁,?比如說?一個(gè)項(xiàng)?目同時(shí)兼容iOS6和iOS7,但某?一個(gè)
        framework只在iOS7上有僧须,這時(shí)候如果?用強(qiáng)鏈接片迅,那么在iOS7上運(yùn)?行行就會(huì)crash,使?用weak_frameworks可以避免 這種情況皆辽。
        # s.weak_frameworks = ["UserNotifications", "SafariServices"] s.ios.vendored_frameworks = "A.framework" # ?自定義framework 只針對(duì)iOS平臺(tái)
        # s.vendored_frameworks = "A.framework", "B.framework" # ?自定義framework ,全部平臺(tái)
        s.ios.library = "xml2" # 系統(tǒng)靜態(tài)庫(kù)芥挣,可以指定平臺(tái)
        # s.libraries = "xml2", 'z' # 系統(tǒng)靜態(tài)庫(kù)數(shù)組驱闷,全部平臺(tái)
        s.ios.vendored_library = "libTest.a" # ?自定義靜態(tài)庫(kù) 只針對(duì)iOS平臺(tái)
        # s.vendored_libraries = "libTest1.a", "libTest2.a" # 自定義靜態(tài)庫(kù),全部
        s.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format' # 編譯參數(shù)空免,在BuildSetting 中可設(shè)置
        s.xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' } # 針對(duì)整個(gè)項(xiàng)?目
        s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' } # pod 的 target 項(xiàng)?目配置
        s.user_target_xcconfig = { 'MY_SUBSPEC' => 'YES' } # 主?工程的 target 配置
        s.prefix_header_contents = "#import <UIKit/UIKit.h>", "#import<Foundation/Foundation.h>" # pch ?文件內(nèi)容
        s.prefix_header_file = 'iphone/include/prefix.pch' # pch ?文件
        s.module_name = 'Demo' # swift 模塊名
        s.header_dir = 'Header' # 頭?文件存放位置空另,主要?的是為項(xiàng)?目中引?用頭?文件時(shí)使?用 <> 找不不到報(bào)錯(cuò),React 中就有用到
        s.header_mappings_dir = 'src/include' # 頭?文件?文件夾目錄結(jié)構(gòu)
        s.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' } # 編譯時(shí)執(zhí)行的腳本
        # s.script_phases = [ { :name => 'Hello World', :script => 'echo "Hello World"' } ]
        s.source_files = "Classes/**/*.{h,m}" # 源?文件路路徑蹋砚,是只相對(duì) podspec ?文件所在?文件夾的路路徑扼菠,匹配正則
        s.public_header_files = "Headers/Plublic/*.h" # 公開頭?件
        s.private_header_files = "Headers/Private/*.h" # 私有頭?件,不會(huì)對(duì)外暴暴露露
        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' # 不不包含?文件秧饮,多?用于跨平臺(tái)
        # s.exclude_files = 'Classes/**/unused.{h,m}'
        s.preserve_path = "aa.txt" # 受保護(hù)的?文件,下載以后泽篮,不會(huì)被刪除, Cocoapods 默認(rèn)會(huì)刪除 podspec 沒有引?用到的?文件, 多用與靜態(tài)庫(kù),framework杭抠,資源?文件等
        s.module_map = 'source/module.modulemap' # modulemap 文件夷磕,Cocoapods 默認(rèn)會(huì)?己創(chuàng)建
        s.subspec "Demo1" do |ss| # 上述屬性?大多數(shù)子模塊都可使?用
            ss.dependency "JSONKit" # 依賴,此處可以是公開庫(kù)亏拉,私有庫(kù)扣蜻,本地庫(kù)(前提是在主?工程安裝)
            ss.subspec "Demo11" do |sss|
                ss.dependency "AFNetworking", "~> 1.0.0"
            end
        end
    end
     

Demo
Cocoapods官網(wǎng)
本文參考資料

都擼到這里了, 還不給個(gè)?? !

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逆巍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弱贼,更是在濱河造成了極大的恐慌蒸苇,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吮旅,死亡現(xiàn)場(chǎng)離奇詭異溪烤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)庇勃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門檬嘀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人责嚷,你說我怎么就攤上這事鸳兽。” “怎么了罕拂?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵揍异,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我爆班,道長(zhǎng)衷掷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任柿菩,我火速辦了婚禮戚嗅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枢舶。我一直安慰自己懦胞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布凉泄。 她就那樣靜靜地躺著躏尉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旧困。 梳的紋絲不亂的頭發(fā)上醇份,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音吼具,去河邊找鬼僚纷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拗盒,可吹牛的內(nèi)容都是我干的怖竭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼陡蝇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼痊臭!你這毒婦竟也來了哮肚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤广匙,失蹤者是張志新(化名)和其女友劉穎允趟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸦致,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡潮剪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了分唾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抗碰。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绽乔,靈堂內(nèi)的尸體忽然破棺而出弧蝇,到底是詐尸還是另有隱情,我是刑警寧澤折砸,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布看疗,位于F島的核電站,受9級(jí)特大地震影響睦授,放射性物質(zhì)發(fā)生泄漏鹃觉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一睹逃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祷肯,春花似錦沉填、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蒋纬,卻和暖如春猎荠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜀备。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工关摇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碾阁。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓输虱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親脂凶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宪睹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353