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
20k
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
17k
ネイティブアプリでもFluxしたい
yonekawa
0
2.3k
freeeモバイルチームの変遷と進化
yonekawa
0
7.7k
ReactiveCocoa Pitfalls at freee
yonekawa
2
850
RAC用クラス拡張の作り方
yonekawa
2
2.9k
Dive into Joybox
yonekawa
5
1.7k
Other Decks in Programming
See All in Programming
Rubyでやりたい駆動開発 / Ruby driven development
chobishiba
1
750
AIプログラマーDevinは PHPerの夢を見るか?
shinyasaita
1
240
初学者でも今すぐできる、Claude Codeの生産性を10倍上げるTips
s4yuba
16
12k
Deep Dive into ~/.claude/projects
hiragram
14
8.8k
Result型で“失敗”を型にするPHPコードの書き方
kajitack
5
970
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
410
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
5
1.4k
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
3
500
git worktree × Claude Code × MCP ~生成AI時代の並列開発フロー~
hisuzuya
1
590
AI時代のソフトウェア開発を考える(2025/07版) / Agentic Software Engineering Findy 2025-07 Edition
twada
PRO
96
34k
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
220
NPOでのDevinの活用
codeforeveryone
0
870
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
How to Think Like a Performance Engineer
csswizardry
25
1.7k
What's in a price? How to price your products and services
michaelherold
246
12k
Docker and Python
trallard
44
3.5k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Code Review Best Practice
trishagee
69
19k
The Straight Up "How To Draw Better" Workshop
denniskardys
235
140k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Testing 201, or: Great Expectations
jmmastey
43
7.6k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
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ϢʔςΟϦςΟ