主題簡介:
今年 Apple WWDC 2014 發表新的程式語言 Swift,造成全世界熱烈討論,在這個典範轉移 (Paradigm Shift) 的過渡時期,我們要做好哪些準備呢?
當全世界的程式語言(包含 Swift、Java),都往 Functional Programming 發展,我們要先來了解一下,什麼是 Functional Programming,可當作是迎接 Swift 新語言挑戰之前的先修班。
什麼是 ReactiveCocoa?
ReactiveCocoa 是由 GitHub 發表,來自于兩位大師 Josh Abernathy & Justin Spahr-Summers 所創造而來,主要將 Functional Reactive Programming 概念注入 Objective-C。
Functional Reactive Programming
一般程式週期為 Input 到 Output 的處理轉換,Input 可以是來自于 資料、Web Service、鍵盤事件…等,Output 可以是 使用者UI 或 存入檔案,ReactiveCocoa 提供開發者另一個資料輸入輸出的新思維,將複雜的程式邏輯,用簡潔的方式解決。
Mattt大神說「ReactiveCocoa 是 Objective-C 的新紀元」
Justin DeWind「ReactiveCocoa 將是 Cocoa 的未來」
講者簡介:
簡介
- 一個熱愛 iOS 開發、Ruby、Linux 的開發者。
- 喜愛分享、寫作,以分享知識為樂。
- 喜歡把問題簡化,用最簡單的方式解決問題。
參與
- CodeData 作者
- iOS Dev Club 講者
- Cocoahead Taichung 講者
- 參加蘋果官方主辦 2013年 Tech Talk
- 麥克自由聚(Apple, Mac, iOS 相關) 講師
簡報:
錄影:
\#1
首先感謝大家來參加
沒想到人會那麼多 (大約兩百多人
有人是因為題目來的嗎?請舉手
那各位一定是鄉民(笑
\#2
今天要分享的是一種開發範式 functional reactive programming
能夠幫我們建立描述資料流的架構
首先介紹我們今天的主角 ReactiveCocoa
我們簡稱 RAC
\#3
先請教大家幾個問題
有聽過 RAC 的請舉手?(現場大約20位來賓聽過
有沒有很熟悉 RAC 的?(後排有一位舉手
太好了,等下如果有小弟沒講好的地方有請大大回答
已經用在專案上面的,有嗎?(現場 不多 個位數
其實 RAC 很適合半途插進去
因為非常 loosely coupled
\#4
好!什麼是 RAC?
RAC 是一個開放原始碼的套件,提供 FRP(functional reactive programming)開發範式
從 GitHub for Mac 專案所分支出來的套件
由 Josh & Justin 兩位大大所開發
他們兩位的關係是
起初 RAC 專案主要是由 Josh 維護開發管理
後來 Josh 把 Justin 找進去 GitHub 之後
主要就是由 Justin 在維護管理
這模式好像在資訊業很常見(笑
\#5
那 什麼是 Stream?
\#6
Stream 就是 在管子(Pipeline) 裡的資料流
Stream 的意思就是 在管線裡面流動的資料
用 RAC 的術語 管子就是 Signal
Signal 在 RAC 裡面扮演著很重要的角色
我們稍後會更進一步介紹
如同我們前面提到
RAC 提供一個 建構模式
讓我們可以定義資料流動時
如何對資料做一個適當的處理
可以將比較複雜、散亂的商業邏輯
做出適當的定義
\#7
所以 大家會覺得我用 RAC 像是
\#8
所以商業邏輯加上管子
理論上應該被我們整理的很整齊
簡潔清晰
沒錯 RAC 框架要帶給我們的就是這樣的好處
\#9
但是呢
實際用起來是…
\#10
用起來結果 Stream 爆掉了
資料流到處亂竄
也不照著水管流動
跟我想的不一樣
好像沒那麼簡單
\#11
而且看了 ReactiveCocoa 的 README 文件後…
\#12
就像是小孩在玩大車一樣
無法駕馭
有點難理解
光是 README 我就看了好幾次
\#13
我今天就來跟各位分享一下 我用 RAC 的心得
這是我們今天的 Agenda
1. 簡單介紹一下 FRP 的概念
2. 事件與非同步的問題
3. 介紹 RAC
4. RAC 基礎
5. RAC 範例
6. iOS Dev Club 社群介紹
\#14
先稍微自我介紹一下 我叫 張景隆
網路上暱稱 Appletone
上面是我比較熟悉的 skills
早期在學校主要就是在寫 Perl 跟 Java
後來用 Java 做了許多專案
甚至大家可能都有用過
例如
移民署入出境管理系統
自動通關
海關查驗
\#15
這是我近期的作品
biiChat
這是一個 電商平台結合聊天室
就類似 yahoo 拍賣的問與答留言板
但是因為這類的溝通 反應不夠及時
所以我們把 電商 結合類似 Line 的概念
讓商家跟顧客的溝通 能達到一個即時的回饋
提升顧客滿意度
並且 導入 Geo-Fence (地理圍欄)
提供附近優惠通知
就是商家可以設定活動優惠內容
當使用者在附近時
使用者將會收到 附近商家的優惠活動
可拿著優惠訊息前往消費折扣
實踐電商 O2O (online-to-offline)的做法
BTWCar
是個 軟硬整合胎壓計 BLE(藍芽低功耗) App
這個 App 可以 記錄油耗、保養記錄、胎壓
還可拍照 分享到 Facebook
CWMoney
記賬 App
是台灣AppStore 所有分類 Top10 常客
財經類 Top1 的記帳軟體
\#16
這張圖呢 是我們學資訊的一個很簡單的概念
Input 就是我們的 資料, web service, 鍵盤事件, 觸控事件, 螢幕轉向事件…
Output 就是將輸入的資料、事件,轉換處理 顯示到 UI 或是 轉存到其他地方
像我們在寫程式的 function 一樣 把參數傳進去
把結果 return 回來
把這個概念記在心裡
因為這個觀念很重要 Signal 也是在做類似的事情
轉換 (Transform), 合併 (Combine) 資料流
\#17
我們來看看 語言特性的分類
命令式語言
什麼是命令式語言
如同畫面上很簡單的程式
x等於1 y等於1
x加y等於z
這時候把 y 的數值改為 2
不會影響 z 的結果
大部份的語言都是屬於命令式語言
\#18
我們來看看 響應式編程
x等於1 y等於1
x加y等於z
這時候把 y 的數值改為 2
z 的結果 馬上會跟著改變
\#19
我們再來看看 functional programming
FP(functional programming) 以 lambda 語句為基礎
我們先來看 Objective-C 的範例
將 1~3 的連續數字 乘上 5
並將結果附加到一個陣列上
Swift 範例 就簡短很多
剛剛說的在 FP 叫做 map
map 方法是用來處理轉換資料流的數值,並創建新的資料流
在 RAC 概念裡面很重要 也很常見
Swift map 這個 function 其實是有兩個參數
後面的參數是 Closure
這邊我們把 Closure 提取出來 叫做 Trailing Closure
$0 是參數名稱縮寫, 數字 0 代表第一個參數
所以用 FP 我們就可以將程式縮短很多
也少了變數 與 狀態
\#20
Functional Reactive Programming
簡單來說就是 將剛剛介紹的 Reactive Programming 響應式編程
賦予 functional programming 的特性
使 RP 有著許多 FP 好用的函示
\#21
我們來看看 當我們開始著手寫 iOS App 時
可能會遇到的一些問題
首先 我們可以使用 target-action 去定義 事件
也可以用 delegate 來實現多行
Block..Notifications..KVO.. 等等
這些都是我們常用來處理 事件 非同步 等技巧
但是這些技巧給我們帶來哪些問題
方法太多
缺乏一致性
整個商業邏輯 被分散到程式的某些角落
難以整合各個事件
\#22
所以呢 RAC 的出現就是要處理這些問題
提供一個統一的方式
來整合這些功能
這也是一個很重要的概念
因為很多事情我們必須要非同步處理
才不會把 UI 反應給停住
連今年 WWDC Tim Cook 也說
這是一個非同步的世界
\#23
有人會問
為什麼是 ReactiveCocoa 呢
\#24
Mattt大神說「ReactiveCocoa 是 Objective-C 的新紀元」
Justin DeWind「ReactiveCocoa 將是 Cocoa 的未來」
有大大們背書
還有 GitHub 光環
這裏有兩篇文章連結
大家可以找時間看看
\#25
我們來了解一些 RAC 的術語
RACSignal 跟 RACSequence 有什麼差別
什麼是熱信號 什麼是冷信號
\#26
RACSequence 跟 RACSignal 都繼承於 RACStream
RACSequence 是 pull-driven
RACSignal 是 push-driven
聽起來有點抽象
我們先來看看主角 RACSignal
RACSignal 在 RAC 是主角
扮演所有資料、事件的串接、轉換
推送 資料 給訂閱者 或是 適當的對象
所以我們稱為 push-driven
那什麼是 pull-driven 呢
\#27
各位有抽過捧花嗎?
但是我們要講的跟抽捧花的結果無關 XD
各位試想一下 新娘的角色
手中握著捧花跟絲帶
伴娘們都各握一條絲帶
新娘只要一拉 就可以拉動所有的伴娘
就是 pull-driven 的概念
RACSequence 顧名思義
Sequence 處理連續的資料
\#28
我們來看 什麼是熱信號 什麼是冷信號
\#29
熱信號就是
類似按鈕事件
只要事件一觸發 就馬上收到通知
這就是熱信號
那什麼是冷信號
例如呼叫網路服務
那些不會馬上知道結果的處理
都叫做冷信號
\#30
知道一些 RAC 概念 之後
我們來看看怎樣建立信號
先來介紹 Marcos
RACObserve
用來建立 RACSignal
可用來監控數值變化
若變動 則觸發信號
RAC
放在 assignment operator 的左邊
綁定 RACSignal 給的數值
\#31
我們先看左邊 RACObserve 轉成 Signal
當有新的數值時 遞送新的資料 給訂閱者
然後 subscribeNext 裡面的 block 就會執行
這邊的例子就是說
利用 RACObserve(self, username) Macro 建立一個 Signal 當 self.username 有新的數值時,傳送訊號 給 訂閱者
subscribeNext 當 Signal 傳送數值時,會執行這個 block
\#32
我們來看 RAC 怎麼使用
跟剛剛一樣 我們把 RACObserve 擺在右邊
左邊我們用 RAC 去綁定 畫面上的 consoleLabel
所以只要 self.username 一改變
就會把值 印到 consoleLabel
\#33
網路上有人說
既然 RAC 廣泛使用 KVO
怎不直接使用 KVO 就好
\#34
因為信號可以被串接 轉換 …
而且 KVO 不好用
以下消音 … XD
\#35
接下來我們建立好一些概念後
我們來看範例
今天準備了五個範例
來教大家如何使用 RAC
活用 RAC
範例一
會介紹到
rac_textSignal, map 跟 避免 retain cycles
\#36
RAC 很貼心的提供很多 屬性 與 方法
大多都以 rac_ 開頭
例如 UITextField RAC 就提供 rac_textSignal
當 UITextField 文字一改變
就馬上通知訂閱者
\#37
這邊呢我們先看 map
我們把 rac_textSignal 信號轉換
把 信號送進來的資料流
就是 UITextField 的 文字
把它轉成大寫
轉成大寫之後 再送給訂閱者
這邊我們注意到
有兩個特別的 Marcos
這個源自 libextobjc 專案
這專案作者也是 RAC 專案維護者 Justin 大大
這邊把一些常用的功能 已經納入 RAC
所以我們可以直接 import RACEXTScope
就可以使用 Marcos
這邊因為我們在 block 裡面用到 self
在 block 引用到 self 時
self 的 retain count 會被 +1
所以 當結束時 self 不會被 release
為了避免記憶體遺漏的問題
我們可以使用 weakify, strongify 來解決這樣的問題
\#38
第二個範例
登入
\#39
這是一個簡單的登入畫面
兩個欄位 一個按鈕
輸入使用者 密碼
然後送出
\#40
我們運用範例一 教的 rac_textSignal
建立 使用者欄位的信號 與 密碼欄位的信號
當這兩個欄位都有輸入數值時
才讓 登入按鈕 亮起來
這邊我們使用 combineLatest 把信號合併
並且 reduce 結果 回傳 true 或 false
\#41
範例三
UserDefault 是一個可以存放一些
簡單的資料的地方
例如 使用者偏好設定 哪些功能要不要打開
\#42
這是一個常用的範例
一般網路服務登入後 常用的做法,將 token 存在 UserDefaults
之後 API 都透過這樣的方式取得 token 發送 網路API 到雲端伺服器
分兩個部分
我們先看上半部
使用 NSUserDefault
這邊我們用了 RAC 提供的方法 rac_channelTerminalForKey
建立 RACSignal
那什麼是 channelTerminal 什麼是 RACChannel
RACChannel 能夠建立雙向的 Signal
RACChannel 的兩端 分別各夾帶一個 channelTerminal
好處是 只要任一邊的數值改變
就能把資料寫到另一邊 channelTerminal
所以我們可以使用 RACChannel 把 NSUserDefault 的某個設定
綁到 物件的某個屬性
只要屬性改變 就能直接寫回 NSUserDefault
這個範例我們只要把它當作是一般的信號處理即可
接下來看下半部
將 UserDefaults 的 token 轉為 Signal 使用rac_channelTerminalForKey
這邊我們使用 filter 過濾我們想要的資料流
這邊使用 chuzzle 簡易的判斷 有數值時 我們才通知訂閱者
然後在 subscribeNext 處理載入資料
所以只要使用者一登入 取得 token 寫入 UserDefault
subscribeNext 這段程式碼 將會被自動執行
\#43
範例四
我們一定要介紹 AFNetworking 跟 RAC 整合
跟 AFNetworkReachabilityManager
\#44
我們先看 AFNetworkReachabilityManager
自從蘋果官方寫的偵測網路狀態的程式 Reachability
後來 AFNetworking 也納入了該功能
這邊我們可以看到 我們使用 ReachabilityManager 建立 isReachable 信號
來隨時通知程式 目前網路是否正常
只要是在 WIFI 或 cellular 下 網路都正常
其他則否
\#45
這整段程式是在處理呼叫 API 取得 自己的 IP
的 AFNetworking 簡單程式
我們把重點放在中間 如何使用 AFNetworking 建立 信號
使用 RACSignal createSignal
createSignal block 裡面 我們處理 AFNetworking 處理
我們再把重點縮小 注意 sendNext, sendComplete, sendError
這邊我們把 createSignal 給我們的 subscriber 參數
發送信號 成功 完成 或是 失敗
下面我們就可以很簡單的去訂閱 myIPSignal
當取得IP時 通知我
\#46
範例五
這個範例我們故意把他弄複雜一點
我們來看看畫面上的條件
檢查 網路狀態 以及 雲端伺服器 是否正常
使用者是否啟用同步功能
是否有待同步資料
需綁定 FB Account
可設定 WIFI 或 3G 底下同步
\#47
我們畫了一個簡單的流程圖
概觀一下我們要處理的狀態
\#48
我們將程式碼切割兩個部分 來看
先處理狀態 網路狀態 是否開啟雲端 FB帳號是否已經綁定 是否開啟僅WIFI底下同步
將這些信號合併為一個 preparedSignal 信號
準備上傳的信號
下半部我們監控整個待處理的資料
先過濾準備上傳的信號 是否為 true
subscribeNext 則處理上傳
整個本來很複雜的邏輯
我們可以透過 RAC 去定義他
讓他變得更簡單
\#49
如果 subscribeNext 需要處理很久 時間很長
我們可以用 deliverOn 把他推到背景處理
\#50
今天介紹的 RACSignal 還有一堆 很強大 好用的 Operations
都在 RACSignal+Operations.h 裡面
大家可以去看看
\#51
最後我整理一下今天所講的部分
跟各位做個總結
我們學到了
RACSequence & RACSignal 的差別
熱信號 與 冷信號
實用的 Macros: RACObserve() & RAC()
信號 的 建立、訂閱、合併、轉換、過濾
以及如何建立非同步的網路信號
\#52
後面容小弟利用一點時間介紹我們的社群
iOS Dev Club
\#53
iOS Dev Club 為台灣目前最大 iOS 開發社群
(2014/10/25 時 社群人數約 1700人, 目前 2014/12/06 約 2000人)
iOS Dev Club 成立於 2011 年 5 月。
我們是以 Facebook 的社團(groups)成立,主要是為了在中部附近的 iOS App 設計開發同好,可以經常性碰面互相學習的聚會,我們的地點都選擇在咖啡館,固定在每個月最後一週的星期六上午,每次都會安排主題分享研習。
第一年,我們在彰化的顏氏牧場II舉辦。
第二年,我們在台中的默契咖啡舉辦。
第三年,我們挑戰環島~
因為每個月中旬發出聚會訊息時,最常見的歎息就是:為什麼不是在XXX? (XXX=請自行帶入離自己居住熟悉或最近的城市)
於是第三年,我們分別在台北、新竹、台中、高雄辦了六場的 iOS Dev Club 開環島開發這聚會,我們到這幾個城市拜訪當地的 iOS 開發社團、專業的程式設計社團,互相交流也互相認識。
第四年,我們來到了台中市龍井區的蘋果貓咖啡舉辦,我們除了在這裡每個月舉辦一次之外,也會陸續在每週都有研習課程加入,請大家密切注意我們在 Facebook 粉絲專頁發佈的活動資訊。
\#54
iOS Dev Club 環島開發聚#1 臺北 2013/5/26
\#55
iOS Dev Club 環島開發聚#2 新竹 2013/6/29
\#56
iOS Dev Club 環島開發聚#3 高雄 2013/07/27
\#57
iOS Dev Club 環島開發聚#6 臺北 2013/11/30
\#58
WWDC 2014 研習分享 2014/06/28
\#59
Apple 9/9 發表會後的設計須知 開發者的頭豈止於大 2014/09/27
\#60
Apple 9/9 發表會後的設計須知 開發者的頭豈止於大 2014/09/27
\#61
然後我們來介紹 iOS Dev Club 一些資源
\#62
這是我們的官方網站
http://iosdev.club
\#63
粉絲團
請加入我們
http://www.facebook.com/groups/iostw/
\#64
youtube 頻道
會把我們活動的錄影放在這
http://www.youtube.com/user/iOSDevClub
\#65
我們的 GitHub
http://github.com/iOSDevClub
\#66
我們的理念是這樣
不用害怕問問題
你的問題 可能也是許多人的問題
我們社群的氣氛很棒 大家都很熱心
解決問題的時候
記得回來分享自己的心得
分享的內容不在乎難易、深淺、長短
這是一個很融洽的大家庭
\#67
最後
小弟 在台中資策會 有開 Swift 課程
http://taichung.iiiedu.org.tw/swift.html
這個課程通過
勞動部職訓局青年就業讚計劃
凡未滿29歲 失業三個月以上者
享全額補助
明天也別忘記 高見龍 龍哥 的 Swift 議程
\#68
這是我的 twitter 跟 email
有問題歡迎寫 mail 跟我討論
謝謝各位參加!
http://mopcon.org/2014/speakers.php#evillon
|