天天看點

Cocoapods 本地私有庫和遠端私有庫的使用一 本地私有庫二 本地私有庫 - 單獨測試三 遠端私有庫CocoaPods 庫更新CocoaPods 庫依賴CocoaPods 子庫CocoaPods 資源依賴CocoaPods 圖檔依賴

本地私有庫和遠端私有庫的使用

  • 一 本地私有庫
    • 1.1 建立本地 git倉庫
    • 1.2 建立庫描述檔案
    • 1.3 導入本地私有庫
  • 二 本地私有庫 - 單獨測試
    • 方案一
    • 方案二
    • 方案三(推薦)
  • 三 遠端私有庫
    • SSH 授權
    • 添加私有遠端索引庫
    • 上傳源碼到 Git
    • 上傳 Spec 到遠端索引庫
  • CocoaPods 庫更新
  • CocoaPods 庫依賴
  • CocoaPods 子庫
  • CocoaPods 資源依賴
  • CocoaPods 圖檔依賴

一 本地私有庫

本地私有庫就是建立一個倉庫,将其存儲在本地,在本地的其他工程中直接使用。首先在桌面建立一個庫,路徑如下:

BaseTool/Classes/Network.h
BaseTool/Classes/Network.m
           

接着建立一個殼工程,現在你的目标是使用 pod 的方式,将 NetWork 這個庫內建到殼工程中。

1.1 建立本地 git倉庫

git init
git add.
git commit -m 'x'
           

1.2 建立庫描述檔案

和公開庫一樣,我們需要先建立一個 spec 檔案,指令如下:

  • 編輯 Network.podspec 檔案
Pod::Spec.new do |s|
  s.name          = "Network"
  s.version       = "0.0.1"
  s.summary       = "Network."
  s.homepage      = ""
  s.license       = 'MIT'
  s.author        = { "goodswifter" => "[email protected]" }
  s.source        = { :git => "", :tag => "#{s.version}" }
  s.source_files    = "Classes/**/*.{h,m}"
  s.platform      = :ios, "9.0" #平台及支援的最低版本
end
           

現在你的本地庫已經準備完畢了,下面就可以使用這個庫了。

1.3 導入本地私有庫

現在進入到殼工程目錄下,執行指令:

pod init
           

編輯

Podfile

檔案,如下:

platform :ios, '9.0'

target 'TestLocalPod' do
  use_frameworks!

  pod 'Network', :path => '../Network'
end
           

這裡有一個

path

關鍵字,它表示在

pod install

執行時,在指定的路徑下尋找

Network.podspec

檔案。

下面執行 pod install 指令,提示資訊如下:

Analyzing dependencies
Downloading dependencies
Installing Network (0.0.1)
Generating Pods project
Integrating client project
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
           

現在

Network

這個庫就內建到了殼工程中。

與使用遠端庫不同,本地庫的源檔案會在

Development Pods

這個目錄下,而不是

Pods

目錄,順便一提,

CocoaPods

的庫開發,一般也是這樣搭建環境的,開發完成後再修改

spec

檔案,将其

pull request

到遠端索引庫。

二 本地私有庫 - 單獨測試

方案一

首先在

LocalLib/Network/

路徑下建立一個測試工程

Example

,然後将

Classes

拖到這個測試工程中,這裡需要注意的是,

Example

Classes

是引用關系,不要

Copy

簡單粗暴的拖拽,現在

Example

工程就可以使用

Network

庫了。

方案二

Network

通過

CocoaPods

安裝在

Example

中,和安裝在殼工程一樣。

方案三(推薦)

看到這裡,是不是感覺很煩?就是想做個測試而已,還要拖來拖去,那麼繁瑣。

不要着急下面來介紹一種更快捷高效的方式,執行下面的指令:

pod lib create ADFMBase
----------------------------
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 ] # 是否需要包含一個Demo
 > 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?
 > AD
           

現在我們就有了一個 CocoaPods 的模闆工程,它的結構是這樣的:

