星期二, 1月 22, 2013

威能的 Firefox OS unit testing

今天在謀智台客發表了篇文章,主要是講 Firefox OS 在 unit testing 有個不錯的機制,就是設定妥當後,當你在任何編輯器或 IDE 按下儲存後,unit testing 就會自動開始測試跟你剛剛儲存的那個 javascript 相關的測項,最後用 Mac 的 notification center 或是 Linux 的 libnotify 告訴你測試結果,像下面這樣:



可以讓你隨時都知道自己有沒有把任何東西搞爆了。

有興趣的可以看一下

缺它不可!靈活運用 Firefox OS Gaia 的單元測試

星期三, 1月 02, 2013

travis + jsdom: Javascript unit test 的最後一塊拼圖

在昨天晚上出去跨年前,我把自己之前練習寫的 weather app 重新整理過了一次,主要是把存取 DOM 的部分聚集起來然後寫 unit test 以及開始用 travis 測試。

travis 是好幾個朋友跟我提過但是我都沒認真看怎麼玩,終於在上次的 Hacking Thursdaykanruczchen 討論了幾番之後決定還是自己來試試看比較有感覺。

travis 提供的服務就如 Jenkins 一樣,是一個 CI (continuous integration) 的服務 -- 但是不用自己架 Jenkins 對我來講實在太棒了,我是真的很怕麻煩還要自己維護 CI service。Travis 是直接跟 github 整合的 CI service,所有在 github 的專案都可以很簡單地用 travis hook 透過一個 .travis.yml 來指定 build 以及測試的方式。

jsdom 則是一個在 node.js 上面的 DOM 實作,意思就是說可以利用它在 node.js 裡面操作 window, document 等元件。這個對我來說真是大大的福音。因為 mobile-weather 大多數的邏輯操作都是跟 DOM 相關的,如果剔除這些其實也沒什麼邏輯好測試的。jsdom 讓我可以在 node.js 裡面操作 DOM 等於我就可以驗證一些跟 DOM 相關的邏輯。

jsdom 真的是 javascript unit test 的最後一塊拼圖,有他之後我們就可以測試跟 DOM相關的部分了 :D

最後我在 unit test 採用的是 mocha, chai,前者是 node.js 上面的 unit test framework,後者是 assertion library。

首先第一個步驟是寫 package.json。因為我們的 unit test 會跑在 node.js 裡面,所以我們要先寫 package.json 來交代要用到哪些 library,並且我們可以在裡面指定當執行 "npm test" 的時候要如何執行測試。



4 - 8 行的部分是指定 devDependencies 要使用 mocha, chai 跟 jsdom。9 - 11 行做的是執行 npm test 的時候事實上會執行 node_modules/.bin/mocha -u tdd test/weather_test.js。這之後如果換了 unit test framework 也可以很輕易地從這邊換掉測試方式 :-)

至於 mocha -u tdd 是 mocha 同時有提供 BDD 跟 TDD 的 interface 可以置換,我這邊是採用 TDD。

接下來就可以開始來寫 unit test 了。

目前的 unit test 測試的項目還不多,先把架構弄好之後再慢慢補上。第三行是把 index.html 轉成字串儲存下來。在 7 - 12 行的地方利用 jsdom 生成 window 跟 document,並且每次都重新生成 Weather object 跟重新初始化,主要的目的是讓每個 test case 不會互相影響。test case 我們挑在 20-25 行的 'updateWeekday' 來看。我們知道 2013/1/1 是禮拜二,而 updateWeekday 裡面就會把 day0.textContent 設定為 'T' (Tuesday),接下來依序設定。


所以我們就可以假定 day0.textContent 是 T, day4.textContent 是 S 這樣的方式來測試。寫完 test cast,下達 npm test 就可以進行測試囉。

這樣 unit test 就告一個段落,最後就是把它移到 travis 上面就大功告成了!先在根目錄開個 .travis.yml,內容是你的 travis 組態:

