Swift iOS : 使用CocoaPods管理依賴

開發一個可用的系統,再怎麼小也須要依賴第三方庫,好比你們經常採用Alamofire這個第三方庫來訪問網絡。CocoaPods是一種很是優秀的包含依賴工程到本工程內的方式。CocoaPods爲不少開源倉庫創建了一組podspec文件列表,此podspec指定了到何處去下載代碼,以及如何和當前工程集成。node

以我本身爲例,我5月份開始研究Swift,爲學習的目的而開發了一個cnode 客戶端。最初爲了讓本身能夠集中精力於cnode自己的業務邏輯,所以決定使用了一些第三方開源庫:ios

Alamofire
ObjectMapper 
AlamofireObjectMapper
Cartography
Kingfisher 
GTMRefresh
DrawerController
SwiftIcons
PKHUD
複製代碼

有了CocoaPods,只要編寫一個Podfile,寫入這些文件和版本:git

use_frameworks!
target 'cnode' do
    pod 'Alamofire', '~> 4.4.0'
    ...
end
複製代碼

就可使用pod命令,一鍵更新所有依賴。沒有它的話,我得把這些第三方開源庫的源代碼文件複製到項目中,或者設置成git submodule。那些惱人的和依賴關係,還有編譯參數配置什麼的,均可以使用Pod而得以避免除。github

本文探討的是如何使用業已存在和久經考驗的Swift第三方Pod,以及如何建立一個本身的Pod,並把它發佈到CocoaPods倉庫內。json

使用Pod

準備CocoaPods

CocoaPods須要系統內已經安裝了ruby,若是沒有安裝,請首先安裝它。swift

可使用以下命令:xcode

sudo gem install cocoapods
複製代碼

安裝gem工具。隨即便用:ruby

pod setup --verbose
複製代碼

以後,只要pod目錄沒有更新,就儘量使用這個命令(快得多):網絡

pod install --verbose --no-repo-update
複製代碼

作配置。命令執行完畢,cocoapods就是可用的了。app

建立一個演示工程

步驟以下:

  1. 打開xcode
  2. 點擊「Create a new Xcode project」
  3. 選擇Single View App
  4. 填寫product name爲poddemo;填寫語言爲Swift
  5. 設置目錄

完成建立後,退出xcode

初始化

打開Terminal,導航到工程目錄,執行命令:

pod init
複製代碼

此命令會在目錄內建立Podfile文件。接下來使用xcode打開Podfile文件:

open -a Podfile
複製代碼

加入alamofire文件的依賴,修改後的Podfile爲:

target 'poddemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for poddemo
  pod 'Alamofire', '~> 4.4'
end
複製代碼

退出xcode,在terminal內執行命令:

pod install
複製代碼

安裝Alamofire,而且建立一個擴展名爲xcworkspace的文件。

使用Alamofire訪問HTTP

再次使用xcoce打開xcworkspace文件。編輯AppDelegate.swift爲:

import UIKit
import Alamofire
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        foo()
        window = UIWindow()
        window!.rootViewController = UIViewController()
        window!.rootViewController!.view.backgroundColor = .blue
        window!.makeKeyAndVisible()
        return true
    }
    func foo(){
        Alamofire.request("https://httpbin.org/get").responseJSON { response in
            print(response.request)
            print(response.response)
            print(response.data)
            print(response.result)
            if let JSON = response.result.value {
                print("JSON: \(JSON)")
            }
        }
    }
}
複製代碼

編譯運行,指望的輸出爲:

Optional(https://httpbin.org/get)
Optional(<NSHTTPURLResponse: 0x600000222840> { URL: https://httpbin.org/get } { status code: 200, headers {
    "Access-Control-Allow-Credentials" = true;
    "Access-Control-Allow-Origin" = "*";
    Connection = "keep-alive";
    "Content-Length" = 359;
    "Content-Type" = "application/json";
    Date = "Wed, 26 Apr 2017 01:15:59 GMT";
    Server = "gunicorn/19.7.1";
    Via = "1.1 vegur";
} })
Optional(359 bytes)
SUCCESS
JSON: {
    args =     {
    };
    headers =     {
        Accept = "*/*";
        "Accept-Encoding" = "gzip;q=1.0, compress;q=0.5";
        "Accept-Language" = "en;q=1.0";
        Connection = close;
        Host = "httpbin.org";
        "User-Agent" = "poddemo/1.0 (home.poddemo; build:1; iOS 10.2.0) Alamofire/4.4.0";
    };
    origin = "221.237.156.243";
    url = "https://httpbin.org/get";
}
複製代碼

若是輸出是對的,就說明經過CocoaPods導入的第三方庫已經成功。

建立Pod

你建立了一個庫函數,想要共享它。怎麼辦?cocoapods能夠幫忙。

準備代碼

首先,咱們建立這樣的Cocoa touch framework。添加一個swift文件(名字爲:robot.swift),內容爲:

import Foundation
public func inc(_ i : Int)->Int{return i + 1}
複製代碼

編譯經過便可。

爲此代碼建立podspec文件

想要CocoaPods幫忙分享,就得按照它的要求,編寫一個規格文件,以便說明做者,主頁,受權等信息。特別重要的是,指明源代碼的位置。

如今導航到工程目錄,執行以下命令:

touch robot.podspec
複製代碼

粘貼內容爲:

