CocoaPods 私有庫 step by step

目錄


環境

macOS 10.12.6
Xcode 9.1
CocoaPods 1.3.1
Swift 4.0


TL;DR(步驟概述)

1、創建示例工程
pod lib create XGLib
2、編寫 Pod 庫

如果使用了 Swift,需要指定 Swift 版本:在 Terminal 中的項目目錄下,輸入 echo "4.0" > .swift-version,會在項目根目錄下生成一個 .swift-version 文件

3、Build 項目后,在 Demo 工程中調用
4、修改 podspec 文件

必須修改字段:

s.version
s.summary
s.source
5、本地校驗pod lib lint
6、提交代碼到遠程倉庫
7、為項目打上tag,并推送遠端
git tag -m "first release v0.0.1" 0.0.1
git push --tags     #推送tag到遠端倉庫
8、聯網校驗pod spec lint
9、創建私有的 Spec 索引庫

如果已經創建過,就不需要再創建了

10、將創建的私有 Spec 索引庫添加到CocoaPods的目錄下

如果已經添加過,就不需要再添加了

pod repo add CodingSpecRepo https://coding.net/u/rxg9527/p/SpecRepo
11、添加 Podspec 到私有 Spec 索引庫中
pod repo push CodingSpecRepo XGLib.podspec
More: 私有庫升級,添加庫依賴,圖片依賴,私有庫子庫

一、在CocoaPods的指令幫助下創建一個示例工程

# 指令
pod lib create MyLibrary
# 示例
pod lib create XGLib

之后會有一系列問題:

  1. 使用語言
  2. 是否需要為你創建一個Demo應用
  3. 想要使用哪個測試框架
  4. 是否需要UI Test
  5. 使用語言為Objective-C的話,會詢問Objective-C類前綴使用什么

這里在第2個問題中輸入Yes來創建一個Demo應用,以更好的調試和自測Pods庫代碼。

image


1、Pod Lib Create生成的模版
XGLib目錄結構
├── .travis.yml
├── _Pods.xcproject
├── Example
│   ├── XGLib
│   ├── XGLib.xcodeproj
│   ├── XGLib.xcworkspace
│   ├── Podfile
│   ├── Podfile.lock
│   ├── Pods
│   └── Tests
├── LICENSE
├── XGLib.podspec
├── Pod
│   ├── Assets
│   └── Classes
│     └── RemoveMe.[swift/m]
└── README.md

文件:

  • .travis.yml - a setup file for travis-ci.
  • _Pods.xcproject - a symlink to your Pod's project for 支持Carthage
  • LICENSE - 默認MIT License.
  • XGLib.podspec - 該庫的Podspec
  • README.md - 默認README
  • RemoveMe.swift/m - a single file to to ensure compilation works initially.

文件夾:

  • Pod - 個人Pods庫的所有類
  • Example - 生成的Demo

2、生成的Workspace結構
workspace結構
  1. 編輯 Podspec metadata, 更改 README 和 Podspec
  2. Demo 工程
  3. 測試
  4. Pods 開發文件夾,真正修改類的區域。
  5. Finally the Pods used in setting Up the project.

注意:Swift的Class和function要聲明為public,才能在Demo中可用


3、Development Pods文件夾

Development Pods 不同于普通的 CocoaPods,是 symlinked files,所以編輯 這些文件會改變源文件,因此可以在 Xcode 中做更改。Demo 和測試文件需要通過#import <MyLib/XYZ.h>的方式引入頭文件。

注意: 因為 Development Pods 的實現細節, 當添加文件到 Pod/ClassesPod/Assets 或 更新 podspec,需要執行 pod installpod update
例如我們創建的 XGLib,在 pod lib create XGLib 的過程中已經執行過了 pod install ,之后添加文件只需執行 pod update


二、實際編寫 Pod 庫(類庫代碼僅作參考)

1、在XGLib中編寫一個文件

Pod/Classes 目錄下刪除 RemoveMe.swift,創建一個 UILabel-Extension.swift,代碼如下:

// Swift4.0代碼(3.0可用)
//  UILabel-Extension.swift
//  XGLib

import Foundation

extension UILabel {
 