~/Desktop/本地私有庫 » tree ADFMBase -L 2                                                                           jingshi@goodswifter
ADFMBase
├── ADFMBase
│   ├── Assets
│   └── Classes
│       └── ReplaceMe.m
├── ADFMBase.podspec
├── Example
│   ├── ADFMBase
│   ├── ADFMBase.xcodeproj
│   ├── ADFMBase.xcworkspace
│   ├── Podfile
│   ├── Podfile.lock
│   ├── Pods
│   └── Tests
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj

10 directories, 5 files
           

看吧,把源碼拖到

ReplaceMe.m

的同級目錄,執行

pod install

,就完成了本地私有庫和其測試工程。

Cocoapods 本地私有庫和遠端私有庫的使用一 本地私有庫二 本地私有庫 - 單獨測試三 遠端私有庫CocoaPods 庫更新CocoaPods 庫依賴CocoaPods 子庫CocoaPods 資源依賴CocoaPods 圖檔依賴

三 遠端私有庫

Cocoapods 本地私有庫和遠端私有庫的使用一 本地私有庫二 本地私有庫 - 單獨測試三 遠端私有庫CocoaPods 庫更新CocoaPods 庫依賴CocoaPods 子庫CocoaPods 資源依賴CocoaPods 圖檔依賴

現在使用

pod lib create

就可以友善的生成一個本地私有庫了,但是本地私有庫有一定的局限性,例如:

  • 需要在 Podfile 檔案中主動指明路徑;
  • 版本更新不容易維護;
  • 多人開發時,不友善進行合作;

遠端私有庫就可以友善的解決以上的問題,`制作遠端私有庫分為以下幾個步驟:

  1. 建立私有

    git

    遠端倉庫;
  2. 建立私有

    CocoaPods

    遠端索引庫;
  3. 建立

    Pod

    所需要的項目工程檔案,并上傳到

    git

    遠端私有庫;
  4. 驗證

    podspec

    描述檔案;
  5. 向私有

    CocoaPods

    遠端索引庫送出

    podspec

    描述檔案;
  6. 使用

    Pod

    庫;

git

倉庫的建立在此就不在贅述了,本文中我使用

github

做示例,私有

CocoaPods

遠端索引庫實際上也是一個

git

倉庫,現在我們有兩個私有庫,一個用來存放

Pod

庫的源碼,一個用來存放

Pod

庫的描述檔案。

SSH 授權

添加私有索引庫需要使用 SSH 授權,也是和 Git 倉庫一樣的,了解的同學可以跳過這一步驟,首先建立公鑰:

ssh-keygen
           

然後找到下面的檔案:

~/.ssh/id_rsa.pub
           

裡面存放的字元就是公鑰了,然後将公鑰添加

github

,連結如下:

https://github.com/settings/keys
           

添加私有遠端索引庫

現在執行

pod repo

,可以看到下面的資訊:

master
- Type: git (master)
- URL:  https://github.com/CocoaPods/Specs.git
- Path: /Users/jingshi/.cocoapods/repos/master
           

現在我們隻有一個 CocoaPods 遠端索引庫,也是官方的索引庫,下面執行:

  • 注意

    : 建立私有庫的時候一定要建立

    .gitignore

    檔案
pod repo add ADFMSpecs https://github.com/goodswifter/ADFMSpecs.git
           

此時我們的 CocoaPods 遠端索引庫就安裝好了,到下面的路徑去看一下:

~/.cocoapods/repos
           

上傳源碼到 Git

還記得 pod lib create 指令嗎?前面我們使用它來制作了本地私有庫,現在它又排上用場了,執行:

pod lib create ADFMBase
           

源碼拖到

ReplaceMe.m

的同級目錄,它現在看起來應該是這個樣子:

.
├── Assets
└── Classes
    └── Category
        ├── CALayer+PauseAimate.h
        ├── CALayer+PauseAimate.m
        ├── UIImage+XMGImage.h
        ├── UIImage+XMGImage.m
        ├── UIView+XMGLayout.h
        └── UIView+XMGLayout.m

3 directories, 6 files
           

執行 pod install,就完成了本地私有庫和其測試工程,通過測試之後,我們就可以把這個本地私有庫制作成遠端私有庫了。

首先修改

ADFMBase.podspec

檔案:

Pod::Spec.new do |s|
  s.name                  = 'ADFMBase'
  s.version               = '0.0.1'
  s.summary               = 'ADFMBase.'
  s.homepage              = 'https://github.com/goodswifter/ADFMBase'
  s.license               = { :type => 'MIT', :file => 'LICENSE' }
  s.author                = { 'goodswifter' => '[email protected]' }
  s.source                = { :git => 'https://github.com/goodswifter/ADFMBase.git', :tag => s.version.to_s }
  s.ios.deployment_target = '9.0'
  s.source_files          = 'ADFMBase/Classes/**/*'
end
           

然後使用品質檢查工具驗證一下,保證在

ADFMBase.podspec

路徑下,執行:

pod lib lint
           

根據提示修複就好了

-> ADFMBase (0.0.1)
 
ADFMBase passed validation.
           

下面執行:

git add .
git commit -m x
           

然後和遠端倉庫進行關聯:

git remote add origin https://github.com/goodswifter/ADFMBase.git
git pull origin master
git push origin master
           

最後打标簽

git tag 0.0.1
git push --tags
           

上傳 Spec 到遠端索引庫

首先執行下面的指令:

pod spec lint
           

檢驗通過後,提示如下:

然後将

podspec

檔案推到遠端私有索引庫:

pod repo push ADFMSpecs ADFMBase.podspec
           
  • 上傳報錯
pod repo push ADFMSpecs ADFMBase.podspec --allow-warnings

Validating spec
 -> ADFMBase (0.0.1)
    - WARN  | url: The URL (https://github.com/goodswifter/ADFMBasic) is not reachable.
    - NOTE  | xcodebuild:  note: Using new build system
    - NOTE  | [iOS] xcodebuild:  note: Planning build
    - NOTE  | [iOS] xcodebuild:  note: Constructing build description

Updating the `ADFMSpecs' repo