這邊我們指定採用 node.js,並且只測 0.8 這個版本。其實我們只有在 unit test 的時候會用到 node.js,基本上他還是一個一般的 browser app。所以不需要測試多個 node.js 版本。把這邊全部都 push 上 github 後,用你的 github 帳號登入 travis。然後在 account 的頁面找到你的 project 把右邊的 switch 推到 on。

當下次你 commit & push 的時候,就會看到 travis 開始測試你的 project 囉!

並且有每一次的 build log:


超棒的吧,不用在自己架 Jenkins 囉!新年快樂!

目前的計劃是如果我們 fork jsdom 然後把 Firefox OS 有用到的 API 加進去,我們就可以開心的丟掉 Browser 測試 Firefox OS app 了 :D

星期二, 11月 27, 2012

[Firefox OS] HTML 內嵌 SVG 動畫實例

前言:這些實作都已經包含在最新的 Firefox OS 裡面,有興趣的可以 check 最新的 code 出來玩。

最近接到了一個需要變更設計的 issue,我看到這個設計愣了一下,主要的原因是因為要做出這樣的設計用 HTML + CSS 還真的需要想一下如何實作。

主要更改的地方是 Firefox OS 的兩個元件:Lockscreen 跟 Dialer。

這兩個元件主要的設計概念都是希望有一條像是橡皮筋(或跳繩)的線上下的跳動,並且在往上跳動的時候露出下面的兩個按鈕,提示使用者可以把這條橡皮筋往上滑,接下來按下按鈕解鎖。我們這邊只討論如何實作,不討論視覺設計 :P



如上圖所示,上面的那條弧線是需要動態的上下彈動,如果用 HTML + CSS 的話有幾種方法可以嘗試做到跟缺點:
  1. 上一個 canvas,然後把這條線在 canvas 上面不斷的重繪(缺點:這樣要不停的計算跟重繪)
  2. 用超級多張 png 不停的置換圖檔(缺點:要生出超級多圖)
  3. 先畫一張弧線,接著用 CSS 的 Transform 更改他的 scale()(缺點,接近中間的時候整個圖形就會被壓得很扁)
考慮過 HTML + CSS 的解法之後,以上的解法似乎都不太好。這個時候我就開始考慮用 SVG 來做這件事情。但是用 SVG 來做這件事情其實是蠻冒險的,因為在這期間問了幾個同事他們都沒有測試過 SVG 在 Firefox OS 真正的手機上的詳細效能。所以收到這個設計的時候我先寫信問了個對於整個 platform 比較熟的同事,然後因為 deadline 非常的趕,但是我又不能不確定效能狀況就下手,所以就先決定做個獨立可以同時在電腦跟手機都可以驗證的小型 app。

這個 app 要驗證的事情有兩件:
  1. 當用滑鼠(手指)按住拖曳,這個時候改變 SVG 的屬性讓他改變弧度的效能衝擊有多大
  2. 使用 SVG animation (SMIL) 效能到底如何
然而做這個 DEMO 幾乎也可以搞清楚要怎麼用 SVG 實作這個解鎖畫面了。在弧線的部分,採用 SVG 的 Path 搭配上 c (curveto) 參數可以達成弧線,動畫的部分則是用 SMIL 的 animate tag 完成。下面這個網頁就是驗證效能用的網頁(我只用過 Firefox 打開過,其他瀏覽器不知道有沒有支援):

http://yurenju.github.com/lockscreen-demo/wrapper.html

這邊只是用來驗證的網頁,所以會有一些小 bug。主要的功能就是往上拉的時候用 javascript 去改變 SVG d (data) 裡面的 c (curveto) 的參數,放開滑鼠的時候用 SMIL animate 把 curve 滑回原位。而下面有個連結 install lockscreen demo 用途是如果你用 Firefox OS 的手機點了這個連結就可以把這個 demo app 安裝到手機裡面。