    convenience public init(bgColor: UIColor?,
                            text: String?,
                            textColor: UIColor?,
                            fontSize: CGFloat?,
                            isBold: Bool?,
                            textAlignment: NSTextAlignment?,
                            numberOfLines: Int?) {
        self.init()
        
        if let color = bgColor {
            backgroundColor = color
        }
        if let text = text {
            self.text = text
        }
        if let textColor = textColor {
            self.textColor = textColor
        }
        
        if let fontSize = fontSize {
            if let isBold = isBold {
                if isBold {
                    font = UIFont.boldSystemFont(ofSize: fontSize)
                } else {
                    font = UIFont.systemFont(ofSize: fontSize)
                }
            } else {
                font = UIFont.systemFont(ofSize: fontSize)
            }
        }
        
        if let textAlignment = textAlignment {
            self.textAlignment = textAlignment
        }
        
        if let numberOfLines = numberOfLines {
            self.numberOfLines = numberOfLines
        }        
    }

}

2、Build 項目后,在 Demo 工程中調用

?+B build項目(不先build的話,沒有代碼提示),之后 import 該項目,在 ViewController 中調用。成功運行項目。

image


3、修改 podspec 文件

podspec 文件主要有以下幾個字段:

  • version:這個 spec 映射的版本,保證 Git 的 releases 與此對應;
  • homepage:項目主頁;
  • source:框架源代碼的托管地址;
  • tag:與 version 對應;
  • source_files:框架源代碼的目錄、文件、文件類型等規則;
image

4、如果類庫使用了 Swift 語言,需要指定 Swift 版本

在終端中的項目目錄下,輸入 echo "4.0" > .swift-version,會在項目根目錄下生成一個 .swift-version 文件,如圖

image


5、提交代碼到遠程倉庫

這里我個人提交到了國內的代碼托管平臺Coding,網址在rxg9527 - XGLib

同時根據我們輸入的 s.version 版本號,我們要對相應的提交記錄打上Tag,并Push到遠程

git tag -m "first release v0.0.1" 0.0.1
git push --tags     #推送tag到遠端倉庫
image

6、校驗私有庫

我們可以用 pod lib lintpod spec lint 兩條命令來對類庫做驗證。

  • pod lib lint
    本地檢查 Pods,主要校驗 podspec 文件

  • pod spec lint
    遠程檢查 Pods,這次 CocoaPods 會根據 podspec 文件里的 source 檢查對應的倉庫里有沒有指定tag的倉庫

這時如果一切順利,Pod庫的編寫就大功告成,通過 CocoaPods 的質檢環節了。


三、通過私有的 Spec 索引庫管理使用私有庫

1、創建私有的 Spec 庫

團隊或個人自建的Pods私有庫編寫完成后,我們需要創建一個私有的Spec庫來存放。而 CocoaPods 所有的公有庫都是存放在 CocoaPods 官方建立的 Spec 索引倉庫中的。

示例中,我使用國內的Coding來存放 Spec 庫。

image

2、將第1步創建的私有SpecRepo添加到CocoaPods的目錄下
# 指令
pod repo add REPO_NAME SOURCE_URL
# 示例
pod repo add CodingSpecRepo https://coding.net/u/rxg9527/p/SpecRepo

此時添加的「私有SpecRepo」目錄是在~/.cocoapods/repos/下的
[圖片上傳失敗...(image-1ff75c-1512367322220)]

去檢查一下這步添加操作是否成功

# 指令
cd ~/.cocoapods/repos/REPO_NAME
pod repo lint .
# 示例
cd ~/.cocoapods/repos/CodingSpecRepo
pod repo lint .
image

3、添加 Podspec 到私有 Spec 索引庫中

首先確認已經為私有庫打過tag并設置了version,然后運行

# 指令
pod repo push REPO_NAME SPEC_NAME.podspec
# 示例
pod repo push CodingSpecRepo XGLib.podspec

這條指令默認會執行 pod spec lint 做校驗。

此時 ~/.cocoapods/repos/REPO_NAME下的目錄結構會是

.
├── Specs
    └── [SPEC_NAME]
        └── [VERSION]
            └── [SPEC_NAME].podspec

本地 Spec 索引庫目錄結構
遠程 Spec 索引庫目錄結構

4、使用私有庫

現在私有庫就可以在 Podfile 文件中指定使用了,通過 source 目錄 的方式使用私有 Spec 索引庫:

# 指令
source 'URL_TO_REPOSITORY'
# 示例
source 'https://coding.net/u/rxg9527/p/SpecRepo/git'

