Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Fluxで複雑な状態の変化を予測可能にするiOSアプリ開発
Search
Kenichi Yonekawa
April 13, 2016
Programming
9
19k
Fluxで複雑な状態の変化を予測可能にするiOSアプリ開発
Reactive Swift Meetup
http://wantedly.connpass.com/event/29039/
Kenichi Yonekawa
April 13, 2016
Tweet
Share
More Decks by Kenichi Yonekawa
See All by Kenichi Yonekawa
iOSアプリの設計とDependency Injection
yonekawa
22
16k
ネイティブアプリでもFluxしたい
yonekawa
0
2.1k
freeeモバイルチームの変遷と進化
yonekawa
0
7.4k
ReactiveCocoa Pitfalls at freee
yonekawa
2
830
RAC用クラス拡張の作り方
yonekawa
2
2.9k
Dive into Joybox
yonekawa
5
1.7k
Other Decks in Programming
See All in Programming
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
cmp.Or に感動した
otakakot
3
200
Why Jakarta EE Matters to Spring - and Vice Versa
ivargrimstad
0
1.2k
みんなでプロポーザルを書いてみた
yuriko1211
0
280
イベント駆動で成長して委員会
happymana
1
340
初めてDefinitelyTypedにPRを出した話
syumai
0
420
Snowflake x dbtで作るセキュアでアジャイルなデータ基盤
tsoshiro
2
520
Jakarta EE meets AI
ivargrimstad
0
150
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
Functional Event Sourcing using Sekiban
tomohisa
0
100
受け取る人から提供する人になるということ
little_rubyist
0
250
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
510
110k
What's new in Ruby 2.0
geeforr
343
31k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
840
Designing Experiences People Love
moore
138
23k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
The World Runs on Bad Software
bkeepers
PRO
65
11k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Speed Design
sergeychernyshev
25
620
Scaling GitHub
holman
458
140k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Transcript
@yonekawa 'MVYͰෳࡶͳঢ়ଶͷมԽΛ ༧ଌՄೳʹ͢ΔJ04ΞϓϦ։ൃ
None
None
GSFFFͷJ04ΞϓϦ
https://itunes.apple.com/jp/app/id811207074
ಛతͳ՝ • ͋ΔೖྗબʹΑͬͯՃͷϑΥʔϜ͕දࣔ/ඇදࣔʹ ͳͬͨΓ͢Δέʔε͕ଟ͘ɺViewͷঢ়ଶཧ͕ෳࡶ • 1ͭͷσʔλมߋॲཧʹରͯ͠ෳͷϞσϧ͕ؔ࿈͠ɺґଘ ͠߹͏͜ͱ͕ଟ͍ • ΞϓϦͱͯ͠ͷػೳͷଟ͞ɺͦΕΒ͕૬ޓʹؔ࿈͋͠͏ը໘ ભҠͷෳࡶ͞
MVVMͷ࠾༻ • ViewModelͰViewͷঢ়ଶͱϏδωεϩδοΫΛཧ • ReactiveCocoaͷRACSignalΛView͕subscribeͯ͠ঢ়ଶΛ όΠϯσΟϯά͢Δ • ViewModelʹมԽ͕ى͖Δͱ֘ͷϓϩύςΟͷมߋ͕ RACSignalʹΑͬͯ௨͞ΕɺView͕Ԡ͢Δ
ViewController ViewModel APIClient ߏ VIEW VIEW View ϝιουݺͼग़͠ RACSignal VIEW
VIEW Model
ݱঢ়ͷ՝ • ΞϓϦͷن͕େ͖͘ͳΔʹͭΕͯɺUIΠϕϯτγεςϜ ΠϕϯτʹΑΔঢ়ଶͷมԽΛཧͰ͖ͳ͘ͳ͖ͬͯͨ • ViewModelͱͷํόΠϯσΟϯάʹΑΔґଘؔͷ ༧ଌͷͮ͠Β͞ • ঢ়ଶͷཧͱϞσϧͷૢ࡞ͱυϝΠϯϩδοΫ͕ີ݁߹ •
Ͳ͜Ͱ୭ʹΑͬͯԿ͕มΘͬͯࠓͲ͏ͳͬͯΔͷ͔͕͍͔ ͚ͮΒ͍
WebϑϩϯτΤϯυ͔ΒֶͿ • JavaScriptͷੈքͰMVVM (2way-binding) ͏·͘ड͚ ೖΕΒΕͳ͔ͬͨ • ReactͷొʹΑͬͯΞʔΩςΫνϟͷτϨϯυFluxΛݩ ʹͨ͠୯ํϑϩʔ
Flux facebook/flux: Application Architecture for Building User Interfaces
ΑΓྑ͍ΞʔΩςΫνϟͷԾઆ • WebϑϩϯτΤϯυͷྺ࢙͔ΒɺfreeeΞϓϦ๊͕͍͑ͯΔ ํόΠϯσΟϯάͷຊ࣭తͳͳͷͰ • ୯ํϑϩʔͷίϯηϓτiOSʹ͓͍ͯViewͷঢ়ଶཧ Λ៉ྷʹ͢ΔͨΊʹ༗༻ͳͷͰ
'MVYͷ࠾༻
جຊϑϩʔ • Viewͷঢ়ଶΛStore͕࣋ͪɺStoreActionͷൃߦΛͪड ͚Δ • StoreΛ֎෦͔Βมߋ͢Δ͜ͱͰ͖ͣɺdispatch͞Εͨ ActionʹԠͯࣗ͡Ͱมߋ͢ΔͷΈ • StoreͦΕ͕มߋ͞Εͨ͜ͱͷΈΛViewʹ௨͢Δ •
มߋ͞ΕͨࠩΛૹͬͨΓ͠ͳ͍ • ViewৗʹStoreͷ࠷৽ͷঢ়ଶ͔Βߏங͞ΕΔ
։ൃํ • جຊతʹViewControllerͱ1:1ͰStoreΛ࡞Γঢ়ଶΛཧ͢Δ • ΞϓϦέʔγϣϯશମͷঢ়ଶʢೝূ͍ͯ͠Δͱ͔ʣΛཧ͢Δ StoreΛ࡞Γɺάϩʔόϧʹอ࣋͢Δ • APIϦΫΤετActionCreatorͰߦ͍ɺ݁ՌΛActionͷ Payloadͱͯ͠Storeʹड͚͢ •
Realm(DB)ͷอଘΞϓϦέʔγϣϯͷঢ়ଶมԽͱΈͳ͠ StoreͰߦ͏
Store ViewController Store ViewController ߏ Dispatcher Action Action Store Store
(Global) Store ViewController ActionCreator Action Action Application
ϥΠϒϥϦԽ • https://github.com/yonekawa/SwiftFlux • DispatcherͱͦΕʹඥͮ͘Action/StoreͷநԽ • ReduceStoreͱ͔Flux UtilsҰ෦࣮ͯ͠Δ • ϓϩτίϧࢦͰSwiftΒ͠͞Λҙࣝͨ͠
struct FetchTodo: Action { typealias Payload = [Todo] func invoke(dispatcher:
Dispatcher) { Session.sendRequest(FetchTodoRequest()) { result in switch result { case .Success(let todos): dispatcher.dispatch(self, result: Result(value: todos)) case .Failure(let error): dispatcher.dispatch(self, result: Result(error: error)) } } } } Action
class TodoStore: StoreBase { private(set) var todos: [Todo] private(set) var
error: Error? func init() { register(FetchTodo.self) { (result) in switch result { case .Success(let todos): error = nil self.todos = payload emitChange() case .Failure(let error): self.error = error emitChange() } } } } Store
class ViewController: UITableViewController { let store = TodoStore() func viewDidLoad()
{ super.viewDidLoad() store.subscribe { () in tableView.reloadData() } ActionCreator.invoke(FetchAction()) } } ViewController
࣮ઓೖ https://itunes.apple.com/jp/app/id1037197002
ϝϦοτ • ViewৗʹStore͔Βશͯߏங͞ΕΔͷͰɺݱࡏͷViewͷঢ় ଶ͕໌ࣔతʹͳΓݟ௨͕͠Α͘ͳΔ • StoreΛߋ৽͢ΔͷStore͔ࣗ͋͠Γಘͳ͍ͷͰɺঢ়ଶͷ มԽ֘ͷAction͕ൃߦ͞Ε͔ͨΛ͏͚ͩͰΑ͍ • APIϦΫΤετͷঢ়ଶΛม͑ಘΔϩδοΫͱঢ়ଶΛཧ͢ ΔॴΛ໌֬ʹ͚ΒΕΔ
Viewͷࠩߋ৽ • SwiftͷੈքʹReact͕ଘࡏ͠ͳ͍ɻͦΕͬΆ͍ͷ͍͘ ͔ͭ͋Δ͕Viewͷ࡞Γํ͕ಠࣗʹͳ͓ͬͯΓɺUIKit͕ఏڙ ͢Δͷ͔Β֎ΕΔͷϦεΫ͕ߴ͍ • ViewΛຖճ࠶ߏங͢Δͷίετ͕͔͔ΔͷͰࠩߋ৽͕ ඞཁɻ͔͠͠ؾΛ͚ͭͳ͍ͱঢ়ଶΛ࡞ͬͯ͠·͏ɻ • UITableViewͳͲΛ͏·ࠩ͘ߋ৽͢Δ൚༻తͳΈ͕΄
͍͠
ίʔυྔ૿͑Δ • ঢ়ଶΛม͑ΔͨΊʹຖճActionͱStoreʹ࣮͕ඞཁ • ୯७ͳೖྗͷөͳͲຖճDispatcherΛܦ༝ͯ͠Store ૹΔͷͰʹͳΔ • ঢ়ଶΛཧ͢ΔͨΊͷखؒͱͯ͋͠Δఔ͔ͨ͠ͳ͍
Τϥʔॲཧ • ActionΛ࡞Δͱ͖ʹൃੜͨ͠ΤϥʔΛͲ͏ѻ͏͖͔ɻࠓ Τϥʔը໘ͷঢ়ଶͷ̍ͭͱͯ͠Storeʹ͍ͯ͠Δ • SVProgressHUDͷΑ͏ͳग़͙ͯ͢ফ͑ΔUIΛ͏߹ɺ Store͕࣋ͭΤϥʔঢ়ଶΛஞҰϦηοτ͢Δͷ͕໘
Ξχϝʔγϣϯ • ۪ʹΔͱ͍͢͝ճͷϑϩʔ͕ճΔ • Ξχϝʔγϣϯͷ։࢝ͱऴྃΛঢ়ଶͱͯ͠ཧ͢Δ͖ʁ • ReactͰ͜Εঢ়ଶཧͷର֎ͱ͍ͯ͠Δ༷ࢠ
'MVYWT3FEVY
Redux • ΞϓϦέʔγϣϯͷঢ়ଶ1ͭͷStoreΦϒδΣΫτ͕ཧ ͢Δ • StateϦʔυΦϯϦʔͰActionͷൃߦʹΑͬͯͷΈมߋ͞ ΕಘΔ • ঢ়ଶͷભҠͨͩͷؔ(Reducer)ʹΑͬͯߦ͏
ReduxͷϝϦοτ • Store͕1͔ͭ͠ଘࡏ͠ͳ͍ͨΊɺঢ়ଶ͕มΘΔॴ͕ΑΓ ݶఆ͞Εͯݟ௨͘͢͠ͳΔ • ҰՕॴͰશͯͷঢ়ଶ͕มΘΔͨΊɺશͳมߋͷཤྺΛอ ࣋Ͱ͖Δ͜ͱʹΑΓɺUndo/RedoͳͲ༰қ • Reducerؔલͷঢ়ଶʹॲཧΛՃ͑ͯ৽͍͠ঢ়ଶΛฦͩ͢ ͚ͳͷͰςετ͍͢͠
Redux or Flux? • جຊతʹReduxͷSingle State TreeΑΓྑ͍ঢ়ଶཧͷ ΈΛఏڙͯ͘͠ΕΔͷͰΑ͍ • ReduxSingle
State TreeΛલఏʹσβΠϯ͞Ε͍ͯΔͷ ͰɺΞϓϦέʔγϣϯશମΛͦΕલఏʹ࡞Βͳ͍ͱ͍͚ͳ͍ • Flux੍͕؇͍ͷͰɺෳࡶͳUIΛ෦తʹஔ͖͑ΔͳͲ طଘͷΞϓϦʹೖΕ͍͢
ReSwift • https://github.com/ReSwift/ReSwift • ReduxͷSwift࣮ • ৄ͘͠ninjinkun͞Μ͕ͯ͘͠ΕΔͱࢥ͍·͢ɻ
·ͱΊ
·ͱΊ • ୯ํϑϩʔͷΞʔΩςΫνϟViewͷঢ়ଶΛݟ௨͢͠ ͯ͘͘͠ΕΔͷͰiOSʹ͓͍ͯϝϦοτ͕͋Δ • React͕ແ͍ͨΊStoreͷঢ়ଶ͔ΒޮΑ͘ViewΛ࡞Δͱ͜ Ζʹ՝͕͋Δ͕ɺͷ༨͋Γͦ͏ • ϥΠϒϥϦࠓͷͱ͜ΖReSwift͕ຊ໋͕ͩɺطଘΞϓϦʹ ద༻͢ΔͳΒγϯϓϧͳFlux͋Γ
SwiftFluxͷࠓޙͷల • ͬͱܕ҆શʹͰ͖ΔΑ͏ʹΠϯλϑΣʔεΛݟ͍ͨ͠ • ෳͷStoreΛଋͶͯཧͰ͖ΔStoreGroupతػೳ • ൚༻తͳࠩߋ৽ͷͨΊͷUIϢʔςΟϦςΟ