cocoaPods私有庫的建立與使用

溫特兒發表於2019-03-16

一 建立私有 pods

建立私有 Spec Repo(也就是所有私有 pod 的倉庫)

spec repopods的一個索引,是所有公開的podspodspec檔案的一個倉庫,其實就是一個部署在伺服器的Git倉庫,當你使用CocoaPods 後它會被Clone到本地的~/.cocoapods/repos這個倉庫只存放podspec檔案

步驟1:建立私有倉庫

1、在git上建立私有倉庫地址

2、在終端terminal執行命令

# pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
$ pod repo add MySpecs https://git.net/winter/MySpecs.git
複製程式碼
步驟2:建立 pod 專案工程

1、建立 Pod 專案工程

# pod lib create [Project Name] 
$ pod lib create MyLib
複製程式碼

然後按照步驟一步一步執行,如果碰到建立失敗的情況,更新 cocoaPods 再試試!

2、新增相關程式碼

├── MyLib
│   ├── Assets **存放資原始檔!!!**
│   └── Classes
│       └── ReplaceMe.m **注意存放你自己實現的庫相關程式碼!!!**
複製程式碼
├── Example
│   **就是一個樣例工程相關程式碼檔案**
複製程式碼

3、開發模式下測試 pod 開啟Example工程目錄下的podfile檔案:

#pod 'MyLib', :path => '../' # 指定路徑
pod 'MyLib', :path => '../MyLib.podspec'  # 指定podspec檔案
複製程式碼

然後在 Example 工程目錄下執行 pod update命令安裝依賴,開啟專案工程,可以看到庫檔案都被載入到Pods子專案中了 不過它們並沒有在 Pods 目錄下,而是跟測試專案一樣存在於 Development Pods/MyLib 中,這是因為我們是在本地測試,而沒有把 podspec 檔案新增到 Spec Repo 中的緣故。測試庫檔案沒有問題,接著我們需要執行第4步

4、提交Pod到程式碼倉庫,注意:不是podspec索引倉庫,是程式碼倉庫 在終端執行命令:

$ git add .
$ git commit -s -m "初始化MyLib 庫"
$ git remote add origin git@git.net:winter/MyLib.git           #新增遠端倉庫
$ git push origin master     #提交到遠端倉庫
$ git tag -m "first release" "0.1.0" #打上標籤,這個很重要
$ git push --tags     #推送tag到遠端倉庫
複製程式碼

到這裡,成功提交到遠端程式碼倉庫,MyLib Pod 庫就初步完成了程式碼實現,接下來就是重點了,將製作的私有庫放到podspec索引倉庫。

步驟3:提交podspec檔案到私有Spec Repo倉庫

1、配置podspec檔案

#
# Be sure to run `pod lib lint MyLib.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#

Pod::Spec.new do |s|
  s.name             = 'MyLib'
  s.version          = '0.1.0'
  s.summary          = 'MyLib for example'

# 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: Add long description of the pod here.
                       DESC

  s.homepage         = 'http://www.jianshu.com/u/06f42a993882'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'winter' => 'winter.wei@hey900.com' }
  s.source           = { :git => 'https://git.net/winter/MyLib.git', :tag => s.version.to_s }
  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

  s.ios.deployment_target = '8.0'

  s.source_files = 'MyLib/Classes/**/*'
  
  s.resource_bundles = {
    'MyLib' => ['MyLib/Assets/*.png']
  }

  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
end
複製程式碼

開啟MyLib工程目錄下的MyLib.podspec檔案並參考上面的說明配置好相關選項。 podspec更多配置請參考: 官方文件

2、編輯完MyLib.podspec檔案後,需要驗證一下這個MyLib.podspec檔案是否可用

$ pod lib lint
// 如果終端輸出這個資訊,就說明驗證通過,否則會提示錯誤資訊,去修改
-> MyLib (0.1.0)
MyLib passed validation.
複製程式碼

3、驗證通過,想SpecRepo提交podspec

# pod repo push [Repo名] [podspec 檔名字]
$ pod repo push MySpecs MyLib.podspec
複製程式碼

如果提交成功 終端上就會輸出一些相關pod資訊,如果不成功,則會列印一些失敗資訊,切記:失敗後,去解決問題,或者更新cocoaPods。