整個 Podfile 文件:

source 'https://github.com/CocoaPods/Specs.git' # CocoaPods 官方 Spec 索引庫
source 'https://coding.net/u/rxg9527/p/SpecRepo/git'

platform :ios, '8.0'
use_frameworks!

target 'UsePrivatePodDemo' do
    pod 'XGLib', '~>0.0.1'
end

UsePrivatePodDemo 工程中,?+B build項目(不先build的話,沒有代碼提示),之后 import 該項目,在 ViewController 中調用。成功運行項目。


四、Other

1、私有庫升級

UILabel-Extension.swift 添加方法:

import Foundation

extension UILabel {
    ……
    ……    
        /// 背景透明,不加粗,居中對齊
    convenience public init(centerText: String?,
                            textColor: UIColor?,
                            fontSize: CGFloat?) {
        self.init(bgColor: nil, text: centerText, textColor: textColor, fontSize: fontSize, isBold: false, textAlignment: .center, numberOfLines: nil)
    }
    
    /// 背景透明,加粗,居中對齊
    convenience public init(centerBoldText: String?,
                            textColor: UIColor?,
                            fontSize: CGFloat?) {
        self.init(bgColor: nil, text: centerBoldText, textColor: textColor, fontSize: fontSize, isBold: true, textAlignment: .center, numberOfLines: nil)
    }
    
}

然后跟之前一樣:

  1. 在 Demo 工程中調用確認沒問題
  2. pod lib lint本地校驗
  3. 修改 podspec 文件,至少要修改提高 version
  4. 提交代碼到遠程倉庫
  5. 根據 s.version 版本號,對相應的提交記錄打 tag,并 Push 到遠程
  6. pod spec lint聯網校驗
  7. pod repo push REPO_NAME SPEC_NAME.podspec,即pod repo push CodingSpecRepo XGLib.podspec

Okay, That's it!

遠程私有庫和遠程私有索引庫全部更新完畢,現在這個庫只要更新本地的索引文件就可以使用了

pod update --no-repo-update
pod install

2、CocoaPods 庫依賴

假設我們封裝的私有庫要基于某個公有庫做封裝,比如常見的項目中需要我們基于 Alamofire 做一層業務上的封裝??,那么如何在私有庫的制作中,優雅的導入 Alamofire 呢?
CocoaPods 為我們提供了這種能力,通過修改 podspec 文件中的 s.dependency 字段就可以完成,同時可以像 Podfile 中那樣指定版本號。
dependency 指明了這個庫的依賴,下面我們通過依賴 Kingfisher 來示范:

1、 在 XGLib.podspec 中加入

s.dependency 'Kingfisher', '~> 4.0'

2、 新建 UIImageView-Extension.swift
3、 在 Demo 工程中執行 pod update --no-repo-update 會引入 KingfisherUIImageView-Extension.swift
4、 完成 UIImageView-Extension.swift

//
//  UIImageView-Extension.swift

import Foundation
import Kingfisher

extension UIImageView {
    
    public func setImage(with url: URL?) {
        self.kf.setImage(with: url)
    }
    
}

5、?+B build項目(不先build的話,沒有代碼提示),import 該項目,在 ViewController 中調用。

let iv = UIImageView(frame: CGRect(x: 20, y: 120, width: 280, height: 400))
iv.setImage(with: URL(string: "http://wx3.sinaimg.cn/large/9d0d09ably1fl8ilobp1sj213d1jv7e8.jpg"))
view.addSubview(iv)
image

6、像上一步私有庫升級一樣,開始升級流程


3、CocoaPods 圖片依賴

Pod 庫中的圖片、音頻、視頻,一般在路徑組件名/Assets中。
我們可以把一些圖片拖入到 Assets 文件夾內,然后在 podspec 文件中加入以下代碼:

s.resource_bundles = {
  'XGLib' => ['XGLib/Assets/*.png']
}

2、 在 Demo 工程中執行 pod update --no-repo-update 會引入圖片資源
3、 ?+B build項目(不先build的話,沒有代碼提示),import 該項目,在 ViewController 中調用。

let iv2 = UIImageView(frame: CGRect(x: 120, y: 50, width: 200, height: 200))
let privatePodBundle = Bundle(for: privatePodClass.self)
if let path = privatePodBundle.path(forResource: "eat_full.png", ofType: nil, inDirectory: "XGLib.bundle") {
    iv2.image = UIImage(contentsOfFile: path)
}
view.addSubview(iv2)