很棒的是當我把這個 app 安裝到手機裡面,發現這樣實作的效能在手機上是完全可以接受的!既然可以接受那就大膽的把這樣的實作方式引入 Firefox OS。這邊有針對 lockscreen 的 commit


在 SVG 方面,首先利用 path tag 來劃出最原始的弧線。在 attribute d (data) 裡面用了兩個參數:M (moveto) 跟 C (curveto),moveto 用來指定 path 的起點,curveto 用來指定用來控制曲線的兩根桿子的弧度。SVG 1.1 Path 裡面有張圖讓 curve 的控制點比較好理解一點:



C 後面接的兩組 (x, y) 分別是兩個控制點的坐標,我們需要的大概像是最左上角那張圖的效果。attribute 'd' 裡面的最後一個參數則是曲線的終點。整個 attribute 長這樣:

M0,80 C100,150 220,150 320,80

第一個是曲線起始坐標,最後一個是曲線結束坐標,中間兩個則是控制點的坐標。

接下來說明 path 裡面的五個 animate tag。1 跟 3 是針對曲線的彎度變化,而 2 跟 4 則是針對透明度的變化。1-4 都是用於拖曳橡皮筋之後放開的動畫,而 (5) 則是當你不去碰橡皮筋時,他的彈跳提示動畫。請想像這一整組動畫:一條繩子彈上去後隨著重力掉下來,掉到地上之後會再彈跳幾下後靜止。下面講解比較複雜的第五組動畫:

先看到 values。用分號切分開來的話總共有五組數據:
  1. 起始的曲線數據 (Y=150)
  2. 第一次彈跳到最高的數據,兩個控制點的 Y 坐標都變少了讓整個圓弧的開口朝下 (Y=40)
  3. 回到最地上 (Y=150)
  4. 再次彈起來,但是幅度較低 (Y=100)
  5. 回到原點 (Y=150)
至於 keySplines 則是指定彈跳的 timing function,如果你用過 CSS animation,就跟 ease-in/out 那種差不多的東西,只是要直接指定數據,下面這張圖是 keySplines 設定 0.5 0 0.5 1 會產生的 timing function:


keySplines 裡面有四組數據,分別就是 1-2, 2-3, 3-4, 4-5 這四段動畫的 timing function。每一組數據裡面都是兩個控制點的坐標。

SVG 的部分大概就是這樣!這部分有很多需要細微調整的,有興趣的就留言一起討論吧。接下來是 Javascript 部分。這邊我就講一些 SVG + Javascript 要注意的小技巧
  • fill=freeze 功能為讓動畫結束之後停留在最後一格,不過這樣的話如果你想要用 mousemove 去逐漸改變曲線的外形時,你會發現這個屬性會讓整個 path 卡死。如果拿掉 fill=freeze 的話,因為我執行完動畫之後還要把曲線固定在最後一格,所以拿掉的話就導致動畫有閃爍的現象。 解法就是平常不用,等到要播放補間動畫的時候再把 freeze 加上去。
  • 用 beginElement(), endElement() 來播放、停止動畫
  • addEventListener endEvent 來處理動畫結束後的後續處理。
這邊的細節真的非常的多,如果你也想 HTML + SVG + Javascript 來實作的話,建議是要讀一下 SVG 跟 SMIL 的 spec,然後撿想要用的東西放在裡面,什麼不明白的事情就直接寫到 SVG 裡面看一下效果如何就是了。那個時候這個 commit 要上真是超級緊張的,因為這是我開始 contribute Firefox OS 以來最大的修改。結果上的時候還是有些小細節沒注意到,感謝同事的幫忙在 bug 還沒關之前就注意到這個低級錯誤然後讓我可以及時的推入 repository 了。

之後更複雜的是 Dialer 的部分。



