Slide 1

Slide 1 text

Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ ॴ ༑ଠ @tokorom iOS App Programer Reactive Swift Meetup

Slide 2

Slide 2 text

ॴ༑ଠ @tokorom ɾϑϦʔλʔ ɾΧοίѱ͍ϦΞΫςΟϒ෩ϓϩάϥϚ ɾpotatotipsӡӦ૭ޱʢओ࠵ऀ͞Μ͍ͭ΋ืूதʣ

Slide 3

Slide 3 text

ΧοίΠΠ ϦΞΫςΟϒϓϩάϥϛϯά FRP RxSwift ReSwift Redux Flux

Slide 4

Slide 4 text

ʢ࣭໰ʣ •͓࢓ࣄͰ͸ɺطଘϓϩδΣΫτͷόʔδϣϯΞο ϓ͕ϝΠϯʁ •൒೥ʹҰճ͘Β͍৽نϓϩδΣΫτʹθϩ͔Β ܞΘΕΔ޾ͤऀʁ

Slide 5

Slide 5 text

΅͘ͷϦΞΫςΟϒϓϩάϥϛϯάʁ •ϓϩδΣΫτ։࢝࣌͸͘͝ී௨ͷMVCߏ੒ •όʔδϣϯΞοϓ࣌ʹϦΞΫςΟϒϓϩάϥϛ ϯά༻ϥΠϒϥϦಋೖ •ϦϦʔεؒࡍʹύϑΥʔϚϯε໰୊ൃ֮ •RxSwiftʹࠩ͠ସ͑ •ݱঢ়ɺ҆ఆಈ࡞ •ؾʹೖͬͯΔ

Slide 6

Slide 6 text

ී௨ͷMVCߏ੒ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController

Slide 7

Slide 7 text

ී௨ͷMVCߏ੒ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController XXXManager໋໊ͬͯͲ͏ͳͷ !?

Slide 8

Slide 8 text

ී௨ͷMVCߏ੒ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController Topic Topic Topic

Slide 9

Slide 9 text

ී௨ͷMVCߏ੒ •ModelManager UserManager TopicManager XXXManager XXXViewController XXXViewController Topic Topic Topic

Slide 10

Slide 10 text

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ʂ

Slide 11

Slide 11 text

topic.rx_observe(Bool.self, "isHearted") .subscribeNext { [weak self] in self?.heartButton?.selected = $0 ?? false } //.addDisposableTo(disposeBag) Modelͷߋ৽Λ؂ࢹ •؂ࢹଆαϯϓϧʢViewʣ ͑ͬ!? ViewModel ͸?

Slide 12

Slide 12 text

Θ͍Θ͍ ϦΞΫςΟϒ ϓϩάϥϛϯά ͩͬʂʂʂ ͜Ε͸ ϦΞΫςΟϒ ϓϩάϥϛϯά ͳͷʂʁ

Slide 13

Slide 13 text

KVO + αʁ •΍͍ͬͯΔ͜ͱݟฦͨ͠ΒɺͨͩKVOͰViewͱ ModelΛόΠϯσΟϯάͯ͠Δ͚ͩ •debounce ͱ͔ distinctUntilChanged ͱ͔ Rxతศརػೳ΋͋ΔͷͰRxSwift࢖͏ํָ͕͸ָ •Ͱ΋໾ʹཱͭͳΒͦΕͰྑ͍ʁ ͳΜ͔Χοίѱ͍͚ͲͶ

Slide 14

Slide 14 text

໾ʹཱͭʢ۩ମతʹ͸ʁʣ •όά͕ݮΔ? ɹ=> ݮͬͨʂ •࣮૷ָ͕ʹͳΔ? => ָʹͳͬͨʂ

Slide 15

Slide 15 text

࣮ࡍʹྑ͍ޮՌ͕͋ͬͨͱ͜Ζ •ࢄΒ͹ΔὑͪΌΜ໰୊ͷղܾ •௨৴઀ଓ෮׆͞Μ໰୊ͷղܾ

Slide 16

Slide 16 text

ࢄΒ͹ΔὑͪΌΜ໰୊ •ৄࡉը໘Ͱὑͯ͠Ϧετը໘ʹ໭ͬͨΒʁ

Slide 17

Slide 17 text

ࢄΒ͹ΔὑͪΌΜ໰୊ •ϕλͳ࣮૷ •viewWillAppear + visibleCellsͰὑ͞Ε͍ͯΔ͔ νΣοΫ •cellForRowAtIndexPathͰὑ͞Ε͍ͯΔ͔νΣοΫ •willDisplayCellͰὑ͞Ε͍ͯΔ͔νΣοΫ

Slide 18

Slide 18 text

ࢄΒ͹ΔὑͪΌΜ໰୊ •ὑ͢Δ௨৴தʹը໘ભҠͪ͠ΌͬͨΒʁ

Slide 19

Slide 19 text