二 使用 cocoaPods

使用私有 pods

我們可以直接指定某一個依賴的podspec,這樣就可以使用公司的私有庫。該方案有利於使企業內部的公共專案支援CocoaPods。

pod 'MySpec', :podspec => 'https://my.com/mySpec.podspec'
複製程式碼

在建立私有 pods 遇到引用第三方framework(例如umeng)

需要注意,如果 pod repo push 出現下面的錯誤資訊:

can't get podspec validation - ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code
複製程式碼

解決辦法,可以試試:

1,pod lib lint --allow-warnings
2,解決所有的warning
3,pod repo push <repo-name> <podspec-file-name>.podspec --allow-warnings --use-libraries
複製程式碼

如果pod lib lint --allow-warnings出現一些 not find file之類的warning,一定要解決掉,否則也會出現以上錯誤資訊。

不更新 Pods

CocoaPods 在執行pod install和pod update時,會預設先更新一次pod spec索引,使用--no-repo-update引數可以禁止其做索引更新操作。

pod install --no-repo-update
pod update --no-repo-update
複製程式碼

給 Pods 新增資原始檔

podspec裡面

s.resource_bundles = {
     'MyLibrary' => ['your/path/Assets/**/*.{png,xib,plist}']
}
複製程式碼
訪問 bundle 資原始檔

一般情況下,我們自己建立的pods新增的資原始檔,使用[NSBundle mainBundle]是找不到該資源的路徑,所以,在這裡,我們需要建立一個NSBundlecategory

@implementation NSBundle (MyLibrary)

+ (NSBundle *)my_myLibraryBundle {
    return [self bundleWithURL:[self my_myLibraryBundleURL]];
}

+ (NSURL *)my_myLibraryBundleURL {
    NSBundle *bundle = [NSBundle bundleForClass:[MYSomeClass class]];
    return [bundle URLForResource:@"MyLibrary" withExtension:@"bundle"];
}
@end
複製程式碼

順便說下,MYSomeClass這個類可以是任意類名,但是有個前提,這個類必須是在你建立的library或者framework內。再說這個邏輯:先拿到最外面的 bundle,對 framework 連結方式來說是 framework 的 bundle 的根目錄,對靜態庫連結方式來說就是 target client 的 main bundle,然後再去找下面名為MyLibrary的 bundle。

圖片資源的訪問

上面我們已經可以正常訪問我們自己的 bundle,如果訪問我們自己 bundle 的圖片資源,還是一樣建立UIImagecategory

#import "UIImage+MyLibrary.h"
#import "NSBundle+MyLibrary.h"

@implementation UIImage (MyLibrary)

+ (UIImage *)my_bundleImageNamed:(NSString *)name {
    return [self my_imageNamed:name inBundle:[NSBundle my_myLibraryBundle]];
}


+ (UIImage *)my_imageNamed:(NSString *)name inBundle:(NSBundle *)bundle {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0
    return [UIImage imageNamed:name inBundle:bundle compatibleWithTraitCollection:nil];
#elif __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
    return [UIImage imageWithContentsOfFile:[bundle pathForResource:name ofType:@"png"]];
#else
    if ([UIImage respondsToSelector:@selector(imageNamed:inBundle:compatibleWithTraitCollection:)]) {
        return [UIImage imageNamed:name inBundle:bundle compatibleWithTraitCollection:nil];
    } else {
        return [UIImage imageWithContentsOfFile:[bundle pathForResource:name ofType:@"png"]];
    }
#endif
}
@end
複製程式碼

+ imageNamed:inBundle:compatibleWithTraitCollection:這個方法iOS8以後才有,所以需要條件編譯。+ imageWithContentsOfFile:沒有快取機制。

問題 Unable to find a specification for xxxxx

有時候在安裝某一第三方會出現 “Unable to find a specification for xxxxx” 這個問題,在這裡找到了解決方法,只需要把當前Pod的目錄清理一下就行了。在終端執行以下命令:

pod repo remove master  
pod setup
複製程式碼

setup(pod setup可能需要花費很長時間)成功後執行installupdate即可.

相關文章