Slide 1

Slide 1 text

"CFNB57ʹ͓͚Δ J04ΞʔΩςΫνϟͷ՝୊ղܾ .77. 6OJP 'MVY :VTVLF.PSJTIJUB!ZZTTLL "CFNB57։ൃہωΠςΟϒج൫

Slide 2

Slide 2 text

"HFOEB wϓϩμΫτഎܠ wઃܭͷมભ wݱࡏͷ՝୊

Slide 3

Slide 3 text

ϓϩμΫτഎܠ

Slide 4

Slide 4 text

ϓϩμΫτഎܠ w೥݄͔Β։࢝ͯ͠ݱࡏ೥໨ wݱࡏ͸໊Ͱ։ൃ wϨϙδτϦ wJ04"QQ "1*ΫϥΠΞϯτ ϩάͷϞσ ϧʜFUD

Slide 5

Slide 5 text

ϓϩμΫτഎܠνʔϜਓ਺ ࣌ؒ ਓ਺ ্ཱͪ͛࣌

Slide 6

Slide 6 text

ઃܭͷมભ

Slide 7

Slide 7 text

ઃܭͷมભ wୈ̍ੈ୅'MVY wୈ̎ੈ୅.77.'MVY wୈ̏ੈ୅.77. 6OJP 'MVY

Slide 8

Slide 8 text

ઃܭͷมભ$POUSJCVUJPOHSBQI ୈ̍ੈ୅ ୈ̎ੈ୅ ୈ̏ੈ୅

Slide 9

Slide 9 text

ઃܭͷมભ$POUSJCVUJPOHSBQI ୈ̍ੈ୅ ୈ̎ੈ୅ ୈ̏ੈ୅ ॎԽɺϏσΦػೳ։࢝

Slide 10

Slide 10 text

ઃܭͷมભ$POUSJCVUJPOHSBQI ୈ̍ੈ୅ ୈ̎ੈ୅ ୈ̏ੈ୅ ΞϓϦ಺ίΠϯɺ౤͛મػೳ։࢝

Slide 11

Slide 11 text

ઃܭͷมભνʔϜਓ਺ ࣌ؒ ਓ਺ ୈ̍ੈ୅ ୈ̎ੈ୅ ୈ̏ੈ୅

Slide 12

Slide 12 text

ୈ̍ੈ୅ w࣌ظ wॳظϦϦʔε w.PUJWBUJPO wෳࡶͳঢ়ଶ؅ཧΛΘ͔Γ΍͘͢؅ཧ͍ͨ͠ wΫϥΠΞϯτؒ "OESPJEJ048FC ͰઃܭΛ౷Ұͨ͠ ͍

Slide 13

Slide 13 text

࠾༻'MVY 3Y4XJGU Facebook https://facebook.github.io/flux/docs/in-depth-overview/

Slide 14

Slide 14 text

ୈ̍ੈ୅'MVY 6*Πϕϯτ ঢ়ଶΛ؂ࢹͯ͠6*΁൓ө

Slide 15

Slide 15 text

ୈ̍ੈ୅"DUJPO func getElement() { dispatcher.isLoading.dispatch(true) APIClient.getElement() .do(onError: { [weak self] error in self?.dispatcher.error(error) // Τϥʔ }) .do(onCompleted: { [weak self] in self?.dispatcher.isLoading.dispatch(false) // ׬ྃ }) .subscribe(onNext: { [weak self] element in self?.dispatcher.element.dispatch(element) // ੒ޭ }) .disposed(by: disposeBag) }

Slide 16

Slide 16 text

ୈ̍ੈ୅%JTQBUDIFS final class Dispatcher { static let shared = Dispatcher() let element = DispatchSubject() let isLoading = DispatchSubject() let error = DispatchSubject() }

Slide 17

Slide 17 text

