CocoaPods 建立私有倉庫(ObjC)

Cocoapods的原理

pod repo

經過Podfile文件執行pod install或者pod update往iOS項目中導入第三方庫,其實是找到podspec文件中描述的git倉庫(svn), 而後從git倉庫clone到本地的。html

咱們從gem安裝cocoapods成功以後,在本地的~/.cocoapods/repo目下的master文件夾下就存在了cocoapods遠程倉庫的全部索引,也就是spec文件。ios

cocoapods repo

經過一層層的查找能夠找到與咱們須要的第三方庫名字一致的一個文件夾,可是文件夾裏並無咱們所需的代碼文件。git

首先repo/master爲何這麼分層呢?github

  • 這是由於爲了合理的對cocoapods數以萬計的三方庫索引,因此將三方庫的名字進行了md5加密而後取前三個字母做爲這個第三方庫的前三個索引,這樣每一個目錄下存放的庫就不會太多,從而減小查找時間。

爲何不是代碼文件?web

  • 由於cocoapods自己就不保存代碼文件,它只保留一個庫的描述,經過這個庫的描述去git倉庫去查找代碼文件。

pod repo中的文件夾

使用git做爲遠程倉庫push到cocoapods的狀況下,git tag將做爲此次push的版本號,這就是爲何repo/master下的第三方庫文件夾中會有一些這樣的文件夾。xcode

每一個版本對應的文件夾下有一個podspec文件,這個文件是庫的描述:bash

SDWebImage(4.4.6)的podspec服務器

{
  "name": "SDWebImage", 名字
  "version": "4.4.6", 版本號
  "platforms": { 支持的平臺
    "osx": "10.9",
    "ios": "7.0",
    "tvos": "9.0",
    "watchos": "2.0"
  },
  "license": "MIT", 開源協議
  "summary": "Asynchronous image downloader with cache support with an UIImageView category.", 簡述
  "homepage": "https://github.com/SDWebImage/SDWebImage", 主頁
  "authors": { 做者
    "Olivier Poitrey": "rs@dailymotion.com"
  },
  "source": { 源文件倉庫
    "git": "https://github.com/SDWebImage/SDWebImage.git",
    "tag": "4.4.6"
  },
  "description": "This library provides a category for UIImageView with support for remote images coming from the web. It provides an UIImageView category adding web image and cache management to the Cocoa Touch framework, an asynchronous image downloader, an asynchronous memory + disk image caching with automatic cache expiration handling, a guarantee that the same URL won't be downloaded several times, a guarantee that bogus URLs won't be retried again and again, and performances!", 描述
  "requires_arc": true, 是不是在ARC下
  "frameworks": "ImageIO", 須要的framework
  "default_subspecs": "Core", 默認的子庫 有多個子庫的狀況下
  "subspecs": [ 子庫 每一個子庫能夠做爲一個獨立的庫引入到項目中
    {
      "name": "Core", 名字
      "source_files": "SDWebImage/{NS,SD,UI}*.{h,m}", 文件路徑 經過通配符查找
      "exclude_files": [ 不包含的文件
        "SDWebImage/UIImage+WebP.{h,m}",
        "SDWebImage/SDWebImageWebPCoder.{h,m}"
      ],
      "tvos": { tvos平臺下的配置
        "exclude_files": "SDWebImage/MKAnnotationView+WebCache.*"
      }
    },
    {
      "name": "MapKit",
      "platforms": {
        "osx": "10.9",
        "ios": "7.0",
        "tvos": "9.0"
      },
      "source_files": "SDWebImage/MKAnnotationView+WebCache.*",
      "frameworks": "MapKit",
      "dependencies": { 依賴的庫
        "SDWebImage/Core": [

        ]
      }
    },
    {
      "name": "GIF",
      "platforms": {
        "ios": "7.0"
      },
      "source_files": "SDWebImage/FLAnimatedImage/*.{h,m}",
      "dependencies": {
        "SDWebImage/Core": [

        ],
        "FLAnimatedImage": [
          "~> 1.0"
        ]
      }
    },
    {
      "name": "WebP",
      "source_files": [
        "SDWebImage/UIImage+WebP.{h,m}",
        "SDWebImage/SDWebImageWebPCoder.{h,m}"
      ],
      "xcconfig": { xcode的配置
        "GCC_PREPROCESSOR_DEFINITIONS": "$(inherited) SD_WEBP=1",
        "USER_HEADER_SEARCH_PATHS": "$(inherited) $(SRCROOT)/libwebp/src"
      },
      "watchos": {
        "xcconfig": {
          "GCC_PREPROCESSOR_DEFINITIONS": "$(inherited) SD_WEBP=1 WEBP_USE_INTRINSICS=1",
          "USER_HEADER_SEARCH_PATHS": "$(inherited) $(SRCROOT)/libwebp/src"
        }
      },
      "dependencies": {
        "SDWebImage/Core": [

        ],
        "libwebp": [
          ">= 0.5"
        ]
      }
    }
  ]
}
複製代碼

建立一個私有cocoapods倉庫

建立存放podsepc的倉庫

經過上述原理,若是建立一個私有的cocoapods倉庫就不能將倉庫的podspec文件發佈到cocoapods的repo中。markdown

因此咱們須要在本身的git服務器中建立一個保存podspec的倉庫。最好保證倉庫建立的時候是一個空倉庫,不須要使用readme之類的文件去初始化它。不然會有git衝突的狀況須要解決。app

建立完倉庫以後獲取倉庫地址 在terminal中執行pod的指令將倉庫添加到本地的pod repo中。

pod repo add [name] [url]

添加完成以後再~/.cocoapods/repo中就能夠看到和master同級的一個目錄,也就是存放庫索引的地方。

添加podspec倉庫

