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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
tokorom
April 13, 2016
Technology
7
13k
カッコ悪くリアクティブじゃダメですか?
レガシーな既存プロジェクトへのRxSwift導入事例
tokorom
April 13, 2016
Tweet
Share
More Decks by tokorom
See All by tokorom
CursorでアプリをBuild/Lint
tokorom
0
230
続・SharePlayの歴史と進化 iOS18とApple Vision Proにおける新展開
tokorom
3
1k
SharePlayの歴史と進化 そしてvisionOSへ (iOSDC 2023)
tokorom
3
1.2k
5分でSharePlay入門
tokorom
3
1.6k
HomeKit 2020
tokorom
7
2.7k
Advanced Segue 2019年のSegue事情
tokorom
9
6.3k
tvOSアプリUIの勘所
tokorom
1
2.3k
古き良きsendAction (in potatotips #26)
tokorom
1
3.8k
画面遷移と私(iOS)
tokorom
4
3.9k
Other Decks in Technology
See All in Technology
MySQLのJSON機能の活用術
ikomachi226
0
150
IaaS/SaaS管理における SREの実践 - SRE Kaigi 2026
bbqallstars
4
1.6k
CDKで始めるTypeScript開発のススメ
tsukuboshi
1
300
What happened to RubyGems and what can we learn?
mikemcquaid
0
230
Mosaic AI Gatewayでコーディングエージェントを配るための運用Tips / JEDAI 2026 新春 Meetup! AIコーディング特集
genda
0
150
あたらしい上流工程の形。 0日導入からはじめるAI駆動PM
kumaiu
5
750
外部キー制約の知っておいて欲しいこと - RDBMSを正しく使うために必要なこと / FOREIGN KEY Night
soudai
PRO
11
4.4k
会社紹介資料 / Sansan Company Profile
sansan33
PRO
15
400k
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
6
67k
SREが向き合う大規模リアーキテクチャ 〜信頼性とアジリティの両立〜
zepprix
0
380
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
10k
クレジットカード決済基盤を支えるSRE - 厳格な監査とSRE運用の両立 (SRE Kaigi 2026)
capytan
6
2.4k
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.3k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
66
36k
Abbi's Birthday
coloredviolet
1
4.7k
Color Theory Basics | Prateek | Gurzu
gurzu
0
190
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
450
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
71
How to Talk to Developers About Accessibility
jct
2
120
Thoughts on Productivity
jonyablonski
74
5k
How to build a perfect <img>
jonoalderson
1
4.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.3k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.2k
Facilitating Awesome Meetings
lara
57
6.7k
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/