如上圖所見左右兩邊各有一個會隨著弧線移動的兩個 spotlight,而線段上的顏色還多了紅色跟綠色線段。線段不同顏色方面,看遍了 SVG 的資料後比較方便的方法還是用多重的漸層並且把兩個漸層的 offset 設定成一樣,這樣就可以讓曲線有不同的顏色。至於隨著 curve 的 spotlight 則是透過 clipPath 作修剪遮罩,讓漸層只在部分的地方露出來即可。做完這次的 commit 我的 SVG 功力真的大增啊... Orz



這是在 Dialer 曲線用的漸層。2 跟 3 的 offset 都是一樣的,但是顏色卻用不一樣,這樣的技巧可以讓線段不會產生漸層。

這段是如何產生 spotlight 的方法。首先 path 不一樣的地方是 d 除了原本的 M 跟 C 以外,又加了 H V Z 分別用來畫出橫線、直線跟關閉 path 用。fill style 則套用上面的 #gradient-red 的漸層紅色,最後用 clipPath 的方式作剪裁遮罩。對綠色的部分也用相同的方法,最後通通拿去做動畫,就完成啦!

所以這是最後的結果:



Dialer 最後實作的結果在這邊,很可惜速度上並不是很好,目前看起來撥電話進來之後整隻手機的效率會下降許多,目前我們也正在改進這個問題。



這個 lockscreen 的 code 都在 github 上面,有興趣的可以抓下來玩玩 :-)

星期一, 10月 29, 2012

Using Google APIs Client for Android

這是在十月 27, 28 日在高雄軟體園區舉辦的 MOPCON 我講的題目。原本演講的時候最後一段 OAuth 的部分是直接在 Source code 裡面講解。不過回來之後已經把投影片都補上了。

另外如果你也有使用 Google APIs Client 也可以交流一下,我發現好像還蠻少人在用的。

總之下面是投影片,請笑納 :D


星期三, 10月 17, 2012

jscallgraph - Javascript Call Graph 靜態分析

最近用 xmind 追 code 追得很辛苦,跟幾位朋友討論過後,不知不覺就開始寫起了靜態分析用的程式。昨天先用 python 驗證了一下概念,深夜開完會議之後就決定用 node.js 來寫個程式會比起用 python 更為合適。目前已經放上 npm,要安裝只要你已經裝好了 node.js 跟 npm,輸入以下指令就可以安裝了。

$ sudo npm -g install jscallgraph
$ sudo apt-get install graphviz

第二行是安裝 graphviz,主要的用途是拿來產生分析完的圖形用的。使用上很簡單,舉例來說你想要對 Firefox OS 的 system app 裡面的 window_manager.js 作靜態分析,把檔案抓下來,用以下指令產生 dot file

$ jcg window_manager.js WindowManager > window_manager.dot

第一個參數是要分析的檔案,第二個參數是要分析的物件,這邊可以參考一下 window_manager.js 的檔案,裡面宣告了 WindowManager 物件,並且把相關 method 都包裝在裡面。

接下來用 graphviz 的 dot 指令產生 png 圖檔

$ dot -Tpng -o window_manager.png window_manager.dot


這樣就完成了!



Source code 放在 github, 請大家自由取用!另外這程式不是什麼 javascript 都可以分析,有興趣的請送 patch! :D

星期一, 10月 15, 2012

[Firefox OS] 呼叫 MozActivity 的內部訊息流程

上週快結束的時候我一直在追蹤一個 Firefox OS 的 Bug #800169,後來發現不是 Gaia (Firefox OS 的 App 層) 之後,我就一路往下看到了 Gecko (Firefox OS 的 Runtime 層),當我覺得快要找出癥結的時候,這個 Bug 在 Nightly build 被別人解決了! XDD

不過趁著這個機會也把架構熟悉過了一遍,跟大家分享一下。

先解釋一下這個 bug,Firefox OS 的瀏覽器在把一個網頁加入到 home screen 的時候,加入 Home screen 的確認視窗會跳出來兩次。

首先我們就從 Browser 的 browser.js 開始,按下『加入至 home screen』後會使用下面的 API 呼叫加入 home screen 的 dialog 。

