怎樣在Swift中使用CocoaPods

jopen 9年前發布 | 49K 次閱讀 Swift Apple Swift開發

怎樣在Swift中使用CocoaPods

本文由yake_099(博客)翻譯自raywenderlich,作者:Joshua Greene

原文:How to Use CocoaPods with Swift


最近關于CocoaPods有很多的議論。你可能從別的開發者那里聽到過,或者在Github的目錄中看到過。如果你之前從來沒有用過,你可能會問,"CocoaPods到底是什么?"

它不是神秘的亞馬遜區域的部落人用手撿出來的生可可的豆莢,肯定不是!讓CocoaPods website來回答可能是最好的:

CocoaPods是Cocoa項目的依賴管理工具。它有上千個能幫你優雅地擴充自己項目的庫。

優雅地擴展項目聽起來很令人好奇,但是什么是依賴管理工具呢?你為什么會需要它呢?

無論你正在創建一個什么樣的app,你都有可能會用到別的開發者的代碼,無論是以框架的形式還是庫的形式。你可能很熟悉UIKit和Foundation,這兩個都是蘋果提供的框架。

在這個教程中,你將會:

  • 了解為什么要和第三方庫做朋友

  • 安裝CocoaPods

  • 在一個starter項目中使用CocoaPods

  • 安裝使用并修改依賴關系文件來提高用戶體驗

  • 了解語義化版本控制

為什么庫是你的朋友

盡管你并不一定非要使用第三方庫和框架,但是它們確實能節省你很多的時間,可以讓你集中注意力在優化自己的app上,而不是敲無數行的你本不需要寫的代碼。

你可以不通過依賴管理工具來使用第三方庫和框架,我們網站提供了關于這種使用方式的實踐性的教程。例如,這是我們的?Alamofire教程?和?SwiftyJSON教程

不使用依賴管理工具,你可以簡單地通過手動方式將每個庫添加到你的工程里面。然而,這個方法有幾個缺點:

  • 更新一個庫到新的版本可能會很麻煩,尤其是一個庫依賴于另外一個庫的情況,那么就必須將這幾個庫全部更新。

  • 在項目中添加三方庫可能會需要在代碼中做一些本地的修改,這使得之后更新版本更加困難。

  • 判斷你的app中用到的庫的當前版本也是一件困難的事,尤其是當你沒有提前記錄下來的時候。

  • 如果沒有一個中央位置來查看所有可用庫的話,查找新庫也是一件很困難的事。

CocoaPods幫你克服以上問題甚至更多別的問題。它抓取庫代碼,解決庫之間的依賴性問題,幫你查找并發現新的庫,甚至以最簡便的方式為你的項目配置正確的環境。

前提

這篇教程要求你熟悉基礎的iOS和Swift開發。如果你完全不了解iOS或者Swift,那么在看這篇教程之前,你最好看下我們網站上一些其他?文章?或者?視頻?教程,然后再回來看這篇。或者是深入來學習iOS Apprentice

這篇教程也包含了使用了Core Graphics的一些類。了解Core Graphics是一件有利的事,但不是必須的。如果你想學習更多關于Core Graphics的知識,請閱讀我們的?Modern Core Graphics With Swift?系列。

這篇教程要求Xcode 6.3和Swift 1.2.

開始

首先你需要安裝CocoaPods。幸運的是,CocoaPods被建立在Ruby上,而最近的Mac OS X版本帶有Ruby。這自從OS X 10.7之后就實現了。

打開終端并且輸入以下命令行:

sudo?gem?install?cocoapods

當要求的時候輸入你的密碼。終端的輸出結果看起來應該是這樣的:

怎樣在Swift中使用CocoaPods

你必須使用sudo來安裝CocoaPods,但是安裝后就無需再使用了。

最后,在終端輸入以下命令行來完成設置:

pod?setup?--verbose

這個過程可能需要幾分鐘的時間,因為它將?CocoaPods Master Specs repository?克隆到了你電腦上的~/.cocoapods/目錄下。

verbose選項記錄下了進程運行時的進展,能讓你看到進程而不是一個僵在那里的屏幕。

太好了,現在你開始設置來使用CocoaPods了。

怎樣在Swift中使用CocoaPods

代碼時間!

為客戶Ice Cream Shop, Inc.開發一款App

你的首要客戶是Ice Cream Shop, Inc。他們的冰淇淋太受歡迎了以至于不能在柜臺接收用戶訂單了。他們雇傭你來做一個漂亮的iOS應用,那樣就能讓用戶在他們的iPhone上下訂單了。

你開始開發app了,并且進展得還不錯。在這里?下載開始程序?。

打開IceCreamShop.xcodeproj,然后運行,你會看到一個非常好吃的香草冰淇淋。

怎樣在Swift中使用CocoaPods