Pod::Spec.new do |s| s.name = 'robot' s.version = '0.1.0' s.summary = '一些屁話' s.description = '一些屁話' s.homepage = 'https://github.com/1000copy/robot' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { '1000copy' => '1000copy@gmail.com' } s.source = { :path => '~/github/pod/robot' } s.ios.deployment_target = '10.0' s.source_files = 'robot/*' end

其中特別重要的是s.name ,s.version , s.source ,s.source_files,沒有這些信息,發佈pod是不可能的。

最好執行下這個命令,檢查此podspec是否正確:

pod lib lint
複製代碼

引用pod

建立一個使用pod的Single View App工程,放到usepod內

cd usepod pod init

粘貼內容到Podfile

pod 'robot',:path=> '~/github/pod/robot/robot.podspec'

執行命令:

pod install --verbose --no-repo-update

引用代碼

打開usepod.workspace文件,貼入引用代碼到AppDelegate.swift內:

import UIKit
import robot
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        print(inc(41))
        return true
    }
}
複製代碼

發佈到github倉庫

文件咱們會放到github倉庫上,所以,一個github的帳號是必要的。倉庫須要建立一個release,由於podspec會引用此release。個人相關信息:

  1. github帳號是1000copy
  2. 用於存儲分享代碼的倉庫名字:robot

你須要在以下的命令和操做中,替代爲你的對應信息。首先:

  1. 建立一個倉庫,命名爲robot

  2. 在命令行內導航到你的工程目錄,執行命令以便把代碼傳遞到github倉庫內

    git init git add . git commit -m "init" git remote add origin git push -u origin master

  3. 在github上,對此倉庫作一個release,版本號設置爲0.1.0,這個號碼值會在podspec文件內引用的。

發佈到cocoapods

執行命令發佈,首先註冊你的郵件,而後推送podspec。

pod trunk register 1000copy@gmail.com
pod trunk push robot.podspec
複製代碼

注意,註冊郵件後,cocoapods會發送一個郵件給你,你點擊裏面的確認連接,便可生效。

你應該看到以下的信息反饋:

🎉  Congrats

 🚀  robot (0.1.0) successfully published
 📅  August 16th, 06:03
 🌎  https://cocoapods.org/pods/robot
 👍  Tell your friends!
複製代碼

如今,你能夠像其餘pod同樣使用robot了。

一些原理

當使用pod setup命令配置pod時,你會發現這個命令執行的時間真夠久的,這令我想要考察它到底下載了什麼東西。

我探尋了本地的存儲,發現了一些cocoapod的內部組織層面的東西。

實際上,CocoaPods把整個的Pod倉庫都拉了下來,整個巨型倉庫在~/.cocoapods內存放。我這裏的大小是:

$ du -sh ~/.cocoapods
1.5G  /Users/lcj/.cocoapods
複製代碼

每個開源庫都有多個版本,每一個版本都有一個目錄。目錄存放在此:

/Users/lcj/.cocoapods/repos/master/Specs/d/a/2/Alamofire
複製代碼

共有這多麼的版本:

$ls /Users/lcj/.cocoapods/repos/master/Specs/d/a/2/Alamofire
1.1.3   2.0.0   3.0.0-beta.2  3.2.0   4.0.0
1.1.4   2.0.0-beta.1  3.0.0-beta.3  3.2.1   4.0.1
1.1.5   2.0.0-beta.2  3.0.1   3.3.0   4.1.0
1.2.0   2.0.0-beta.3  3.1.0   3.3.1   4.2.0
1.2.1   2.0.0-beta.4  3.1.1   3.4.0   4.3.0
1.2.2   2.0.1   3.1.2   3.4.1   4.4.0
1.2.3   2.0.2   3.1.3   3.4.2   4.5.0
1.3.0   3.0.0   3.1.4   3.5.0   4.5.1
1.3.1   3.0.0-beta.1  3.1.5   3.5.1
複製代碼

其中的Alamofire版本1.1.3的podspec文件是這個:

$ls /Users/lcj/.cocoapods/repos/master/Specs/d/a/2/Alamofire/1.1.3/Alamofire.podspec.json

內容以下:

$ cat /Users/lcj/.cocoapods/repos/master/Specs/d/a/2/Alamofire/1.1.3/Alamofire.podspec.json 
{
  "name": "Alamofire",
  "version": "1.1.3",
  "license": "MIT",
  "summary": "Elegant HTTP Networking in Swift",
  "homepage": "https://github.com/Alamofire/Alamofire",
  "social_media_url": "http://twitter.com/mattt",
  "authors": {
    "Mattt Thompson": "m@mattt.me"
  },
  "source": {
    "git": "https://github.com/Alamofire/Alamofire.git",
    "tag": "1.1.3"
  },
  "platforms": {
    "ios": "8.0"
  },
  "source_files": "Source/*.swift",
  "requires_arc": true
}
複製代碼

以上分析,就能夠獲得每次CocoaPods執行install操做的過程。就是首先在本地知道對應的產品和版本的目錄,找到podspec文件,和此文件內soure屬性指定的文件源比對,若是發現有修改,就會更新最新的倉庫到本地。

至於把整個倉庫保存到客戶端是否合適,我持有保留意見。

參考:

  1. http://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/
  2. http://ishalou.com/blog/2012/10/16/how-to-create-a-cocoapods-spec-file/
  3. http://www.yudiz.com/creating-your-own-ios-framework-and-distributed-using-cocoapods/
  4. https://stackoverflow.com/questions/16020216/working-with-git-submodules-cocoapods
相關文章
相關標籤/搜索