new MozActivity({
  name: 'save-bookmark',
  data: {
    type: 'url',
    url: this.currentTab.url,
    name: this.currentTab.title,
    icon: place.iconUri
  }
});

MozActivity 是怎麼呼叫 Dialog 的呢?經過追蹤,當你呼叫了 MozActivity 的時候,真正執行的是 B2G/gecko/dom/activities/src/Activity.cpp。當你找出這個地方後可以用 gdb 來確認是不是這裡,詳細的用法可以參考 Debugging B2G using gdb。Activity:Initialize 的最後面的程式碼是這樣:

nsresult rv;
mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);

mProxy->StartActivity(this, options, window);
return NS_OK;

事實上這個時候 B2G 去調用了同一個目錄底下的 ActivityProxy.js,這個時候用 Child Process Message Manager 的  sendAsyncMessage 丟了用來開啟 Activity 的訊息出去。

cpmm.sendAsyncMessage("Activity:Start", { id: this.id, options: aOptions });
cpmm.addMessageListener("Activity:FireSuccess", this);
cpmm.addMessageListener("Activity:FireError", this);

ActivityService.jsm 的 receiveMessage 會接收到這個訊息,並且交由 this.startActivity 來處理之。而 startActivity 決定完成要用哪個 app 開啟這個 Activity 後,再用 system-message-internal 的 sendMessage 丟出一個名為 activity 的訊息。

let sysmm = Cc["@mozilla.org/system-message-internal;1"]
              .getService(Ci.nsISystemMessagesInternal);
if (!sysmm) {
  // System message is not present, what should we do?
  return;
}

debug("Sending system message...");
let result = aResults.options[aChoice];
sysmm.sendMessage("activity", {
    "id": aMsg.id,
    "payload": aMsg.options,
    "target": result.description
  },
  Services.io.newURI(result.description.href, null, null),
  Services.io.newURI(result.manifest, null, null));

最後到了 SystemMessageInternal.js 裡面的 sendMessage 最後會調用 _processPage 來開啟正確的 App。

let page = { uri: aPage.uri,
             manifest: aPage.manifest,
             type: aPage.type,
             target: aMessage.target };
debug("Asking to open  " + JSON.stringify(page));
Services.obs.notifyObservers(this, "system-messages-open-app", JSON.stringify(page));

而追蹤的 bug 的問題點就在這裡,這邊有兩個 match 的 page,所以他連續開啟了兩次 add to home screen 的 dialog。當我追蹤到這邊的時候,其實基本上已經找到問題的根源了。不過在跟別人討論的過程中突然發現有另外一個 bug 的 patch 已經解決這個問題,而且在 nightly 的 build 也不會有這個問題,所以我就沒繼續追蹤下去了。

藉由這次機會也從 Gaia 到 Gecko 看了一大圈,也算是很有收穫  :D

星期五, 9月 28, 2012

HTML5 mobile app 練習

這幾天在練習 HTML5 mobile app,決定找一個 Android 底下的 app 來重刻成 HTML5 版本,我挑的是 News & Weather 的天氣部分。



這是一個可以根據你現在地點給你當地天氣的 app,按下右邊靠近上面的驚歎號圖示可以看今天一整天的溼度以及溫度變化,在圖形上面用手指滑動可以看指定時間的溼度。

我找了一下如果要每個小時的溼度與溫度的 Weather API 大多都要錢的,所以最後我接了 World Weather Online 的 API, 但是圖表就換成接下來五天的天氣氣溫變化,當作練習就是了。

成果如下,他只能跑在 Firefox for Android 上面,我沒有針對 Chrome/Safari 等 webkit 系列調整。

  


作完之後有一些感想...
  1. 如果不考慮相容性,現在的 CSS3 真的很強大,以前很詭異的排版方法現在都變得好排多了,我連右上角驚歎號圖示按下去顯示另外一頁都是用 CSS3 完成的,不需要 javascript。
  2. CORS 我還是沒搞定,最後用比較醜的 JSONP 解決。
  3. SVG 雖然好用,不過看起來效能在 mobile 上面還無法接受,目前應該還是用 Canvas  比較好。
  4. CSS/SVG 的漸層效果在 Firefox For Android 上面看起來很差,不知道爲什麼。