4、像上一步私有庫升級一樣,開始升級流程


4、CocoaPods 子庫

CocoaPods 有一個子庫的概念,我們在使用一個庫時,可能只需要里面一部分的功能,這時子庫就起到了作用。作為范例,我們可以看一下 pod search AFNetworking 來看一下:

-> AFNetworking (3.1.0)
   A delightful iOS and OS X networking framework.
   pod 'AFNetworking', '~> 3.1.0'
   - Homepage: https://github.com/AFNetworking/AFNetworking
   - Source:   https://github.com/AFNetworking/AFNetworking.git
   - Versions: 3.1.0, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 3.0.0-beta.3, 3.0.0-beta.2, 3.0.0-beta.1,
   2.6.3, 2.6.2, 2.6.1, 2.6.0, 2.5.4, 2.5.3, 2.5.2, 2.5.1, 2.5.0, 2.4.1, 2.4.0, 2.3.1, 2.3.0, 2.2.4,
   2.2.3, 2.2.2, 2.2.1, 2.2.0, 2.1.0, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 2.0.0-RC3, 2.0.0-RC2, 2.0.0-RC1,
   1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.1, 1.2.0, 1.1.0, 1.0.1, 1.0, 1.0RC3, 1.0RC2, 1.0RC1, 0.10.1,
   0.10.0, 0.9.2, 0.9.1, 0.9.0, 0.7.0, 0.5.1 [master repo]
   - Subspecs:
     - AFNetworking/Serialization (3.1.0)
     - AFNetworking/Security (3.1.0)
     - AFNetworking/Reachability (3.1.0)
     - AFNetworking/NSURLSession (3.1.0)
     - AFNetworking/UIKit (3.1.0)

其中的最后一部分 Subspecs 就是 AFNetworking 的子庫了,可以看到為了滿足開發者的不同需求, AFNetworking 作者貼心的為我們制作了子庫供調用。

我們也來實踐一下子庫的操作,首先整理XGLib/Classes目錄結構
[圖片上傳失敗...(image-889d58-1512367322220)]

其實修改 podsepc 文件,修改后如下

Pod::Spec.new do |s|
  s.name             = 'XGLib'
  s.version          = '0.2.0'
  s.summary          = '創建CocoaPods私有庫教程的示例工程'
  s.description      = <<-DESC
創建CocoaPods私有庫教程的示例工程,1年半前就想寫了……Orz
升級0.2.0 加入子庫,修改子庫dependency
                       DESC

  s.homepage         = 'https://coding.net/u/rxg9527/p/XGLib/git'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'ruanxiaogang' => 'rxg9527@sina.cn' }
  s.source           = { :git => 'https://git.coding.net/rxg9527/XGLib.git', :tag => s.version.to_s }
  s.social_media_url = 'https://weibo.com/rxg9527'
  s.ios.deployment_target = '8.0'
  s.source_files = 'XGLib/Classes/**/*'
  
  s.resource_bundles = {
    'XGLib' => ['XGLib/Assets/*.png']
  }
  
  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
  
  s.subspec 'ImageView' do |i|
    i.source_files = 'XGLib/Classes/ImageView/**/*'
    s.dependency 'Kingfisher', '~> 4.0'
  end

  s.subspec 'Label' do |l|
    l.source_files = 'XGLib/Classes/Label/**/*'
  end

end

這里要注意 source_filesdependency 的變化,修改好之后,像之前私有庫升級一樣,開始升級流程。

一切順利的話,現在我們執行 pod search XGLib 后,出來的搜索結果會是這樣:

-> XGLib (0.2.0)
   創建CocoaPods私有庫教程的示例工程
   pod 'XGLib', '~> 0.2.0'
   - Homepage: https://coding.net/u/rxg9527/p/XGLib/git
   - Source:   https://git.coding.net/rxg9527/XGLib.git
   - Versions: 0.2.0, 0.1.2, 0.1.1, 0.1.0, 0.0.2, 0.0.1 [CodingSpecRepo repo]
   - Subspecs:
     - XGLib/ImageView (0.2.0)
     - XGLib/Label (0.2.0)

這時我們就可以通過類似 pod 'XGLib/Label', '~>0.1' 的命令來直接引用子庫了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。