ࢄΒ͹ΔὑͪΌΜ໰୊ •ϕλͳ࣮૷ •௨৴੒ޭ࣌ʹNSNotificationͰ௨஌͢Δʁ

Slide 20

Slide 20 text

ࢄΒ͹ΔὑͪΌΜ໰୊ •RxSwiftͳΒͳʹ΋ߟ͑ͳ͍͍ͯ͘ topic.rx_observe(Bool.self, "isHearted") .subscribeNext { [weak self] in self?.heartButton?.selected = $0 ?? false } //.addDisposableTo(disposeBag) ܁Γฦ͚͢ͲɺͨͩͷKVO͔ͩΒͶ

Slide 21

Slide 21 text

௨৴઀ଓ෮׆͞Μ໰୊ •௨৴ΤϥʔͰίϯςϯπະऔಘͷ͚࣌ͩɺ௨৴ ઀ଓ෮׆ޙʹίϯςϯπ࠶औಘ͍ͨ͠

Slide 22

Slide 22 text

௨৴઀ଓ෮׆͞Μ໰୊ •ϕλͳ࣮૷ •௨৴઀ଓ෮׆ΛNSNotificationͳͲͰϋϯυϦϯά •ͦͷͱ͖ίϯςϯπऔಘࣦഊޙͰɺ͔ͭɺطʹ௨৴ தͰͳ͚Ε͹௨৴Λ࠶౓૸ΒͤΔ •։ൃ͍ͯ͠Δͱ͞Βʹ৚͕݅ՃΘͬͯ͘Δ •௨৴։࢝ͷτϦΨʔͱ৚͕݅͹Β͚ͯ൥ࡶʹͳΓ͕ ͪ

Slide 23

Slide 23 text

௨৴઀ଓ෮׆͞Μ໰୊ •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() }

Slide 24

Slide 24 text

ϦΞΫςΟϒ෩ϓϩάϥϛϯά Ͱ΋ޮՌ͋Γͦ͏ :) Ͱ΋Χοίѱ͍͚ͲͶ

Slide 25

Slide 25 text

Χοίѱࣦ͘ഊͨ͠ͱ͜Ζ •উखʹߋ৽ͪΌΜ໰୊ •εΫϩʔϧ͔͔ͬ͘͘Μ໰୊

Slide 26

Slide 26 text

উखʹߋ৽ͪΌΜ໰୊ •ͱ͋Δը໘Λ։͍ͨޙʹҙਤͤͣ಺༰͕มΘΔ

Slide 27

Slide 27 text

উखʹߋ৽ͪΌΜ໰୊ •͜ͷྫ͸୯ʹόΠϯσΟϯά͕ෆద੾ͳ͚ͩ •ϓϩΞΫςΟϒ →ϦΞΫςΟϒͳΒͰ͸ͷෆ۩ ߹͕͋Δ͜ͱ͸͋Δ •ͨͩ͠ϓϩΞΫςΟϒΦϯϦʔͷ࣌ͷෆ۩߹ͷ ΄͏͕ଟ͍

Slide 28

Slide 28 text

εΫϩʔϧ͔͔ͬ͘͘Μ໰୊ •͍͟ಈ͔ͯ͠ΈͨΒύϑΥʔϚϯεѱ͍ •UICollectionViewCellʹରͯ͠εΫϩʔϧͷ౓ʹ όΠϯσΟϯάͷॲཧ͕૸ΔͨΊ •͜Ε͕ղܾͰ͖ͳͯ͘RxSwiftΛಋೖͨ͠ΒͳΜ ͱ͔ͳͬͨ

Slide 29

Slide 29 text

εΫϩʔϧ͔͔ͬ͘͘Μ໰୊ •ར༻͢ΔϥΠϒϥϦ΍࣮૷ͷ͔ͨ͠ʹΑͬͯม Θͬͯ͘ΔͷͰࣄલʹςετ •ྫ͑͹ࠜݩ͸ࣗ෼ͷ޷͖ͳ࣮૷ʹͯ͠ɺόΠϯ σΟϯάͷͱ͜Ζ͚ͩSwiftBondΛར༻͢Δͱ ͍ͬͨղܾͷํ๏΋ߟ͑ΒΕΔ

Slide 30

Slide 30 text

࣮ࡍʹϓϩδΣΫτͰ࢖ͬͯΈͯͷॴײ •࣮૷͕γϯϓϧʹͳͬͨ •ಛʹෳ਺ͷλΠϛϯά΍৚݅ʹΑΓ࣮ߦ͢΂͖ॲཧ •ෆ۩߹͕50%Ҏ্ݮ͍ͬͯΔͷͰ͸ʢମײʣ •ࠓޙɺϦΞΫςΟϒͳ࣮૷Λ࢖Θͳ͍͜ͱ͸ߟ ͑ͮΒ͍

Slide 31

Slide 31 text

Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ

Slide 32

Slide 32 text

