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
170
続・SharePlayの歴史と進化 iOS18とApple Vision Proにおける新展開
tokorom
3
900
SharePlayの歴史と進化 そしてvisionOSへ (iOSDC 2023)
tokorom
3
1k
5分でSharePlay入門
tokorom
3
1.5k
HomeKit 2020
tokorom
7
2.6k
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
Introduction to Bill One Development Engineer
sansan33
PRO
0
260
cdk initで生成されるあのファイル達は何なのか/cdk-init-generated-files
tomoki10
1
670
ロールが細分化された組織でSREは何をするか?
tgidgd
1
420
CDK Vibe Coding Fes
tomoki10
1
630
Four Keysから始める信頼性の改善 - SRE NEXT 2025
ozakikota
0
410
第64回コンピュータビジョン勉強会「The PanAf-FGBG Dataset: Understanding the Impact of Backgrounds in Wildlife Behaviour Recognition」
x_ttyszk
0
240
Autify Company Deck
autifyhq
2
44k
三視点LLMによる複数観点レビュー
mhlyc
0
230
Deep Security Conference 2025:生成AI時代のセキュリティ監視 /dsc2025-genai-secmon
mizutani
4
2.9k
ポストコロナ時代の SaaS におけるコスト削減の意義
izzii
1
470
モニタリング統一への道のり - 分散モニタリングツール統合のためのオブザーバビリティプロジェクト
niftycorp
PRO
1
520
大量配信システムにおけるSLOの実践:「見えない」信頼性をSLOで可視化
plaidtech
PRO
0
390
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Building Adaptive Systems
keathley
43
2.7k
Code Review Best Practice
trishagee
69
19k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Writing Fast Ruby
sferik
628
62k
KATA
mclloyd
30
14k
Speed Design
sergeychernyshev
32
1k
Statistics for Hackers
jakevdp
799
220k
It's Worth the Effort
3n
185
28k
The Invisible Side of Design
smashingmag
301
51k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
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/