固然也可使用pod repo remove [name]移除repo。

建立存放源碼的倉庫並推送到私有cocoapods

在git服務器上再建立一個倉庫用於存放源代碼。

在terminal中執行pod lib create 名字建立一個cocoapods的demo文件。

pod lib create test
Cloning `https://github.com/CocoaPods/pod-template.git` into `test`.
Configuring test template.
security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.

------------------------------

To get you started we need to ask a few questions, this should only take a minute.

If this is your first time we recommend running through with the guide:
 - https://guides.cocoapods.org/making/using-pod-lib-create.html
 ( hold cmd and click links to open in a browser. )


What platform do you want to use?? [ iOS / macOS ]
 > ios

What language do you want to use?? [ Swift / ObjC ]
 > objc

Would you like to include a demo application with your library? [ Yes / No ]
 > yes

Which testing frameworks will you use? [ Specta / Kiwi / None ]
 > none

Would you like to do view based testing? [ Yes / No ]
 > no

What is your class prefix?
 > soc

複製代碼

執行以後會從git克隆一個模板,並會問幾個問題,依次按照需求選擇便可。完成以後會打開一個Xcode project。

在上圖的路徑(也就是replaceme.m存放的目錄)下添加文件並刪除replaceme.m

進入Example目錄 配置Podfile,將項目名稱.podspec配置到Podfile中,若是有依賴庫,順便添加。

platform :ios, '8.0'

target 'SoCNetWork_Example' do
  pod 'SoCNetWork', :path => '../SoCNetWork.podspec'
  pod 'AFNetworking' # 依賴AFNetworking
  pod 'YYCache' # 依賴YYCache
end
複製代碼

保存以後執行 pod update (可選參數:--verbose 能夠查看詳細的過程 | --no-repo-update 不升級本地的repo會快一些)

執行結束以後在PodsDevelopment Pods目錄下就能夠看到咱們添加的文件了。

添加文件

另外依賴的AFNetworkingYYCache也添加到項目中了。

編譯一下有錯改之,無錯進行下一步。

編輯podspec文件

Pod::Spec.new do |s|
  s.name             = '名字'
  s.version          = '版本號 須要和git tag保持一致'
  s.summary          = '簡述'
  
  # This description is used to generate tags and improve search results.
  # * Think: What does it do? Why did you write it? What is the focus?
  # * Try to keep it short, snappy and to the point.
  # * Write the description between the DESC delimiters below.
  # * Finally, don't worry about the indent, CocoaPods strips it!
  
  s.description      = <<-DESC
  TODO: 描述
  DESC
  
  s.homepage         = '主頁 最好保證能夠訪問'
  s.license          = { :type => 'MIT', :file => 'LICENSE' } #開源協議
  s.author           = { 'SoC' => 'joeqq1028@163.com' } #做者
  s.source           = { :git => 'git倉庫地址', :tag => s.version.to_s }
 
  s.ios.deployment_target = '8.0' #最低支持的系統版本
  
  s.source_files = 'SoCNetWorkOAuth1.0/Classes/**/*' #文件路徑
  s.dependency 'AFNetworking' #依賴的庫
  s.dependency 'YYCache' #依賴的庫
end
複製代碼

關於source_files

這裏若是添加的目錄有嵌套可使用subspec來實現。

例如:

嵌套

OAuth1.0下面有一個oauthcore文件夾。

podspecsource_file項的填寫,再也不須要s.source_file可使用以下示例填寫:

s.subspec 'OAuth1.0' do |ss|
    ss.source_files = '項目名/Classes/OAuth1.0/*.{h,m}'
    ss.subspec 'oauthcore' do |sss|
      sss.source_files = '項目名/Classes/OAuth1.0/oauthcore/*.{h,m}'
    end
  end
複製代碼

關於搜索文件的通配符在cocoapods官網中已經描述的很清楚了


建立完成以後使用pod lib lint來驗證podspec填寫的準確性。能夠選擇參數:

  • --verbose 查看整個過程
  • --allow-warnings 容許一些警告經過驗證 `若是驗證出錯,而project build success 能夠嘗試添加這個參數
  • --source 若是依賴的庫是一個私有倉庫建立的庫,可使用這個參數指定私有倉庫的podspec倉庫,除此以外最好將cocoapods公有庫的source也指定一下.好比(pod lib lint --sources='[私有podsepec倉庫地址],https://github.com/CocoaPods/Specs' --verbose --allow-warnings --no-clean

驗證經過以後 須要將文件push到git倉庫中:

git init
git add .
git commit -am 'desc'
git remote add origin 'url'
git push origin master
git tag 'tag'
git push --tags
複製代碼

添加完成以後將podsepc添加到私有repo中使用命令

pod repo push [repo name] [name.podspec] --verbose --allow-warnings

可選參數一樣包括上述的--source=,跟上面描述的同樣,再也不贅述。

這樣建立私有庫的工做就完成了。

使用私有cocoapods倉庫

使用私有倉庫的時候須要在Podfile中指定source。

source 'repo git url' # 私有倉庫(存放podsepc文件的倉庫)git地址
source 'https://github.com/CocoaPods/Specs.git' # cocoapods 公用倉庫地址

platform :ios, '8.0'

target 'CTVITNetWork' do
  pod 'name'
end
複製代碼

當遇到使用依賴庫建立子類的時候會在 .h 文件中引入依賴庫的頭文件 而這樣一般會在 執行 pod repo push 的時候發生錯誤。這個時候在 pod repo push 命令中添加 --use-libraries 參數可解決這個問題。而若是 .h 文件對依賴庫中類的引用是非必須的, 也能夠將 依賴庫中類的聲明放到 .m 中, 以解決這個錯誤。

END

相關文章
相關標籤/搜索