มΘ͍ͬͯ͘͜ͱ •ઈࢍਐԽத •ReactKit / SwiftBond / RxSwift •The Evolution of Flux Framework (2015೥5݄ʣ •SwiftFlux / Swift Flow / ReduxKit / ReSwift •̍೥ޙʹ͸·ͩݟ͵ϥΠϒϥϦ࢖ͬͯΔʁ •RxSwift͸ྑ͍ײ͡ʹރΕ͖ͯͯΔ͔΋

Slide 33

Slide 33 text

ΩʔϫʔυͷτϨϯυ •MVVM •React / Flux / Redux •ϨΨγʔͳModelManager + KVO ʹࣅͯΔʁ

Slide 34

Slide 34 text

มΘΒͳ͍͜ͱ •ϦΞΫςΟϒͷ༗༻ੑ •ϓϩΞΫςΟϒͷ༗༻ੑ

Slide 35

Slide 35 text

ऄ଍ •KVOͱ͔ݹ͍࢓૊Έʁ࢖͏ͷͬͯͲ͏ͳͷʁ •ΠϯλʔϑΣʔεͳͲ͸͔֬ʹݹ͍͕ར༻͢Δ ͷ͸ѱ͘ͳ͍ͷͰ͸ •ͨͩɺiOS͕ඪ४Ͱඋ͑Δ΋ͷͰ།Ұແೋͳϝ Ϧοτ͕͋ͬͨΓ͢Δ •ϥοϐϯάͳͲͯ͠ར༻͢Δ͜ͱͰΠϯλʔ ϑΣʔεͷ໰୊͸؇࿨Ͱ͖Δ෦෼΋͋Δ

Slide 36

Slide 36 text

KVO •ίϯύΠϧ࣌ʹ͸keyPathޡΓΛൃݟͰ͖ͳ͍ •ղܾํ๏͸͋ΔͩΖ͏͚Ͳ… •࣮ߦ࣌ʹ͸Exception͕ൃੜ͢Δ: addObserver: forKeyPath:@"hoge" options: 5 context:0x0] … •ύϑΥʔϚϯε͸ྑ͘লϝϞϦ

Slide 37

Slide 37 text

sendAction (Responder Chain) •RxSwiftʹ૊Έࠐ·Εͯ͸͍ͳ͍͕ϥοϐϯά͠ ͯར༻͢Ε͹ϝϦοτ͕ग़ͯ͘Δ͔΋͠Εͳ͍ʁ

Slide 38

Slide 38 text

UIApplication - sendAction NEW! iOS 9 Ͱ ྲྀ੕ ͷ͝ͱ͘ݱΕͨ ࠷ڧ ͷ function !?

Slide 39

Slide 39 text

UIApplication - sendAction iPhone OS 2 ͔Β ͘͝ ී௨ ʹଘࡏ͢Δ ͋·Γ ࢖ΘΕͳ͍ ΍ͭ

Slide 40

Slide 40 text

Responder Chain (in UIKit) •Ԟ·ͬͨ֊૚ͰൃՐ •֊૚ͷͲ͜Ͱ΋ड͚ΒΕΔ •DelegateͷΑ͏ʹreceiverΛड͚ ౉͢ඞཁ͕ͳ͍ •ଞखஈͰಉ͡ߏ଄Λ࣮ݱ͢Δͷ͸ ೉͍͠

Slide 41

Slide 41 text

Responder Chain (in UIKit) UITabBarController UIViewController UITabBarController UIViewController UIViewController UIViewController UITableView UITableViewCell UIView UIButton

Slide 42

Slide 42 text

sendActionͷμϝͳͱ͜Ζ •ΠϯλʔϑΣʔε͕ݹ͍ •Selector(จࣈྻ)ࢦఆ •ܾ·ͬͨҾ਺ͷϝιουͰ͔͠௨஌Λड͚ΒΕ ͳ͍ •ಛఆͷObjectΛ౉ͮ͠Β͍

Slide 43

Slide 43 text

sendAction + Rx // HogeΛ؂ࢹ self.rx_action(Int.self, .Hoge) .subscribeNext { NSLog("context: \($0 ?? 0)") //< 100 } //.addDisposableTo(disposeBag) // HogeΛൃՐ self.sendActionForKey(.Hoge, context: 100)

Slide 44

Slide 44 text

·ͱΊ •ϨΨγʔͳϓϩδΣΫτʹϦΞΫςΟϒͳཁૉ ΛऔΓೖΕΔͷ΋ҙ֎ͱ؆୯ˍҰఆҎ্ͷޮՌ ͕ݟࠐΊΔ •KVOͳͲݹ͖ྑ͖࢓૊Έ΋৔߹ʹΑͬͯ͸༗༻ ͳબ୒ࢶ

Slide 45

Slide 45 text

Χοίѱ͘ ϦΞΫςΟϒ ͡ΌμϝͰ͔͢ʁ μϝ͡Όͳ͍ͬ!!

Slide 46

Slide 46 text

More Information Yuta ToKoRo iOS App Programer Twitter @tokorom http://www.tokoro.me/