用戶應該能從這個屏幕中選擇冰淇淋的口味,但是還不太可能,因為你還沒有完成這個功能。

從Views/Storyboards&Nibs中打開Main.storyboard來看app的布局。現在我們來快速整體地看一下這個app的核心,"選擇你的口味"那一屏:

怎樣在Swift中使用CocoaPods

  • PickFlavorViewController處理用戶交互,例如,用戶選擇了冰淇淋的一種口味。

  • PickFlavorDataSource是collection view所展示的不同冰淇淋口味的數據源。

  • IceCreamView是一個自定義的view,可以用來展示冰淇淋圓錐形的蛋卷,并且它以Flavor?model來支撐。

  • ScoopCell是一個自定義的collectionviewcell,它包含了一個ScoopView,這個view也是以Flavor?model來支撐的。

由于每個冰淇淋店一般都會有一些招牌口味,每個也有他們本地的風味。因此,Flavor的實例中包含的數據需要通過web service來提供。

然而,這還沒有回答問題,"為什么用戶不能選擇一個冰淇淋口味?"

在Controllers這個分組下面,打開PickFlavorViewController.swift,你會看到一個備用的方法:

private?func?loadFlavors()?{
??//?Implement?this
}

哈哈,這里面沒有口味,你需要實現它。

你可以使用NSURLConnection或?NSURLSession?并用你自己寫的網絡類,這兒還有一個更簡單的辦法:Alamofire,一個開源的網絡庫。

你可能想就這么把它下載下來并將文件拖拽到工程里面。然而,那是很麻煩的方法。CocoaPods提供了更加優雅和靈活的解決方法。

所以,閑話少說...

怎樣在Swift中使用CocoaPods

安裝你的第一個依賴管理工具

首先你要關掉Xcode

是的,你說的對,該創建Podfile了,在那兒你要定義工程的依賴管理。

打開終端,用 cd 命令進入包含你IceCreamShop項目的那個目錄下:

cd?~/Path/To/Folder/Containing/IceCreamShop

接下來,輸入下面的命令:

pod?init

這將為你的項目創建一個?PodFile

輸入下面的命令行打開PodFile,并使用Xcode進行編輯:

open?-a?Xcode?Podfile

注意:你不能使用TextEdit來編輯Podfile,因為它有可能用圖形化的更有吸引力的typeset quotes代替standard quotes,這可能導致CocoaPods不能理解并拋出錯誤,所以最好用Xcode或者別的編程文本編輯器來編輯你的Podfile。

默認的podFile看起來是這樣的:

#?Uncomment?this?line?to?define?a?global?platform?for?your?project
#?platform?:ios,?'6.0'
?
target?'IceCreamShop'?do
?
end
?
target?'IceCreamShopTests'?do
?
end

將注釋的內容替換成下面的兩行:

platform?:ios,?"8.0"
use_frameworks!

這就告訴了CocoaPods--你的項目使用的是iOS 8.0,并且將使用框架來代替靜態庫。

想要在Swift中使用CocoaPods,你必須明確的寫出use_frameworks! 來選擇使用框架。如果你忘了寫這個,CocoaPods能檢測到你使用使用Swift CocoaPods,你安裝pods的時候就會報錯。

如果你僅僅使用過Swift編程,這可能看起來有些奇怪--那是因為Podfiel實際上使用Ruby寫的。你無需為了使用CocoaPods而學習Ruby,但是你要知道即使是很小的文字錯誤通常也會使CocoaPods出錯。

關于“庫”

你會看到"library"通常代指庫或框架。很抱歉這個教程也在無意間混雜了這兩個概念。實際上,當某人提到"Swift library",他們實際上指的是"Swift dynamic frameworks",因為swift不允許靜態庫。

你可能想知道,"庫(library)和框架(frameworkd)和cocoaPod之間的不同之處"。
Cocoapod或者簡寫為"pod"是一種慣常的叫法,用來表示使用Cocoapods工具添加庫或者框架到你的應用程序中。

iOS 8引入了動態框架,這就允許了代碼、圖片和其他的東西(assets)可以被一起打包。在iOS 8之前,CocoaPods被作為靜態庫來創建,就是很"臃腫的"二進制文件。這意味著它包含了一些代碼說明設置(例如i386 for the simulator, armv7 for devices等),但是它們不允許包含任何資源,例如圖片或資產。

另外一個重要的區別是動態框架有命名空間類,而靜態庫沒有。所以,如果單個項目中不同的靜態庫里分別有一個叫做MyTestClasses的類,那么Xcode可能不能成功創建工程因為它會因重復的標識而導致連接失敗。然而,Xcode很樂意在一個工程里的不同框架下分別有一個名字相同的類。

為什么這很重要?不像OC,標準的Swift運行時庫(runtime libraries)沒有包含在iOS中!這意味著你的框架必須包含了必要的Swift運行時庫。因此,用Swift語言寫的pods必須以動態框架形式創建。如果蘋果允許Swift靜態庫,那么使用同一個標準運行時依賴的不同庫中將會產生重復符號。

幸運的是,CocoaPods為你做了這些事。它甚至能做到一次性包含需要的依賴關系。你所要做的就是在使用swift cocoaPods時記得在Podfile中包含use_frameworks! ,那就沒問題了。

amazing,對不對?

安裝你的第一個依賴關系

這是使用cocoapods安裝你的依賴性文件的最后的時刻。將下面的內容添加到你的Podfile里面

pod?'Alamofire',?'1.2.3'

這個是告訴CocoaPods你想添加1.1.4版本的Alamofire到你的工程中作為一個依賴性文件,這是寫這篇教程時的最新版本。

保存并關閉podFile

現在你需要告訴Cocoapods為你的工程安裝依賴性文件。在終端中輸入下面的命令,但是要首先確認你還在包含了IceCreamShop和Podfile的目錄下:

pod?install

你會看到輸出結果與下面的類似

Analyzing?dependencies
Downloading?dependencies
Installing?Alamofire?(1.1.4)
Generating?Pods?project
Integrating?client?project
[!]?Please?close?any?current?Xcode?sessions?and?use?`IceCreamShop.xcworkspace`?for?this?project?from?now?on.

使用Finder打開你的工程文件夾,你看看到CocoaPods創建了一個新的IceCreamShop.xcworkspace文件和一個Pods文件來存儲所有的工程依賴文件。

注意:從現在開始,就像命令行警告提示的,你必須使用workspace文件而不是project,否則你將遇到編譯錯誤。

太棒了!你已經使用CocoaPods添加了你的第一個依賴管理。

怎樣在Swift中使用CocoaPods

使用安裝好的Pods

如果已經打開了Xcode工程,那要關閉它并打開IceCream.xcworkspace.

打開PickFlavorViewController.swift,在現有的導入下添加以下代碼:

import?Alamofire

點擊command+b進行編譯。如果一切都沒有問題,你不會收到任何編譯錯誤的。

接下來,用下面的代碼代替loadFlavors()方法

private?func?loadFlavors()?{
??let?urlString?=?"http://www.raywenderlich.com/downloads/Flavors.plist"
?
??//?1
??Alamofire.request(.GET,?urlString,?encoding:?.PropertyList(.XMLFormat_v1_0,?0))
????.responsePropertyList?{?request,?response,?array,?error?in
?
????//?2
????if?let?error?=?error?{
??????println("Error:?\(error)")
?
????//?3
????}?else?if?let?array?=?array?as??[[String:?String]]?{
?
??????//?4
??????if?array.isEmpty?{
????????println("No?flavors?were?found!")
?
??????//?5
??????}?else?{
????????self.flavors?=?self.flavorFactory.flavorsFromDictionaryArray(array)
????????self.collectionView.reloadData()
????????self.selectFirstFlavor()
??????}
????}
??}
}

下面是對這個過程的詳細描述:

1.你用Alamofire創建了一個get請求,并下載了一個包含冰淇淋口味的plist文件。

2.一般你去看查看請求是否出錯并解析錯誤。現在如果出錯的話你只需要打印錯誤。

3.將一個AnyObject?類型數組轉換為字典數組。

4.如果數組是空的,你只需要打印一個錯誤信息。

5.如果一切都OK的話,你就將FlavorFactory方法創建的包含Flavor對象的數組賦值給self.flavors。這是一個同事為你寫的類,是用來將裝了字典類型對象的數組轉換為Flavor對象。如果你喜歡的話你可以仔細看看這個工廠類,但是它對教程的其他部分不是特別重要。

編譯并運行!現在你可以選擇一個冰淇淋口味了!

怎樣在Swift中使用CocoaPods

選擇裝飾物

app看起來很不錯了,但是你仍然可以進行優化。

你有沒有注意到app花費了幾秒鐘的時間來下載flavors文件?如果你的網絡很快的話你可能注意不到,但是用戶不會都這么幸運的。

為了讓用戶理解app現在正在加載什么內容,你可以顯示一個加載指示器。MBProgressHUD?是個很不錯的加載指示器.并且它支持CocoaPods,多么的巧合!

你需要把這個加入到你的podfile里面。你現在不用通過命令行打開podfile了,你可以在工作區的pods中找到它。

怎樣在Swift中使用CocoaPods

打開podFile并在Alamofire后面加入下面幾行:

pod?'MBProgressHUD',?'~>?0.9.0'

保存文件,并在終端通過pod install命令來安裝依賴文件,就像你之前做的那樣。

這次發現什么不同的了嗎?對,你寫出了具體的版本號~>0.9.0。這兒會發生什么呢?