[!] /usr/bin/git -C /Users/jingshi/.cocoapods/repos/ADFMSpecs pull

Your configuration specifies to merge with the ref 'refs/heads/master'
from the remote, but no such ref was fetched.
           
  • 原因 : 建立私有庫的時候沒有建立

    .gitignore

    檔案
  • 解決辦法 : 添加

    .gitignore

    檔案即可

現在看一下本地索引庫中是否已經添加成功:

~/.cocoapods/repos
           

再看一看你的遠端索引庫中是否添加成功,現在搜尋一下本地索引檔案試試:

-> ADFMBase (0.0.1)
   ADFMBase.
   pod 'ADFMBase', '~> 0.0.1'
   - Homepage: https://github.com/goodswifter/ADFMBase
   - Source:   https://github.com/goodswifter/ADFMBase.git
   - Versions: 0.0.1 [ADFMSpecs repo]
           

現在我們可以找到自己的遠端私有庫了,下面将

Podfile

檔案改成這樣:

source 'https://github.com/goodswifter/ADPodSpecs.git'
source 'https://github.com/goodswifter/ADFMSpecs.git'

platform :ios, '9.0'

target 'Test01' do
  use_frameworks!
  
  pod 'ADCategories'
  pod 'ADFMBase'

end
           

執行 pod install,整個遠端私有庫的搭建和使用就完成了。

CocoaPods 庫更新

我們使用遠端私有庫的目的就是為了版本更新和多人開發,那麼遠端私有庫如何進行更新,更新後其他人又如何使用呢?現在我們給

ADFMBase

進行更新,給它再增加一些功能:

