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
カッコ悪くリアクティブじゃダメですか?
Search
tokorom
April 13, 2016
Technology
7
12k
カッコ悪くリアクティブじゃダメですか?
レガシーな既存プロジェクトへのRxSwift導入事例
tokorom
April 13, 2016
Tweet
Share
More Decks by tokorom
See All by tokorom
CursorでアプリをBuild/Lint
tokorom
0
140
続・SharePlayの歴史と進化 iOS18とApple Vision Proにおける新展開
tokorom
3
830
SharePlayの歴史と進化 そしてvisionOSへ (iOSDC 2023)
tokorom
3
990
5分でSharePlay入門
tokorom
3
1.5k
HomeKit 2020
tokorom
7
2.5k
Advanced Segue 2019年のSegue事情
tokorom
9
6k
tvOSアプリUIの勘所
tokorom
1
2.1k
古き良きsendAction (in potatotips #26)
tokorom
1
3.7k
画面遷移と私(iOS)
tokorom
4
3.8k
Other Decks in Technology
See All in Technology
新卒から4年間、20年もののWebサービスと向き合って学んだソフトウェア考古学 - PHPカンファレンス新潟2025 / new graduate 4year software archeology
oguri
2
260
それでもぼくらは貢献をつづけるのだ(たぶん) @FOSS4GLT会#002
furukawayasuto
1
240
Postman AI エージェントビルダー最新情報
nagix
0
120
MCP で繋ぐ Figma とデザインシステム〜LLM を使った UI 実装のリアル〜
kimuson
1
940
オープンソースのハードウェアのコンテストに参加している話
iotengineer22
0
120
大規模PaaSにおける監視基盤の構築と効率化の道のり
lycorptech_jp
PRO
0
130
toittaにOpenTelemetryを導入した話 / Mackerel APM リリースパーティ
cohalz
1
170
オープンソースとビジネス: 位置情報の世界からみえる流れ / 札幌IT石狩鍋#2
sorami
0
220
熱々🔥のUDN🍜を喰らえ❗マルチテナントもVM統合も思いのまま❗新機能で切り拓くk8sネットワークの未来
tsukaman
0
190
金融システムをモダナイズするためのAmazon Elastic Kubernetes Service(EKS)ノウハウ大全
daitak
0
100
アプリケーションの中身が見える!Mackerel APMの全貌と展望 / Mackerel APMリリースパーティ
mackerelio
0
120
主要ライブラリの実例に学ぶ、TypeScriptで実現する型安全な座標定義
tiroljpn
1
220
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
137
33k
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.4k
GraphQLとの向き合い方2022年版
quramy
46
14k
Gamification - CAS2011
davidbonilla
81
5.3k
Producing Creativity
orderedlist
PRO
345
40k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
122
52k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
42
2.3k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
52
2.8k
Transcript
Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ ॴ ༑ଠ @tokorom iOS App Programer Reactive
Swift Meetup
ॴ༑ଠ @tokorom ɾϑϦʔλʔ ɾΧοίѱ͍ϦΞΫςΟϒ෩ϓϩάϥϚ ɾpotatotipsӡӦ૭ޱʢओ࠵ऀ͞Μ͍ͭืूதʣ
ΧοίΠΠ ϦΞΫςΟϒϓϩάϥϛϯά FRP RxSwift ReSwift Redux Flux
ʢ࣭ʣ •͓ࣄͰɺطଘϓϩδΣΫτͷόʔδϣϯΞο ϓ͕ϝΠϯʁ •ʹҰճ͘Β͍৽نϓϩδΣΫτʹθϩ͔Β ܞΘΕΔͤऀʁ
΅͘ͷϦΞΫςΟϒϓϩάϥϛϯάʁ •ϓϩδΣΫτ։࢝࣌͘͝ී௨ͷMVCߏ •όʔδϣϯΞοϓ࣌ʹϦΞΫςΟϒϓϩάϥϛ ϯά༻ϥΠϒϥϦಋೖ •ϦϦʔεؒࡍʹύϑΥʔϚϯεൃ֮ •RxSwiftʹࠩ͠ସ͑ •ݱঢ়ɺ҆ఆಈ࡞ •ؾʹೖͬͯΔ
ී௨ͷMVCߏ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController
ී௨ͷMVCߏ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController XXXManager໋໊ͬͯͲ͏ͳͷ !?
ී௨ͷMVCߏ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController Topic Topic Topic
ී௨ͷMVCߏ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController Topic Topic Topic
class Topic { let identifier: String var title: String? var
isHearted: Bool } Modelͷߋ৽Λࢹ •Μͩ݁Ռ -> ModelΛ KVO class Topic: NSObject { let identifier: String dynamic var title: String? dynamic var isHearted: Bool } ग़ͨʔʂ Swift࣌ʹ NSObjectʂ
topic.rx_observe(Bool.self, "isHearted") .subscribeNext { [weak self] in self?.heartButton?.selected = $0
?? false } //.addDisposableTo(disposeBag) Modelͷߋ৽Λࢹ •ࢹଆαϯϓϧʢViewʣ ͑ͬ!? ViewModel ?
Θ͍Θ͍ ϦΞΫςΟϒ ϓϩάϥϛϯά ͩͬʂʂʂ ͜Ε ϦΞΫςΟϒ ϓϩάϥϛϯά ͳͷʂʁ
KVO + αʁ •͍ͬͯΔ͜ͱݟฦͨ͠ΒɺͨͩKVOͰViewͱ ModelΛόΠϯσΟϯάͯ͠Δ͚ͩ •debounce ͱ͔ distinctUntilChanged ͱ͔ Rxతศརػೳ͋ΔͷͰRxSwift͏ํָָ͕
•ͰʹཱͭͳΒͦΕͰྑ͍ʁ ͳΜ͔Χοίѱ͍͚ͲͶ
ʹཱͭʢ۩ମతʹʁʣ •όά͕ݮΔ? ɹ=> ݮͬͨʂ •ָ࣮͕ʹͳΔ? => ָʹͳͬͨʂ
࣮ࡍʹྑ͍ޮՌ͕͋ͬͨͱ͜Ζ •ࢄΒΔὑͪΌΜͷղܾ •௨৴ଓ෮׆͞Μͷղܾ
ࢄΒΔὑͪΌΜ •ৄࡉը໘Ͱὑͯ͠Ϧετը໘ʹͬͨΒʁ
ࢄΒΔὑͪΌΜ •ϕλͳ࣮ •viewWillAppear + visibleCellsͰὑ͞Ε͍ͯΔ͔ νΣοΫ •cellForRowAtIndexPathͰὑ͞Ε͍ͯΔ͔νΣοΫ •willDisplayCellͰὑ͞Ε͍ͯΔ͔νΣοΫ
ࢄΒΔὑͪΌΜ •ὑ͢Δ௨৴தʹը໘ભҠͪ͠ΌͬͨΒʁ
ࢄΒΔὑͪΌΜ •ϕλͳ࣮ •௨৴ޭ࣌ʹNSNotificationͰ௨͢Δʁ
ࢄΒΔὑͪΌΜ •RxSwiftͳΒͳʹߟ͑ͳ͍͍ͯ͘ topic.rx_observe(Bool.self, "isHearted") .subscribeNext { [weak self] in self?.heartButton?.selected
= $0 ?? false } //.addDisposableTo(disposeBag) ܁Γฦ͚͢ͲɺͨͩͷKVO͔ͩΒͶ
௨৴ଓ෮׆͞Μ •௨৴ΤϥʔͰίϯςϯπະऔಘͷ͚࣌ͩɺ௨৴ ଓ෮׆ޙʹίϯςϯπ࠶औಘ͍ͨ͠
௨৴ଓ෮׆͞Μ •ϕλͳ࣮ •௨৴ଓ෮׆ΛNSNotificationͳͲͰϋϯυϦϯά •ͦͷͱ͖ίϯςϯπऔಘࣦഊޙͰɺ͔ͭɺطʹ௨৴ தͰͳ͚Ε௨৴Λ࠶ΒͤΔ •։ൃ͍ͯ͠Δͱ͞Βʹ͕݅ՃΘͬͯ͘Δ •௨৴։࢝ͷτϦΨʔͱ͕݅Β͚ͯࡶʹͳΓ͕ ͪ
௨৴ଓ෮׆͞Μ •RxSwiftͳΒҰݩཧͰ͖Δ let a = Reachability.rx_reachable.asObservable() let b = rx_contentState.asObservable()
Observable.combineLatest(a, b) { ($0, $1) } .filter { reachable, contentState in reachable && contentState == .Unload } .subscribeNext { [weak self] _ in self?.reloadDataIfNeeded() }
ϦΞΫςΟϒ෩ϓϩάϥϛϯά ͰޮՌ͋Γͦ͏ :) ͰΧοίѱ͍͚ͲͶ
Χοίѱࣦ͘ഊͨ͠ͱ͜Ζ •উखʹߋ৽ͪΌΜ •εΫϩʔϧ͔͔ͬ͘͘Μ
উखʹߋ৽ͪΌΜ •ͱ͋Δը໘Λ։͍ͨޙʹҙਤͤͣ༰͕มΘΔ
উखʹߋ৽ͪΌΜ •͜ͷྫ୯ʹόΠϯσΟϯά͕ෆదͳ͚ͩ •ϓϩΞΫςΟϒ →ϦΞΫςΟϒͳΒͰͷෆ۩ ߹͕͋Δ͜ͱ͋Δ •ͨͩ͠ϓϩΞΫςΟϒΦϯϦʔͷ࣌ͷෆ۩߹ͷ ΄͏͕ଟ͍
εΫϩʔϧ͔͔ͬ͘͘Μ •͍͟ಈ͔ͯ͠ΈͨΒύϑΥʔϚϯεѱ͍ •UICollectionViewCellʹରͯ͠εΫϩʔϧͷʹ όΠϯσΟϯάͷॲཧ͕ΔͨΊ •͜Ε͕ղܾͰ͖ͳͯ͘RxSwiftΛಋೖͨ͠ΒͳΜ ͱ͔ͳͬͨ
εΫϩʔϧ͔͔ͬ͘͘Μ •ར༻͢ΔϥΠϒϥϦ࣮ͷ͔ͨ͠ʹΑͬͯม Θͬͯ͘ΔͷͰࣄલʹςετ •ྫ͑ࠜݩࣗͷ͖ͳ࣮ʹͯ͠ɺόΠϯ σΟϯάͷͱ͜Ζ͚ͩSwiftBondΛར༻͢Δͱ ͍ͬͨղܾͷํ๏ߟ͑ΒΕΔ
࣮ࡍʹϓϩδΣΫτͰͬͯΈͯͷॴײ •࣮͕γϯϓϧʹͳͬͨ •ಛʹෳͷλΠϛϯά݅ʹΑΓ࣮ߦ͖͢ॲཧ •ෆ۩߹͕50%Ҏ্ݮ͍ͬͯΔͷͰʢମײʣ •ࠓޙɺϦΞΫςΟϒͳ࣮ΛΘͳ͍͜ͱߟ ͑ͮΒ͍
Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ
มΘ͍ͬͯ͘͜ͱ •ઈࢍਐԽத •ReactKit / SwiftBond / RxSwift •The Evolution of
Flux Framework (20155݄ʣ •SwiftFlux / Swift Flow / ReduxKit / ReSwift •̍ޙʹ·ͩݟ͵ϥΠϒϥϦͬͯΔʁ •RxSwiftྑ͍ײ͡ʹރΕ͖ͯͯΔ͔
ΩʔϫʔυͷτϨϯυ •MVVM •React / Flux / Redux •ϨΨγʔͳModelManager + KVO
ʹࣅͯΔʁ
มΘΒͳ͍͜ͱ •ϦΞΫςΟϒͷ༗༻ੑ •ϓϩΞΫςΟϒͷ༗༻ੑ
ऄ •KVOͱ͔ݹ͍Έʁ͏ͷͬͯͲ͏ͳͷʁ •ΠϯλʔϑΣʔεͳͲ͔֬ʹݹ͍͕ར༻͢Δ ͷѱ͘ͳ͍ͷͰ •ͨͩɺiOS͕ඪ४Ͱඋ͑ΔͷͰ།Ұແೋͳϝ Ϧοτ͕͋ͬͨΓ͢Δ •ϥοϐϯάͳͲͯ͠ར༻͢Δ͜ͱͰΠϯλʔ ϑΣʔεͷ؇Ͱ͖Δ෦͋Δ
KVO •ίϯύΠϧ࣌ʹkeyPathޡΓΛൃݟͰ͖ͳ͍ •ղܾํ๏͋ΔͩΖ͏͚Ͳ… •࣮ߦ࣌ʹException͕ൃੜ͢Δ: addObserver:<RxCocoa.KVOObserver 0x7f8133b500b0> forKeyPath:@"hoge" options: 5 context:0x0]
… •ύϑΥʔϚϯεྑ͘লϝϞϦ
sendAction (Responder Chain) •RxSwiftʹΈࠐ·Ε͍ͯͳ͍͕ϥοϐϯά͠ ͯར༻͢ΕϝϦοτ͕ग़ͯ͘Δ͔͠Εͳ͍ʁ
UIApplication - sendAction NEW! iOS 9 Ͱ ྲྀ ͷ͝ͱ͘ݱΕͨ ࠷ڧ
ͷ function !?
UIApplication - sendAction iPhone OS 2 ͔Β ͘͝ ී௨ ʹଘࡏ͢Δ
͋·Γ ΘΕͳ͍ ͭ
Responder Chain (in UIKit) •Ԟ·ͬͨ֊ͰൃՐ •֊ͷͲ͜Ͱड͚ΒΕΔ •DelegateͷΑ͏ʹreceiverΛड͚ ͢ඞཁ͕ͳ͍ •ଞखஈͰಉ͡ߏΛ࣮ݱ͢Δͷ ͍͠
Responder Chain (in UIKit) UITabBarController UIViewController UITabBarController UIViewController UIViewController UIViewController
UITableView UITableViewCell UIView UIButton
sendActionͷμϝͳͱ͜Ζ •ΠϯλʔϑΣʔε͕ݹ͍ •Selector(จࣈྻ)ࢦఆ •ܾ·ͬͨҾͷϝιουͰ͔͠௨Λड͚ΒΕ ͳ͍ •ಛఆͷObjectΛͮ͠Β͍
sendAction + Rx // HogeΛࢹ self.rx_action(Int.self, .Hoge) .subscribeNext { NSLog("context:
\($0 ?? 0)") //< 100 } //.addDisposableTo(disposeBag) // HogeΛൃՐ self.sendActionForKey(.Hoge, context: 100)
·ͱΊ •ϨΨγʔͳϓϩδΣΫτʹϦΞΫςΟϒͳཁૉ ΛऔΓೖΕΔͷҙ֎ͱ؆୯ˍҰఆҎ্ͷޮՌ ͕ݟࠐΊΔ •KVOͳͲݹ͖ྑ͖Έ߹ʹΑͬͯ༗༻ ͳબࢶ
Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ μϝ͡Όͳ͍ͬ!!
More Information Yuta ToKoRo iOS App Programer Twitter @tokorom http://www.tokoro.me/