Cocoapods建議所有的pods都使用語義化版本號(?Semantic Versioning)。

語義化版本號

這三個數字被定義為主要的,次要的和補丁版本號。例如,版本號0.9.0會被翻譯為

怎樣在Swift中使用CocoaPods

當主要的(major)版本號數字增加時, 意味著你做了一些不能兼容舊版本的更新。當你將pod升級到下一個主要版本時,你可能需要修復編譯錯誤,否則pod可能跟之前表現得不太一樣。

當次要(minor)版本號增加時,意味著增加了新功能,但同時兼容舊版本。當你決定升級時,你可能需要也可能不需要新的功能,但是它不應該引起編譯錯誤或者改變現有的功能。

當補丁(patch)版本號增加的時候,這意味著做了bug修復。但是沒有沒有增加也沒有改變功能。一般來說,你會希望盡快更新補丁版本到最新的版本,以便使用最新最穩定版本的pod。

最后,最高版本號(major>minor>patch)必須按照以上規則逐步增加,而較低的版本號必須從0開始。

需要一個例子嗎?

考慮一個當前版本為1.2.3的pod。

如果做了一些不能向后兼容的改變,沒有新的功能,但是修改了現有的bug,那么下一個版本是2.0.0

挑戰時間

1.如果一個pod當前版本號是2.4.6,并且做了一些修復bug的改變,添加了一些向后兼容的功能,新版本應該是多少呢??

答案:2.5.0

解釋:如果修改包含向后兼容的新功能,次要版本號(monir)就要增加了,并且補丁版本號(patch)就要被置為0.

2.如果一個pod的當前版本是3.5.8,并且對當前的功能做了一些改變,新版本應該是多少?

答案:4.0.0

解釋:如果改變修改了現有的功能,那么這就是不向后兼容的。所以,主要版本號(major)必須增加,而次要版本和補充版本置為0.

3.如果一個pod的向前版本號是10.20.30并且只修復了一些bug,那么新版本號應該是多少?

答案:10.20.31

解釋:如果只修復了bug,補充版本號(patch)就要增加了。

說了這么多,這兒有一個例外:

如果一個pod的版本低于1.0.0,這就被認為是測試版,次要版本號(minor)增加可能意味著向后兼容的改變。

所以在MBProgressHUB中使用~>0.9.0意味著你需要安裝大于或者等于0.9.0但是小于0.10.0的最新的版本.

這就保證了你在安裝pod的時候獲得了最新的bug修復,但是不會意外的拉去向后兼容的改變。這兒還有一些其他的可用操作。具體的列表,請看Podfile Syntax Reference

顯示進程

現在,回到PickFlavorViewController.swift,在其他的引用下面添加下面的內容

import?MBProgressHUD

下一步,在loadFlavors()后面加入以下方法

private?func?showLoadingHUD()?{
??let?hud?=?MBProgressHUD.showHUDAddedTo(contentView,?animated:?true)
??hud.labelText?=?"Loading..."
}
?
private?func?hideLoadingHUD()?{
??MBProgressHUD.hideAllHUDsForView(contentView,?animated:?true)
}

現在在loadFlavors()方法中,添加下面代碼:

private?func?loadFlavors()?{
????let?urlString?=?"http://www.raywenderlich.com/downloads/Flavors.plist"
?
????showLoadingHUD()??//?<--?Add?this?line ????Alamofire.request(.GET,?urlString,?encoding:?.PropertyList(.XMLFormat_v1_0,?0)) ??????.responsePropertyList?{?request,?response,?array,?error?in ? ??????self.hideLoadingHUD()??//?<--?And?this?line ? ??????if?let?error?=?error?{ ??//...

就像方法名字所表明的,showLoadingHUD()方法會在GET請求下載時產生一個MBProgressHUD的實例對象,當請求結束時hideLoadingHUD()會將HUD隱藏。由于showLoadingHUD()在閉包之外所以它不需要前置代碼self。

編譯運行。現在你會看到一個加載指示器:

怎樣在Swift中使用CocoaPods

干的漂亮!用戶現在可以選擇他們最喜歡的冰淇淋口味了,并且在口味文件下載的時候會顯示一個正在加載的指示器。

下一步

你可以從這兒 下載完整的項目

恭喜你,現在你已經學會了使用cocoapods的基礎,包括創建和修改依賴性文件,并且理解了語義化版本號。現在你可以準備開始在你自己的項目中使用他們了。

當然你 還可以用cocoapods做很多別的事。你可以在Cocoapods官方網站上搜索現有的pods。也可以參考Cocoapods指南去學習如何使用這個杰出工具的更多細節內容。但是要記住,一旦你開始使用你會好奇你曾經是怎么不用它來進行管理的!

希望你享受閱讀這篇教程的過程我寫的時候。

來源:Ray Wenderlich

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!