.
ADFMBase
│   ├── Assets
│   └── Classes
│       ├── Base
│       │   ├── Base.h
│       │   ├── Sington.h
│       │   ├── XMGConst.h
│       │   └── XMGConst.m
│       ├── Category
│       │   ├── CALayer+PauseAimate.h
│       │   ├── CALayer+PauseAimate.m
│       │   ├── UIImage+XMGImage.h
│       │   ├── UIImage+XMGImage.m
│       │   ├── UIView+XMGLayout.h
│       │   └── UIView+XMGLayout.m
│       └── Tool
│           ├── XMGAlertTool.h
│           ├── XMGAlertTool.m
│           ├── XMGCacheTool.h
│           ├── XMGCacheTool.m
│           ├── XMGDeviceMessage.h
│           ├── XMGDeviceMessage.m
│           ├── XMGNoticeLocal.h
│           └── XMGNoticeLocal.m
├── ADFMBase.podspec
├── Example
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj
           

ADFMBase

的測試工程中測試無誤後,将

ADFMBase.podspec

version

修改一下:

Pod::Spec.new do |s|
  s.name          = "ADFMBase"
  s.version       = "0.1.0"
  s.summary       = "ADFMBase."
  s.homepage      = "https://github.com/goodswifter/ADFMBase"
  s.license       = 'MIT'
  s.author        = { "goodswifter" => "[email protected]" }
  s.source        = { :git => "https://github.com/goodswifter/ADFMBase.git", :tag => "#{s.version}" }
  s.source_files    = "ADFMBase/Classes/**/*.{h,m}"
  s.platform      = :ios, "9.0" #平台及支援的最低版本
end
           

現在檢查一下私有庫是否有錯誤:

pod lib lint
           

檢查通過後就可以将

ADFMBase

0.1.0

版本推到遠端私有庫中,同時建立

0.1.0

的 Tag。

然後檢查一下

spec

檔案:

pod spec lint
           

檢查通過後,執行:

pod repo push ADFMSpecs ADFMBase.podspec
           

如果存在警告,可以執行:

pod repo push ADFMSpecs ADFMBase.podspec --allow-warnings
           

遠端私有庫和遠端私有索引庫全部更新完畢,現在我們回到使用者的視角,這個庫可以使用了嗎?還不行。

因為本地的索引檔案還沒有更新,這個源還找不到,現在進入殼工程,執行:

pod update --no-repo-update
           

ADFMBase

的 0.1.0 版本就乖乖的進入了殼工程。

CocoaPods 庫依賴

如果在我們之前的工程中, 大量使用了

ASI

架構, 大家也都知道,

ASI

架構不再維護, 需要換成别的網絡架構, 例如

AFN

, 但是現在要更換架構的話,

ASI

架構在我們的項目中已經無處不再, 這樣換的話,我們是不是很痛苦呢?

Cocoapods 本地私有庫和遠端私有庫的使用一 本地私有庫二 本地私有庫 - 單獨測試三 遠端私有庫CocoaPods 庫更新CocoaPods 庫依賴CocoaPods 子庫CocoaPods 資源依賴CocoaPods 圖檔依賴

是以我們一般在開發中都會封裝網絡請求,做到分層解耦,這樣如果換架構,隻修改網絡請求這層的封裝就可以了,那麼現在我們需要将

ASI

封裝成

Netwok

,再把

Netwok

弄到我們的

ADFMBase

裡面去,怎麼做呢?

Cocoapods 本地私有庫和遠端私有庫的使用一 本地私有庫二 本地私有庫 - 單獨測試三 遠端私有庫CocoaPods 庫更新CocoaPods 庫依賴CocoaPods 子庫CocoaPods 資源依賴CocoaPods 圖檔依賴

現在先将

Network

拖到

ADFMBase

的 Classes

目錄中,因為

ADFMBase

的測試工程沒有

AFN

,是以

