想說既然打定主意想玩一下iOS上的開發, 就從一些最夯的東西開始, 使用Swift自是不用說(另一個原因是我還是不喜歡看Objective-C), 另外想說最近FRP (Functional Reactive Programming), 搭配Swift也剛剛好, 因此想說就從ReactiveCocoa來上手吧….

似乎在iOS流行著用CocoaPods來做相依性管理(dependency management), 如果用Objective-C, ReactiveCocoa 2.x版就已經夠用了, 用CocoaPads也非常簡單沒啥問題, 只要在Podfile裡加入即可:

pod ‘ReactiveCocoa’, ’~> 2.4.4’

但根據下面這篇

“MVVM, SWIFT AND REACTIVECOCOA - IT’S ALL GOOD!”

但2.x跟swift不搭,如果要在Swift上使用2.x版的ReactiveCocoa,就必須要使用這個分支 但使用這個分支的話, 就沒辦法透過CococaPods來管理了

不過所幸, ReactiveCocoa打算在3.0之後直接支援swift, 那如果, 把pod改成:

pod 'ReactiveCocoa’, ’~> 3.0’

不就應該搞定了嘛?代誌當然不是我這笨蛋想的那麼簡單, 首先, 把這些library含進swift project裡要使用dynamic frameworks而不是static library, 這在iOS是iOS8之後才支援的, 而CocoaPods要到0.36才有支援, 針對這個, 就必須要在Podfile裡加上一行

use_frameworks!

但…這樣還沒結束, CocoaPods的repository裡的ReactiveCocoa 3的版本其實只有到 3.0.0 alpha 1, 那是相當早期的版本, swift版本的ReactiveCocoa正在積極開發中, 因此這版本舊到如果是用最新的XCode是會編譯不過的, 問題會出在LlamaKit, LlamaKit版本在CocoaPods上是0.1.0, 但最新的則是0.6.0, 在最新版已經解掉這問題了

那這樣表示我得放棄方便相依管理系統轉向手動了嗎? 還好還有Carthage, 這個跟ReactiveCocoa都是同一個作者做的(好像是Github的員工), Carthage跟CocoaPods的概念不同, CocoaPods的採取的是傳統的中心化的管理, 但Carthage的套件則沒有中心的repository, 而是分散在各個git(github project)中, 相對來說比較簡單單純(感覺就像做git clone後再用xcodebuild去build成framework而已), 不過我在這反而碰到更多的陷阱

像CocoaPods的Podfile一樣, Carthage也有一個設定檔Cartfile, Cartfile的內容跟Podfile很像, 像是要加入ReactiveCocoa 3的話只要加入一行:

github “ReactiveCocoa/ReactiveCocoa” ~> 3.0

這邊跟CocoaPods不一樣的地方是, 它的版本管理部分完全靠git, 因此這行它會去github抓tag是v3.0的最新版本(以現在來說最新的是v3.0-beta.1), 它也可以接某個git branch, 比如說github “ReactiveCocoa/ReactiveCocoa” “swift-development”, 寫好Cartfile後只要執行:

carthage update

它應該…理論上啦…就會把相關的porject抓回來build成framework, 然後去General settings把這些framework”手動”含進來(它不像CocoaPod那麼自動):

不過, 我為什麼說"理論上", 原因是我又碰到問題了!在build到LlamaKit(又是它)時我發生以下的問題!

“project has no shared schemes” error

所以ReactiveCocoa並沒被build出來(X的)

看來幾個對這issue的討論, 似乎是執行xcodebuild -list過久timeout, 導致抓不到build target, 而根據commit的log, 0.6.5似乎解決了這問題, 我原本是用brew install carthage裝的, 所以版本是0.6.4, 所以有抓了package來裝0.6.5

裝了0.6.5就解決了嗎?我這笨蛋真的想的太簡單啦!一樣有問題啦!…沒解嗎? 開了那個commit來看, 原來它所謂的解不過是延長timeout並且把錯誤訊息改成讓人家知道那是因為timeout而不是沒有shared scheme

那怎辦, 該回歸手動了嗎?不!要追根究柢!,但看半天好像也沒啥招, 死馬當活馬醫? cd進去Carthage/Checkouts/ReactiveCocoa/目錄, 發現也有Cartfile, 那就在這邊也來一次carthage update吧….結果有沒問題?有!狀況出現在底下這兩行(Cartfile.private):

github “Quick/Quick” “master” github “Quick/Nimble” “master”

這次它說沒"master"這個object, 但carthage不是有支援用branch name嗎?不管, 拿掉試試, 把"master"都拿掉後, 就成功在這邊build過ReactiveCocoa, 那回到上一層還會出現xcode -list發生timeout的問題嗎?回到上層目錄再試, 正常了, 一次通過! X…該不會是這問題吧?這是什麼情形….那我把github “ReactiveCocoa/ReactiveCocoa” ~> 3.0 改成github “ReactiveCocoa/ReactiveCocoa” “swift-development"呢?果不期然!!一樣的問題!!不是應該有支援用branch name嗎?

(寫太多很累了, 省略發現原因的過程…底下直接寫原因)


原因是我電腦裡面有兩個git, 一個是git 1.7的版本, 一個是macos 10.10幫我裝的git, 那個則是2.3.2的, 因為路徑設的問題, 一直都抓到1.7的版本, carthage認branch name是靠git revparse, 大概1.7跟carthage不相容, 導致了這問題, 改成2.3.2之後….一路順暢….看來來去回報一下好了

但問題不是到這邊為止, carthage還是一個很新的東西, 還有一些像是Facebook/pop並不支援carthage, 現在還沒辦法全用carthage管理, 還好CocoaPods跟Carthage是可以混用的, 所以接下來應該可以讓我順利開始寫東西了吧(希望如此)

後記補充


經多次實驗, Shared scheme跟no object的確是兩個不同的問題, 前者0.6.5的確解決了這問題(我猜是我mac mini太慢所以timeout延到8s還不夠才又碰到, MBPR則沒這問題), 後者的確是git版本造成的