想說既然打定主意想玩一下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版本造成的

正常來說Github page可以有一個自己的url像是http://julianshen.github.io (使用者名稱.github.io),但如果想用自己申請的domain name取代(例如以我的例子我想改成http://github.jln.co)該怎做呢?

首先, 你要到你domain name的管理那邊(像我是host在godaddy,所以就直接用它的了), 新增一筆CNAME的record指向到你的github page 原本的domain(如把github.jln.co對應到julianshen.github.io), 不過光這樣還不夠, 你會發現連到http://github.jln.co還是會有錯誤

在你page的repository裡新增一個檔案叫做CNAME(全大寫喔), 裡面的內容就是你新指定的domain name(github.jln.co, 注意, 並沒有"http://“)

OK, 完成

收到了一個IE 10會看不到圖片的bug, 昨天看了半天, 本以為在IE10沒正確載入遠端的資料(後來覺得我怎會蠢到這麼想), debug了半天(IE 10也沒很好的tool), 結果後來發現完全不是這麼一回事, 原本的code是這樣的:

<div style="background-image: url({{mydata.getImageUrl()}})"></div>

一開始也沒想到這邊, 看起來都沒問題, 但後來下面這樣的並沒問題:

<img src="{{mydata.getImageUrl()}}"/>

才發現原來AngularJS在IE10底下, 在style裡用{{變數}}會有問題, 解決的方法是要改用ng-style, 例如

<div ng-style="mydata.backgroundStyle()"></div>

而這裡的backgroundStyle是這樣的(不是string喔)

backgroundStyle = function() {
    return {
        backgroundImage: this.getImageUrl()
    }
}

image

在今年Google IO時, Google宣布了m 未來Chrome OS上可以跑Android的應用程式, 可能有人對Chrome OS不以為意, 覺得既然有了Android何必又有一個Chrome OS, 對於沒用過Chrome OS的人可能會有這樣的感覺, 不過我必須說, 兩者設計的導向是不同的, Chrome OS速度快, 輕便, 這也是Android所比不上的, Google這一舉動, 讓Chrome OS又可以補足功能性不足的部分, 雖然不會全部的Android 應用程式都可以適用, 不過這已經足夠開啟另一個可能性了

目前開放放在Chrome App store的還不多, 只有像是Vine, Evernote這些少數Google已經測試過的, 如可以在這邊找到Evernote: https://chrome.google.com/webstore/detail/evernote/dhfolfjkgpeaojbiicgheljefkfbbfkc

但這些以外的呢?除了等Google大神以外, 還有其他管道嗎?所幸還有其他大神放出相關的工具讓你包裝, 還是Open source:

https://github.com/vladikoff/chromeos-apk

使用這工具你首先必須要有安裝node.js, 之後用npm安裝chromeos-apk這個module即可: “npm i chromeos-apk -g”

使用方法也很簡單, 只要:

chromeos-apk xxxx.apk

這樣即可, 就會產生一個Chrome extension的目錄, 然後進到Chome, 用"chrome://extensions"進入安裝extension的畫面, 載入unpacked extension即可

不過, 我在安裝時碰到一個問題, 出現了一個訊息: 

There is no “message” element for key extName

這問題是由於產生的檔案中在_locale/en底下那個檔, extName的部分只有descriiption沒有message這屬性, 補上去就好, 內容可以是你的app name

著名的工具軟體Clean Master有一項遊戲加速的功能, 它會放一個捷徑在桌面上, 而它的長得就像是跟資料夾一樣:

之前沒仔細去看它, 一直以為它是個小工具(AppWidget), 但其實它只是個捷徑而已, 點選它會跳出一個透明背景的對話窗, 所以很容易誤以為是桌面上的資料夾(如圖右)

這用了個小技巧, 雖然有點唬人, 但其實不難, 以下就如法炮製一個類似的吧!

在這實驗, 就把Youtube, Google plus, Google map三個app的圖示放一起, 邊框, 麻煩就先省略

利用"com.android.launcher.action.INSTALL_SHORTCUT"這個Intent可以在桌面上創建捷徑, 應該幾乎所有的桌面軟體都有支援, 關鍵點在於這Intent裡會帶的Intent.EXTRA_SHORTCUT_ICON, 這可以帶一個Bitmap來當作這個捷徑的圖示, 沒意外的, 就是從這邊動手

因為我們需要把四個圖示畫到一個上面, 所以每個圖示變成原本的1/4, 因此, 在用BitmapFactory.decodeResource載入圖示時, 可以把sample size設成2(也就是1/4大小), 這樣可以減少一些記憶體的使用, 取得了圖示後就可以把它們畫到另一個新的Bitmap了

要注意的是, 要用INSTALL_SHORTCUT的話, 要在AndroidManifest.xml裡加上:

<uses-permission android:name=“com.android.launcher.permission.INSTALL_SHORTCUT” />

這方法的缺點是, 一旦捷徑被創建好後, 就沒機會改它的圖示了