然後我很懶惰的沒有做 SVG path 的圓角,看起來好像沒有像是 rect 的 rx,ry 可以直接設定...

Source code 我放在 github 上面,有興趣的參考參考。

星期四, 9月 06, 2012

cinnamon - 用 Javascript 高度客製化的 GNOME3


看了 小 Q 的 Facebook 之後,我也裝了 cinnamon 來用用。我之前一直推想 cinnamon 應該是把 GNOME3 裡面的 gnome-shell 的高度客製化,這次裝起來果然是這樣。一個很簡單的確定方式就是按 alt + F2 輸入 lg,就會從下面拉起一個 javascript console, debugger 跟 inspector 合一的開發工具 LookingGlass。


如果去查看 cinnamon 的套件檔案列表,也包含相當多的 Javascript。

因為很多人不知道,所以我再強調一次,整個 gnome-shell 都是 Javascript 寫的,所以 cinnamon 也都是整個用 Javascript 寫的。

比起 Ubuntu 整個砍掉重練用 compiz 重寫一個 unity 桌面環境,我覺得 cinnamon 用 GNOME3 既有的成果開發桌面環境是比較好的選擇,畢竟 Javascript 一來是比較多人會用的程式語言,另外在需要擴充功能的時候,Javascript 也可以很快的就寫好擴充。

更何況 cinnamon 就算是高度客製化他還是 GNOME3,很多資源都是可以共享的,而 unity 就等於完全新開一個獨立的分歧,恐怕濃厚的 Ubuntu 色彩會讓其他 distribution 不太願意使用。(不過 Fedora 18 似乎要把 unity 加入 repository 裡面 )

星期三, 8月 01, 2012

ReactiveUI 概念篇

ReactiveUI 解決了我兩個問題,一個是把 App 中可以測試的部分擴大,二是解決 UI/Thread 糾結的問題。

你怎麼測試你的 app 的呢?底層我們當然可以透過 unit test 的方式進行,但是通常來說 UI 上面的東西都是比較難以測試的。通常我們會透過自動化 UI 的測試如 Sikuli 測試。但是這樣自動化 UI 常常會跟畫面綁定造成常會因為畫面變更而需要重新製作測試的 script。至於 MVC 裡面 Controller 的部分常因為跟 Event 綁定造成 Controller 其實是很難以測試的。ReactiveUI 是一種 MVVM (Model View ViewModel) 的 framework,其中由 ViewModel 取代 Controller 達到連 ViewModel 這個部份都可以測試,原因在後面讓我娓娓道來。

另外,我們這邊討論的 MVVM 只限於 ReactiveUI,我並沒有用過其他的 MVVM Framework。

MVC v.s. MVVM


MVC (Model-View-Controll) 是大家現在非常常用的 pattern,基本上就是把資料 (Model)、UI (View)、邏輯 (Controller) 分開來。在 Android 或一般的 WPF 裡面,我們會把事件處理也放在 Controller 裡面,Controller 可以作為聯繫 View 與 Model 的橋梁處理各式各樣的事情。所以 Controller 處理了邏輯跟事件。那 Controller 有辦法獨立進行測試嗎?這只有在你把邏輯與事件處理拆開後才有辦法單獨針對邏輯測試。

MVVM 是有別於 MVC 的另外一種設計方式,架構如下:



你可以能會說,這架構只是把 Controller 換成 ViewModel 而已,感覺不出來什麼差別阿?但其實不是的,ViewModel 反映了 View 裡面的資料。ReactiveUI 裡面的 ViewModel 包含了兩個重要的東西:屬性與命令