ୈ̍ੈ୅4UPSF final class Store { static let shared = Store() let isLoading: Property let element: Property init(dispatcher: Dispatcher) { // dispatcher͔ΒྲྀΕ͖ͯͨΠϕϯτΛbind͢Δ } }

Slide 18

Slide 18 text

ୈ̍ੈ୅6* override func viewDidLoad() { super.viewDidLoad() // ActionʹΠϕϯτΛൃՐ Action.shared.getElement() // ߋ৽͞Εͨঢ়ଶΛUIʹbind Store.shared.element.asObservable() .bind(to: titleLabel.rx.text) .diposed(by: disposeBag) }

Slide 19

Slide 19 text

ୈ̍ੈ୅'MVY 6*Πϕϯτ ঢ়ଶΛ؂ࢹͯ͠6*΁൓ө

Slide 20

Slide 20 text

ୈ̍ੈ୅ͷྑ͍఺ w7JFXؒͷґଘؔ܎͕ݮΔ w։ൃऀͷ࣮૷͕౷Ұ͞Ε΍͍͢ wσʔλͷྲྀΕ͕Θ͔Γ΍͍͢

Slide 21

Slide 21 text

ୈ̎ੈ୅ w ࣌ظ w ೥݄dλςରԠͷ։ൃ։࢝ w ೥݄dϏσΦػೳͷ։ൃ։࢝

Slide 22

Slide 22 text

ୈ̍ੈ୅ͷ՝୊ w ػೳͷෳࡶԽʹΑΓɺ4UPSF΍6*ͷϥΠϑ αΠΫϧͷ߹੒ϩδοΫ͕7JFX$POUSPMMFS ʹ૿͑ͨ

Slide 23

Slide 23 text

ୈ̍ੈ୅ͷ՝୊ override func viewDidLoad() { super.viewDidLoad() // ঢ়ଶͷߋ৽·ͨ͸λςϤίͷ੾Γସ͑ΛϑοΫͯ͠tableViewΛϦϩʔυ Observable.combineLatest( Store.shared.repositories.asObservable(), rx.traitCollectionDidChange.asObservable() ) .observeOn(MainScheduler.instance) .subscribe(onNext: { [weak self] _ in self?.tableView.reloadData() }) .disposed(by: disposeBag) … }

Slide 24

Slide 24 text

࠾༻.77. 7JFX.PEFM .PEFM 7JFX 7JFX$POUSPMMFS %BUBCJOEJOH

Slide 25

Slide 25 text

ୈ̎ੈ୅7JFX4USFBN

Slide 26

Slide 26 text

ୈ̎ੈ୅7JFX4USFBN final class ViewStream { // Output let element: Property let isLoading: Property init( // Input viewDidLayout: Observable, traitCollectionDidChange: Observable, // Dependency action: Action = .shared, store: Store = .shared ) { // InputͷΠϕϯτΛ΋ͱʹOutputΛ߹੒͢Δ } }

Slide 27

Slide 27 text

ୈ̎ੈ୅ͷྑ͍఺ w7JFX$POUSPMMFSͷ࣮૷Λ6*Πϕϯτͷ఻ൖͱঢ়ଶ Λ6*ʹόΠϯυ͢ΔͷΈʹͰ͖ͨ wϓϨθϯςʔγϣϯϩδοΫΛ6*͔Β෼཭Ͱ͖ɺ ୯ମςετָ͕ʹ͔͚Δ wάϩʔόϧͰอ࣋͢Δඞཁ͕ͳ͍ը໘ͷҰ࣌ঢ়ଶ Λ6*ͷϥΠϑαΠΫϧͰഁغͰ͖Δ

Slide 28

Slide 28 text

ઃܭͷมભνʔϜਓ਺ ࣌ؒ ਓ਺ ୈ̍ੈ୅ ୈ̎ੈ୅ ୈ̏ੈ୅

Slide 29

Slide 29 text

ୈ̎ੈ୅ͷ՝୊ w 7JFX4USFBNͷ࣮૷ํ๏͕࣮૷ऀʹΑͬͯ ͹Β͖͕ͭ͋Δ

Slide 30

Slide 30 text

ୈ̎ੈ୅ͷ՝୊ class SearchViewStream { // Output let repositories: Property<[Repository]> private let _repositories = BehaviorRelay<[Repository]>(value: []) private let _search = PublishRelay() private let disposeBag = DisposeBag() init( // Dependency action: Action = .shared store: Store = .shared ) { // Input ⇨ Output Logic } // Input func search(_ text: string) { _search.accept(text) } }

Slide 31

Slide 31 text

ୈ̎ੈ୅ͷ՝୊ class SearchViewStream { // Output let repositories: Property<[Repository]> private let _repositories = BehaviorRelay<[Repository]>(value: []) private let _search = PublishRelay() private let disposeBag = DisposeBag() init( // Dependency action: Action = .shared store: Store = .shared ) { // Input ⇨ Output Logic } // Input func search(_ text: string) { _search.accept(text) } }

Slide 32

Slide 32 text

ୈ̎ੈ୅ͷ՝୊ class SearchViewStream { // Output let repositories: Property<[Repository]> private let _repositories = BehaviorRelay<[Repository]>(value: []) private let disposeBag = DisposeBag() init( // Input search: Observable // Dependency action: Action = .shared store: Store = .shared ) { // Input ⇨ Output Logic } }

Slide 33

Slide 33 text

ୈ̎ੈ୅ͷ՝୊ class SearchViewStream { // Input let search = PublishRelay() // Output let repositories: Property<[Repository]> private let _repositories = BehaviorRelay<[Repository]>(value: []) private let _search = PublishRelay() private let disposeBag = DisposeBag() init( // Dependency action: Action = .shared store: Store = .shared ) { // Input ⇨ Output Logic } }

Slide 34

Slide 34 text

ߟҊ6OJP $SFBUFECZNBSUZTV[VLJ

Slide 35

Slide 35 text

ୈ̏ੈ୅ w ࣌ظ w "CFNBίΠϯػೳͷ։ൃ w "CFNBαϙʔτ ౤͛મ ػೳͷ։ൃ

Slide 36

Slide 36 text

ୈ̏ੈ୅6OJP class SearchViewModel: UnioStream, SearchViewModelType { struct Input: InputType { let search = PublishRelay() } typealias State = NoState struct Output: OutputType { let repositories: Observable<[Repository]> } struct Extra: ExtraType { let action: Action let store: Store } static func bind(from dependency: Dependency, disposeBag: DisposeBag) -> Output { // Dependency ⇨ Output Logic return Output(repositories: ${repositoriesΛฦ͢ม਺}) } }

Slide 37

Slide 37 text

ୈੈ୅ͷྑ͍఺ w7JFX.PEFMͷ࣮૷ͷ౷Ұ͕࣮ݱͰ͖ͨ w7JFX.PEFMͷϩδοΫͷྲྀΕ͕୯Ұํ޲ͳ ͷͰՄಡੑ্͕͕ͬͨ

Slide 38

Slide 38 text

ୈ̏ੈ୅6OJP

Slide 39

Slide 39 text

ݱࡏͷ՝୊

Slide 40

Slide 40 text

ݱࡏͷ՝୊ wਐԽ͍ͯ͘͠աఔͰલੈ୅ͷ࣮૷͕࢒͍ͬͯΔ wୈ̍ੈ୅ͷ࣮૷ͰҰ෦'MVY಺Ͱ4UPSFUP4UPSF ͳ࣮૷ʹͳ͍ͬͯͯॲཧͷྲྀΕ͕ෳࡶԽ͍ͯ͠Δ wը໘ͷ୯ମىಈ͕Ͱ͖ͳ͍࣮૷ʹͳ͍ͬͯΔ w'MVYͷ"DUJPO͕3FTPVSDF΁௚઀ࢀর͍ͯ͠Δ

Slide 41

Slide 41 text

·ͱΊ wઃܭͷมߋͷλΠϛϯά͸શػೳΛ࡮৽͢ Δͱ͖΍େ͖ͳػೳ։ൃ͕ೖΔͱ͖ wॳظͷίϯηϓτ͔Βൃੜͨ͠՝୊ʹରͯ͠ ౎౓ղܾ͢Δํ๏Λ৽ͨ͠ʹऔΓೖΕͯมԽ ͖ͯͨ͠

Slide 42

Slide 42 text

ࢀর w 'MVYXJUI3Y4XJGU w IUUQTTQFBLFSEFDLDPNEFLBUPUPSPqVYXJUISYTXJGU w .77.'MVY w IUUQTTQFBLFSEFDLDPNNBSUZTV[VLJNWWNQMVTqVY w "CFNBJ04"SDIJUFDUVSF w IUUQTTQFBLFSEFDLDPNUPJLJBCFNBJPTBSDIJUFDUVSF w 6OJP w IUUQTTQFBLFSEFDLDPNNBSUZTV[VLJNWWNGBMTFTIJ[IVBOHXPGVSVGSBNFXPSLXPLBJGBEBP SVTJUJNVEFCBSBUVLJHBBUVUBTIJ[IVBOHXPUPOHTVSV