Network` 肯定是會報錯了,不要慌,下面我們修改 spec 檔案:

Pod::Spec.new do |s|
  s.name          = "ADFMBase"
  s.version       = "0.3.0"
  s.summary       = "ADFMBase."
  s.homepage      = "https://github.com/goodswifter/ADFMBase"
  s.license       = 'MIT'
  s.author        = { "goodswifter" => "[email protected]" }
  s.source        = { :git => "https://github.com/goodswifter/ADFMBase.git", :tag => "#{s.version}" }
  s.source_files    = "ADFMBase/Classes/**/*.{h,m}"
  s.platform      = :ios, "9.0" #平台及支援的最低版本
  s.dependency 'AFNetworking'
end
           

dependency

指明了這個庫的依賴,改好之後

pod install

AFN

就安裝到了

ADFMBase

的測試工程中,現在就可以使用 AFN 進行網絡請求封裝,直接

import

就可以了

現在再進行一次遠端私有庫更新,整個依賴就做好了

CocoaPods 子庫

現在我們實作了一個完整的遠端私有庫,可以更新,依賴其他的庫,提供給其他人使用,但是現在還有一點問題,其他人如果要用我們的庫,就需要把

ADFMBase

完整的克隆過來,但是他可能隻需要

ADFMBase

裡面的

Network

,其他的擴充、工具等并不想使用,也不想導入過來,怎麼辦?有兩種方案:

  • Network

    剝離出來,再單獨建一個遠端私有庫;
  • 使用子庫遷出

    Network

第一種方案大家已經知道了,就是上面的一大篇,麻煩不說,而且東西一多起來,這裡一個庫,那裡一個庫,也不容易管理,是以,下面就有請子庫隆重登場。

注意

Subspecs

這裡,它就是本節要講的東西,首先将

spec

改成下面這樣:

Pod::Spec.new do |s|
  s.name          = "ADFMBase"
  s.version       = "0.4.0"
  s.summary       = "ADFMBase."
  s.homepage      = "https://github.com/goodswifter/ADFMBase"
  s.license       = 'MIT'
  s.author        = { "goodswifter" => "[email protected]" }
  s.source        = { :git => "https://github.com/goodswifter/ADFMBase.git", :tag => "#{s.version}" }
  # s.source_files    = "ADFMBase/Classes/**/*.{h,m}"

  # 子庫
  s.subspec 'Base' do |b|
    b.source_files = 'ADFMBase/Classes/Base/**/*'
  end

  s.subspec 'Category' do |c|
    c.source_files = 'ADFMBase/Classes/Category/**/*'
  end

  s.subspec 'Network' do |n|
    n.source_files = 'ADFMBase/Classes/Network/**/*'
    n.dependency 'AFNetworking'
  end

  s.subspec 'Tool' do |t|
    t.source_files = 'ADFMBase/Classes/Tool/**/*'
  end

  s.platform      = :ios, "9.0" #平台及支援的最低版本
end
           

如果依賴的架構隻有某一個子庫,使用,要将依賴放到子庫的spec中

在這裡要注意 source_files 和 dependency 以及版本的變化,修改完成推到遠端索引庫,并打好 0.4.0 的分支,執行:

pod spec lint
pod repo push ADFMSpecs ADFMBase.podspec
pod update --no-repo-update
pod search ADFMBase
           

CocoaPods 資源依賴

現在我們可以讓一個庫依賴另外一個庫,但是看下面這段代碼:

這段代碼讀取了一個 XIB 檔案,這個庫的結構是這樣的:

.
├── Assets
└── Classes
    ├── Controller
    │   ├── ADNavVC.h
    │   ├── ADNavVC.m
    │   ├── ADTabBarVC.h
    │   └── ADTabBarVC.m
    └── View
        ├── ADMiddleView.h
        ├── ADMiddleView.m
        ├── ADMiddleView.xib
        ├── ADNavBar.h
        ├── ADNavBar.m
        ├── ADTabBar.h
        └── ADTabBar.m
           

們可以成功調用這個方法嗎?不能,因為

ADMiddleView.xib

這個檔案的

Target

MainModule

,使用

CocoaPods

把這個庫安裝到我們項目後,

XIB

檔案即使在,也是在

Pods

這個工程裡,而我們在殼工程中使用

ADMiddleView.xib

,也是必然找不到的。

下面我們把模闆庫的測試工程編譯一下,打開

Products

目錄下的

.app

檔案,看一下檔案結構:

.
├── ADFMMain_Example
├── Assets.car
├── Base.lproj
│   └── LaunchScreen.storyboardc
├── Frameworks
│   ├── ADFMMain.framework
│   │   ├── ADFMMain
│   │   ├── ADFMMain.bundle
│   │   │   ├── Info.plist
│   │   │   ├── _CodeSignature
│   │   │   ├── [email protected]
│   │   │   ├── [email protected]
│   │   ├── ADMiddleView.nib
│   │   ├── Info.plist
│   │   └── _CodeSignature
├── Info.plist
├── PkgInfo
├── _CodeSignature
└── en.lproj
           

通過路徑可以看到,

ADMiddleView.nib

是在:

mainBundle/Frameworks/ADFMMain.framework/ADMiddleView.nib
           

這個路徑下面,是以

mainBundle

中肯定是找不到資源檔案的,那麼該如何修改呢?

+ (instancetype)middleView {
    NSBundle *currentBundle = [NSBundle bundleForClass:self];
    
    return [[currentBundle loadNibNamed:NSStringFromClass(self) owner:nil options:nil] firstObject];
}
           

這部分的重點就是

[NSBundle bundleForClass:self]

這個方法。

CocoaPods 圖檔依賴

上面我們講到了怎樣使用 Pod 庫裡面的 XIB 檔案,但是還有其他資源檔案,例如圖檔、音頻、視訊,圖檔我們一般是放在 Assets.xcassets,但是 Pod 庫并沒有對應的路徑,那麼它所需要的圖檔放在哪裡,已經如何使用呢?現在使用 pod lib create 指令建立一個 Pod 庫,進入以下路徑:

把一些圖檔拖入到

Assets

檔案夾内,然後在

podspec

檔案中加入以下代碼

s.resource_bundles = {
  '元件名' => ['元件名/Assets/*.png'] //隻加載 png 檔案
  # '元件名' => ['元件名/Assets/*'] //加載所有檔案
}
           

然後執行

pod install

Pod

庫中就出現了之前拖入

Assets

檔案夾的圖檔,但是現在還不能使用,我們先來看一下打包以後這些圖檔的路徑:

.
├── ADFMMain_Example
├── Assets.car
├── Base.lproj
│   └── LaunchScreen.storyboardc
├── Frameworks
│   ├── ADFMMain.framework
│   │   ├── ADFMMain
│   │   ├── ADFMMain.bundle
│   │   │   ├── Info.plist
│   │   │   ├── _CodeSignature
│   │   │   ├── [email protected]
│   │   │   ├── [email protected]
│   │   ├── ADMiddleView.nib
│   │   ├── Info.plist
│   │   └── _CodeSignature
├── Info.plist
├── PkgInfo
├── _CodeSignature
└── en.lproj
           

可以看到,打包後的路徑在:

mainBundle/Frameworks/ADFMMain.framework/ADFMMain.bundle
           

複制代碼這個路徑下面,而代碼中的

[UIImage imageNamed:@"xxx.png"]

讀取的是

mainBundle

下的資源檔案,是以還是找不到的,那麼這時使用圖檔,應該将代碼改成這樣:

NSInteger scale = [[UIScreen mainScreen] scale];
NSBundle *currentBundle = [NSBundle bundleForClass:self];
NSString *fullImageName = [NSString stringWithFormat:@"%@@%zdx", imageName, scale];
NSString *currentBundleName = [currentBundle.infoDictionary[@"CFBundleName"] stringByAppendingString:@".bundle"];
NSString *path = [currentBundle pathForResource:fullImageName ofType:@"png" inDirectory:currentBundleName];
path ? [UIImage imageWithContentsOfFile:path] : nil;
           

這裡需要注意的是,檔案名需要完整。以上是在代碼中加載圖檔,如果是在

XIB

中加載圖檔,應該怎樣做呢?那麼再看一下上面的目錄結構,

ADFMMain.nib

ADFMMain.bundle

處于同一個目錄,我們可以在

ADFMMain.xib

中通過相對路徑,使用

ADFMMain.bundle

裡面的圖檔,是以在 XIB 中,圖檔名應該是這樣的:

ADFMMain.bundle/[email protected]
           

繼續閱讀