我用下面這個 Mockup 舉例,這是一個可以選擇要把內容發布到不同 Social Network 的小程式,左邊的 100x100 是自己的大頭照 Avatar。右上角的輸入框是要發布的內容,下面的下拉選單是要發布到哪裡的選項。


在 View 裡面的每個需要資料的元件,指定要跟 ViewModel 裡面的哪個屬性綁定,如同上面的例子,View 裡面要指定:
  1. 圖片的 Source 位置 => AvatarSource
  2. 輸入框的文字 => ContentText
  3. 下拉式選單的選項 => SocialNetworks ["Facebook", "Twitter", "Google+"]
  4. 下拉式選單選擇的項目 => SelectedSocialNetwork
ViewModel 與 View 的互動是雙向的,比如說 (1) 我在輸入框裡面打了 "I saw The Dark Knight Rises today!",這個時候 ViewModel 裡面的 ContentText 就會更新成新的文字敘述。(2) 當我點擊下拉選單,把要發表的 Social Network 從 Facebook 改成 Twitter 後,ViewModel 裡面的 SelectedSocialNetwork 也會被修改成新的數值。從另一個方向來看,(3) 如果我在程式裡面修改了 AvatarSource 的網址,這個時候 View 裡面的圖片就會自動更新。所以兩個方向的更新都是可以的。



至於命令 (Command) 則是獨立於 View Event 的部分。在上面這個例子裡面,按下 PostButton  之後就會執行 PostCommand。由於在 Command 裡面需要的東西,如要發表到哪個 Social Network,要發表的內容都已經綁定到 ViewModel 裡面的屬性了,所以不需要跟 View 互動,只要直接取用屬性及可,我們可以用簡單的虛擬碼表示:

PostCommand.Subscribe( _ => SendToSocialNetwork (SelectedSocialNetwork, Content))

由於屬性與命令都已經 Mapping 到了 ViewModel 了。這下子 ViewModel 的部分就可以被拿出來獨立測試。如同下面的虛擬碼:

Test {
    var ViewModel = new ViewModel()
    ViewModel.SocialNetworks.AddRange("Facebook", "Twitter", "Google+")
    ViewModel.ContentText = "Test Content"
    ViewModel.PostCommand.Execute()
}

如此一來 ViewModel 就可以測試了,而且架構非常乾淨!

而 ReactiveUI 裡面包含了 ReactiveCommand 與 ReactiveAsyncCommand,當你要處理非同步事件只要用 ReactiveAsyncCommand 即可。

這樣的架構是不是很乾淨呢?下次再來講 ReactiveUI 實際上要怎麼使用。

等不及的人,這邊是 ReactiveUI 的官網

星期四, 7月 19, 2012

[H4] 人生自動化之 ifttt 與 on{x}

以下是 Hacking Thursday 聚會討論到的東西,沒看過太多人介紹,所以自己介紹一下。




IFTTT 其實是一個超簡單的東西,他連結了很多網路上各式各樣的服務,接下來就可以用 if this then that 的方式來做一些方便的事情,下面提供我使用的例子:

  1. 如果我在 flickr 上面對一張照片打了愛心,然後就把這張照片傳送到 Dropbox
  2. 如果 ecoupons.com 網站上有 ThinkPad 的特價,然後就寄信提醒我
  3. 如果有人在 Facebook 的照片上 tag 我,然後就把這張照片儲存到 Dropbox
相信這樣大家就很清楚 ifttt 的功能了。



那 on{x} 呢?這個服務跟 IFTTT 一樣,但是他更結合了手機的位置當作觸發條件。一樣用幾個例子讓大家了解這東西怎麼用。另外這是一個服務,而且你需要在你的 Android 安裝相對應的 app。
  1. 如果我離開家裡,就幫我關掉手機的 wifi
  2. 如果我離開公司,就寄送手機簡訊給我老婆上面寫『我要回家啦...』

瞭解了吧,另外 on{x} 更好的是可以用 javascript 寫程式,可謂是 IFTTT 的超級強化版。