本文由yake_099(博客)翻譯自raywenderlich赠橙,作者:Joshua Greene
原文:How to Use CocoaPods with Swift
最近關于CocoaPods有很多的議論。你可能從別的開發(fā)者那里聽到過愤炸,或者在Github的目錄中看到過期揪。如果你之前從來沒有用過,你可能會問规个,"CocoaPods到底是什么凤薛?"
它不是神秘的亞馬遜區(qū)域的部落人用手撿出來的生可可的豆莢,肯定不是诞仓!讓CocoaPods website來回答可能是最好的:
CocoaPods是Cocoa項目的依賴管理工具缤苫。它有上千個能幫你優(yōu)雅地擴充自己項目的庫。
優(yōu)雅地擴展項目聽起來很令人好奇墅拭,但是什么是依賴管理工具呢榨馁?你為什么會需要它呢?
無論你正在創(chuàng)建一個什么樣的app帜矾,你都有可能會用到別的開發(fā)者的代碼翼虫,無論是以框架的形式還是庫的形式。你可能很熟悉UIKit和Foundation,這兩個都是蘋果提供的框架屡萤。
在這個教程中珍剑,你將會:
了解為什么要和第三方庫做朋友
安裝CocoaPods
在一個starter項目中使用CocoaPods
安裝使用并修改依賴關系文件來提高用戶體驗
了解語義化版本控制
為什么庫是你的朋友
盡管你并不一定非要使用第三方庫和框架,但是它們確實能節(jié)省你很多的時間死陆,可以讓你集中注意力在優(yōu)化自己的app上招拙,而不是敲無數(shù)行的你本不需要寫的代碼唧瘾。
你可以不通過依賴管理工具來使用第三方庫和框架,我們網(wǎng)站提供了關于這種使用方式的實踐性的教程别凤。例如饰序,這是我們的Alamofire教程和SwiftyJSON教程。
不使用依賴管理工具规哪,你可以簡單地通過手動方式將每個庫添加到你的工程里面求豫。然而,這個方法有幾個缺點:
更新一個庫到新的版本可能會很麻煩诉稍,尤其是一個庫依賴于另外一個庫的情況蝠嘉,那么就必須將這幾個庫全部更新。
在項目中添加三方庫可能會需要在代碼中做一些本地的修改杯巨,這使得之后更新版本更加困難蚤告。
判斷你的app中用到的庫的當前版本也是一件困難的事,尤其是當你沒有提前記錄下來的時候服爷。
如果沒有一個中央位置來查看所有可用庫的話杜恰,查找新庫也是一件很困難的事。
CocoaPods幫你克服以上問題甚至更多別的問題仍源。它抓取庫代碼箫章,解決庫之間的依賴性問題,幫你查找并發(fā)現(xiàn)新的庫镜会,甚至以最簡便的方式為你的項目配置正確的環(huán)境。
前提
這篇教程要求你熟悉基礎的iOS和Swift開發(fā)终抽。如果你完全不了解iOS或者Swift戳表,那么在看這篇教程之前,你最好看下我們網(wǎng)站上一些其他文章或者視頻教程昼伴,然后再回來看這篇匾旭。或者是深入來學習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之后就實現(xiàn)了泥栖。
打開終端并且輸入以下命令行:
1
sudo?gem?install?cocoapods
當要求的時候輸入你的密碼。終端的輸出結果看起來應該是這樣的:
你必須使用sudo來安裝CocoaPods,但是安裝后就無需再使用了吧享。
最后魏割,在終端輸入以下命令行來完成設置:
1
pod?setup?--verbose
這個過程可能需要幾分鐘的時間,因為它將CocoaPods Master Specs repository克隆到了你電腦上的~/.cocoapods/目錄下钢颂。
verbose選項記錄下了進程運行時的進展钞它,能讓你看到進程而不是一個僵在那里的屏幕。
太好了甸陌,現(xiàn)在你開始設置來使用CocoaPods了须揣。
代碼時間!
為客戶Ice Cream Shop, Inc.開發(fā)一款App
你的首要客戶是Ice Cream Shop, Inc钱豁。他們的冰淇淋太受歡迎了以至于不能在柜臺接收用戶訂單了耻卡。他們雇傭你來做一個漂亮的iOS應用,那樣就能讓用戶在他們的iPhone上下訂單了牲尺。
你開始開發(fā)app了卵酪,并且進展得還不錯。在這里下載開始程序谤碳。
打開IceCreamShop.xcodeproj溃卡,然后運行,你會看到一個非常好吃的香草冰淇淋蜒简。
用戶應該能從這個屏幕中選擇冰淇淋的口味瘸羡,但是還不太可能,因為你還沒有完成這個功能搓茬。
從Views/Storyboards&Nibs中打開Main.storyboard來看app的布局∮汤担現(xiàn)在我們來快速整體地看一下這個app的核心,"選擇你的口味"那一屏:
PickFlavorViewController處理用戶交互卷仑,例如峻村,用戶選擇了冰淇淋的一種口味。
PickFlavorDataSource是collection view所展示的不同冰淇淋口味的數(shù)據(jù)源锡凝。
IceCreamView是一個自定義的view粘昨,可以用來展示冰淇淋圓錐形的蛋卷,并且它以Flavormodel來支撐窜锯。
ScoopCell是一個自定義的collectionviewcell张肾,它包含了一個ScoopView,這個view也是以Flavormodel來支撐的锚扎。
由于每個冰淇淋店一般都會有一些招牌口味捌浩,每個也有他們本地的風味。因此工秩,F(xiàn)lavor的實例中包含的數(shù)據(jù)需要通過web service來提供尸饺。
然而进统,這還沒有回答問題,"為什么用戶不能選擇一個冰淇淋口味浪听?"
在Controllers這個分組下面螟碎,打開PickFlavorViewController.swift,你會看到一個備用的方法:
1
2private?func?loadFlavors()?{
//?Implement?this}
哈哈迹栓,這里面沒有口味掉分,你需要實現(xiàn)它。
你可以使用NSURLConnection或NSURLSession并用你自己寫的網(wǎng)絡類克伊,這兒還有一個更簡單的辦法:Alamofire酥郭,一個開源的網(wǎng)絡庫。
你可能想就這么把它下載下來并將文件拖拽到工程里面愿吹。然而不从,那是很麻煩的方法。CocoaPods提供了更加優(yōu)雅和靈活的解決方法犁跪。
所以椿息,閑話少說...
安裝你的第一個依賴管理工具
首先你要關掉Xcode
是的,你說的對坷衍,該創(chuàng)建Podfile了寝优,在那兒你要定義工程的依賴管理。
打開終端枫耳,用 cd 命令進入包含你IceCreamShop項目的那個目錄下:
1
cd?~/Path/To/Folder/Containing/IceCreamShop
接下來乏矾,輸入下面的命令:
1
pod?init
這將為你的項目創(chuàng)建一個PodFile
輸入下面的命令行打開PodFile,并使用Xcode進行編輯:
1
open?-a?Xcode?Podfile
注意:你不能使用TextEdit來編輯Podfile迁杨,因為它有可能用圖形化的更有吸引力的typeset quotes代替standard quotes钻心,這可能導致CocoaPods不能理解并拋出錯誤,所以最好用Xcode或者別的編程文本編輯器來編輯你的Podfile仑最。
默認的podFile看起來是這樣的:
1
2
3
4
5#?Uncomment?this?line?to?define?a?global?platform?for?your?project#?platform?:ios,?'6.0'
target'IceCreamShop'do
end
target'IceCreamShopTests'do
end
將注釋的內容替換成下面的兩行:
1
platform?:ios,"8.0"use_frameworks!
這就告訴了CocoaPods--你的項目使用的是iOS 8.0,并且將使用框架來代替靜態(tài)庫帆喇。
想要在Swift中使用CocoaPods警医,你必須明確的寫出use_frameworks! 來選擇使用框架。如果你忘了寫這個坯钦,CocoaPods能檢測到你使用使用Swift CocoaPods预皇,你安裝pods的時候就會報錯。
如果你僅僅使用過Swift編程,這可能看起來有些奇怪--那是因為Podfiel實際上使用Ruby寫的婉刀。你無需為了使用CocoaPods而學習Ruby吟温,但是你要知道即使是很小的文字錯誤通常也會使CocoaPods出錯。
關于“庫”
你會看到"library"通常代指庫或框架突颊。很抱歉這個教程也在無意間混雜了這兩個概念鲁豪。實際上潘悼,當某人提到"Swift library",他們實際上指的是"Swift dynamic frameworks",因為swift不允許靜態(tài)庫爬橡。
你可能想知道治唤,"庫(library)和框架(frameworkd)和cocoaPod之間的不同之處"。
Cocoapod或者簡寫為"pod"是一種慣常的叫法糙申,用來表示使用Cocoapods工具添加庫或者框架到你的應用程序中宾添。
iOS 8引入了動態(tài)框架,這就允許了代碼柜裸、圖片和其他的東西(assets)可以被一起打包缕陕。在iOS 8之前,CocoaPods被作為靜態(tài)庫來創(chuàng)建疙挺,就是很"臃腫的"二進制文件扛邑。這意味著它包含了一些代碼說明設置(例如i386 for the simulator, armv7 for devices等),但是它們不允許包含任何資源衔统,例如圖片或資產(chǎn)鹿榜。
另外一個重要的區(qū)別是動態(tài)框架有命名空間類,而靜態(tài)庫沒有锦爵。所以舱殿,如果單個項目中不同的靜態(tài)庫里分別有一個叫做MyTestClasses的類,那么Xcode可能不能成功創(chuàng)建工程因為它會因重復的標識而導致連接失敗险掀。然而沪袭,Xcode很樂意在一個工程里的不同框架下分別有一個名字相同的類。
為什么這很重要樟氢?不像OC冈绊,標準的Swift運行時庫(runtime libraries)沒有包含在iOS中!這意味著你的框架必須包含了必要的Swift運行時庫埠啃。因此死宣,用Swift語言寫的pods必須以動態(tài)框架形式創(chuàng)建。如果蘋果允許Swift靜態(tài)庫碴开,那么使用同一個標準運行時依賴的不同庫中將會產(chǎn)生重復符號毅该。
幸運的是,CocoaPods為你做了這些事潦牛。它甚至能做到一次性包含需要的依賴關系眶掌。你所要做的就是在使用swift cocoaPods時記得在Podfile中包含use_frameworks! ,那就沒問題了巴碗。
amazing朴爬,對不對肾筐?
安裝你的第一個依賴關系
這是使用cocoapods安裝你的依賴性文件的最后的時刻蒲障。將下面的內容添加到你的Podfile里面
1
pod'Alamofire','1.2.3'
這個是告訴CocoaPods你想添加1.1.4版本的Alamofire到你的工程中作為一個依賴性文件与殃,這是寫這篇教程時的最新版本该酗。
保存并關閉podFile
現(xiàn)在你需要告訴Cocoapods為你的工程安裝依賴性文件。在終端中輸入下面的命令蚣常,但是要首先確認你還在包含了IceCreamShop和Podfile的目錄下:
1
pod?install
你會看到輸出結果與下面的類似
1
2
3
4
5Analyzing?dependencies
Downloading?dependencies
Installing?Alamofire?(1.1.4)Generating?Pods?project
Integrating?client?project
[!]?Please?close?any?current?Xcode?sessions?and?use?`IceCreamShop.xcworkspace`forthisproject?from?now?on.
使用Finder打開你的工程文件夾市咽,你看看到CocoaPods創(chuàng)建了一個新的IceCreamShop.xcworkspace文件和一個Pods文件來存儲所有的工程依賴文件。
注意:從現(xiàn)在開始抵蚊,就像命令行警告提示的施绎,你必須使用workspace文件而不是project,否則你將遇到編譯錯誤贞绳。
太棒了谷醉!你已經(jīng)使用CocoaPods添加了你的第一個依賴管理。
使用安裝好的Pods
如果已經(jīng)打開了Xcode工程冈闭,那要關閉它并打開IceCream.xcworkspace.
打開PickFlavorViewController.swift俱尼,在現(xiàn)有的導入下添加以下代碼:
1
import?Alamofire
點擊command+b進行編譯。如果一切都沒有問題萎攒,你不會收到任何編譯錯誤的遇八。
接下來,用下面的代碼代替loadFlavors()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private?func?loadFlavors()?{
let?urlString?="http://www.raywenderlich.com/downloads/Flavors.plist"http://?1
Alamofire.request(.GET,?urlString,?encoding:?.PropertyList(.XMLFormat_v1_0,?0))
.responsePropertyList?{?request,?response,?array,?errorin//?2
iflet?error?=?error?{
println("Error:?\(error)")//?3
}elseiflet?array?=?array?as??[[String:?String]]?{//?4
ifarray.isEmpty?{
println("No?flavors?were?found!")//?5
}else{
self.flavors?=?self.flavorFactory.flavorsFromDictionaryArray(array)
self.collectionView.reloadData()
self.selectFirstFlavor()
}
}
}}
下面是對這個過程的詳細描述:
1.你用Alamofire創(chuàng)建了一個get請求耍休,并下載了一個包含冰淇淋口味的plist文件刃永。
2.一般你去看查看請求是否出錯并解析錯誤。現(xiàn)在如果出錯的話你只需要打印錯誤羊精。
3.將一個AnyObject?類型數(shù)組轉換為字典數(shù)組斯够。
4.如果數(shù)組是空的,你只需要打印一個錯誤信息喧锦。
5.如果一切都OK的話读规,你就將FlavorFactory方法創(chuàng)建的包含F(xiàn)lavor對象的數(shù)組賦值給self.flavors。這是一個同事為你寫的類燃少,是用來將裝了字典類型對象的數(shù)組轉換為Flavor對象束亏。如果你喜歡的話你可以仔細看看這個工廠類,但是它對教程的其他部分不是特別重要阵具。
編譯并運行碍遍!現(xiàn)在你可以選擇一個冰淇淋口味了!
選擇裝飾物
app看起來很不錯了怔昨,但是你仍然可以進行優(yōu)化雀久。
你有沒有注意到app花費了幾秒鐘的時間來下載flavors文件宿稀?如果你的網(wǎng)絡很快的話你可能注意不到趁舀,但是用戶不會都這么幸運的。
為了讓用戶理解app現(xiàn)在正在加載什么內容祝沸,你可以顯示一個加載指示器矮烹。MBProgressHUD是個很不錯的加載指示器.并且它支持CocoaPods越庇,多么的巧合!
你需要把這個加入到你的podfile里面奉狈。你現(xiàn)在不用通過命令行打開podfile了卤唉,你可以在工作區(qū)的pods中找到它。
打開podFile并在Alamofire后面加入下面幾行:
1
pod'MBProgressHUD','~>?0.9.0'
保存文件仁期,并在終端通過pod install命令來安裝依賴文件桑驱,就像你之前做的那樣。
這次發(fā)現(xiàn)什么不同的了嗎跛蛋?對熬的,你寫出了具體的版本號~>0.9.0。這兒會發(fā)生什么呢赊级?
Cocoapods建議所有的pods都使用語義化版本號(Semantic Versioning)押框。
語義化版本號
這三個數(shù)字被定義為主要的,次要的和補丁版本號理逊。例如橡伞,版本號0.9.0會被翻譯為
當主要的(major)版本號數(shù)字增加時, 意味著你做了一些不能兼容舊版本的更新晋被。當你將pod升級到下一個主要版本時兑徘,你可能需要修復編譯錯誤,否則pod可能跟之前表現(xiàn)得不太一樣墨微。
當次要(minor)版本號增加時道媚,意味著增加了新功能,但同時兼容舊版本翘县。當你決定升級時最域,你可能需要也可能不需要新的功能,但是它不應該引起編譯錯誤或者改變現(xiàn)有的功能锈麸。
當補抖浦(patch)版本號增加的時候,這意味著做了bug修復忘伞。但是沒有沒有增加也沒有改變功能薄翅。一般來說,你會希望盡快更新補丁版本到最新的版本氓奈,以便使用最新最穩(wěn)定版本的pod翘魄。
最后,最高版本號(major>minor>patch)必須按照以上規(guī)則逐步增加舀奶,而較低的版本號必須從0開始暑竟。
需要一個例子嗎?
考慮一個當前版本為1.2.3的pod育勺。
如果做了一些不能向后兼容的改變但荤,沒有新的功能罗岖,但是修改了現(xiàn)有的bug,那么下一個版本是2.0.0
挑戰(zhàn)時間
1.如果一個pod當前版本號是2.4.6腹躁,并且做了一些修復bug的改變桑包,添加了一些向后兼容的功能,新版本應該是多少呢纺非??
答案:2.5.0
解釋:如果修改包含向后兼容的新功能哑了,次要版本號(monir)就要增加了,并且補丁版本號(patch)就要被置為0.
2.如果一個pod的當前版本是3.5.8烧颖,并且對當前的功能做了一些改變垒手,新版本應該是多少?
答案:4.0.0
解釋:如果改變修改了現(xiàn)有的功能倒信,那么這就是不向后兼容的科贬。所以,主要版本號(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宴树。
顯示進程
現(xiàn)在,回到PickFlavorViewController.swift晶疼,在其他的引用下面添加下面的內容
1
import?MBProgressHUD
下一步酒贬,在loadFlavors()后面加入以下方法
1
2
3
4
5private?func?showLoadingHUD()?{
let?hud?=?MBProgressHUD.showHUDAddedTo(contentView,?animated:true)
hud.labelText?="Loading..."}
private?func?hideLoadingHUD()?{
MBProgressHUD.hideAllHUDsForView(contentView,?animated:true)}
現(xiàn)在在loadFlavors()方法中,添加下面代碼:
1
2
3
4
5
6private?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,?errorinself.hideLoadingHUD()//?<--?And?this?line???????if?let?error?=?error?{
//...
就像方法名字所表明的翠霍,showLoadingHUD()方法會在GET請求下載時產(chǎn)生一個MBProgressHUD的實例對象锭吨,當請求結束時hideLoadingHUD()會將HUD隱藏。由于showLoadingHUD()在閉包之外所以它不需要前置代碼self寒匙。
編譯運行×闳纾現(xiàn)在你會看到一個加載指示器:
干的漂亮!用戶現(xiàn)在可以選擇他們最喜歡的冰淇淋口味了,并且在口味文件下載的時候會顯示一個正在加載的指示器埠况。
下一步
你可以從這兒下載完整的項目
恭喜你,現(xiàn)在你已經(jīng)學會了使用cocoapods的基礎棵癣,包括創(chuàng)建和修改依賴性文件辕翰,并且理解了語義化版本號。現(xiàn)在你可以準備開始在你自己的項目中使用他們了狈谊。
當然你 還可以用cocoapods做很多別的事喜命。你可以在Cocoapods官方網(wǎng)站上搜索現(xiàn)有的pods。也可以參考Cocoapods指南去學習如何使用這個杰出工具的更多細節(jié)內容河劝。但是要記住壁榕,一旦你開始使用你會好奇你曾經(jīng)是怎么不用它來進行管理的!
希望你享受閱讀這篇教程的過程我寫的時候赎瞎。