Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SWORD ART COMBINE

yimajo
October 25, 2020

SWORD ART COMBINE

この発表資料は『iOSアプリ開発のためのFunctional Architecture情報共有会』で発表した資料です。
https://connpass.com/event/192067/

# その他 引用元

The Composable Architecture
https://github.com/pointfreeco/swift-composable-architecture

combine-schedulers
https://github.com/pointfreeco/combine-schedulers

SAO
https://sao-alicization.net/

YouTube
https://www.youtube.com/user/eguri89

yimajo

October 25, 2020
Tweet

More Decks by yimajo

Other Decks in Programming

Transcript

  1. SWORD ART COMBINE
    - ΞϦγθʔγϣϯ-
    iOS Functional Architecture ษڧձ 2020.10.25
    @yiamjo

    View Slide

  2. ͜ͷεϥΠυʹ͸2020೥य़Ն์ૹͷ
    ΞχϝSAOΞϦγθʔγϣϯฤͷ
    ωλόϨؚ͕·Ε·͢

    View Slide

  3. ͋ͱͰݟΑ͏ͱࢥͬͯΔํ͸
    ໨ΛͭΉ͍͔ͬͯͨͩ͘
    ӾཡΛ͝தࢭ͍ͩ͘͞

    View Slide

  4. Ξχϝ൛͚ͩͰ͍͍ΜͰ·ͣSAOΛݟ
    ͔ͯΒ͜ͷࢿྉΛݟ͍ͯͩ͘͞

    View Slide

  5. ͪΌΜͱΞχϝ൛ݟ·ͨ͠ʁ
    ͋ɺ͍ͭͰʹ
    ͍ͭͰʹܶ৔൛΋͋ΔΜͰΞϦγθʔ
    γϣϯฤͷલʹݟ·ͨ͠ʁ

    View Slide

  6. ͍͍ͬͨɺͳͥͦΜͳ͜ͱΛ…

    View Slide

  7. ͍΍ɺࣗ෼ͷ޷͖ʹεϥΠυ࡞ͬͨ΄
    ͏͕ḿΔ͔Β…

    View Slide

  8. ΞΫηϧϫʔϧυͷํ΋ݟͨ΄͏͕͍
    ͍Ͱ͔͢ʁ

    View Slide

  9. ͳΔ΄Ͳ
    ΞΫηϧϫʔϧυͷํ͸ະࢹௌͰ͔·
    ͍·ͤΜ

    View Slide

  10. Ͱ͸͔͜͜Β͸
    Ξχϝ൛SAO͓Αͼܶ৔Ξχϝ൛Λݟ
    ͨͱ͍͏͜ͱͰਐΊ·͢

    View Slide

  11. • લฤ: TCAͰ࢖ΘΕ͍ͯΔ pointfreeco/combine-schedulers
    • https://github.com/pointfreeco/combine-schedulers
    • RxSwiftͱͷൺֱ
    • ޙฤ: ͦ΋ͦ΋CombineͰͷSchedulerͷ໾ׂ΍ಈ࡞
    • pointfreeco/combine-schedulers ͕Ͳ͏΍ͬͯΔͷ͔
    ࠓ೔࿩͢͜ͱ

    View Slide

  12. TCAͰ࢖ΘΕ͍ͯΔ
    pointfreeco/combine-schedulers
    ʹ͍ͭͯ
    લ൒

    View Slide

  13. TCAͰ͸ReducerͷςετͰ࢖ΘΕΔ

    View Slide

  14. Reducerͷςετͷྫ
    ps://github.com/pointfreeco/swift-composable-architecture/blob/0.8.0/Examples/Search/Search/SearchView.swift
    Examples/Search/SearchView

    View Slide

  15. Reducerͷςετͷྫ
    ps://github.com/pointfreeco/swift-composable-architecture/blob/0.8.0/Examples/Search/Search/SearchView.swift https://github.com/pointfreeco/swift-composable-architecture/blob/0.8.0/Examples/Search/SearchTests/SearchTests.swif
    Examples/Search/SearchView

    View Slide

  16. ೚ҙʹ࣌ؒΛਐΊɺ
    EffectΛଈ࣮࣌ߦ͍ͤͯ͞Δ

    View Slide

  17. Πϝʔδ: ಈըϓϨΠϠʔ

    View Slide

  18. Πϝʔδ: ಈըϓϨΠϠʔ

    View Slide

  19. ࣍ʹԿ͕͋Δ͔ͱ͍͏ͷ͕Θ͔͍ͬͯͯɺ
    ͦͷλΠϛϯά·Ͱ࣌ؒΛਐΊΔ͜ͱ͕Ͱ͖ΔͷͰ
    ςετ࣮ߦ࣌ʹ࣮࣌ؒͷܦա͸ඞཁ͕ͳ͍ɻ
    Πϝʔδ: ಈըϓϨΠϠʔ

    View Slide

  20. ൺֱͷͨΊʹRxSwiftͷ࿩Λग़͢Αʂ

    View Slide

  21. RxSwift ͷ TestScheduler ͸
    ࣌ؒΛԾ૝తʹѻ͏͜ͱͰ
    ςετίʔυΛಡΈ΍ͯ͘͢͠Δ

    View Slide

  22. ղ૾౓ͱ͍͏֓೦͕͋Δ
    • Ծ૝࣌ؒ = ݱ࣮࣌ؒ / ղ૾౓
    • ۩ମྫʢղ૾౓Λ0.1ͱͨ͠৔߹ʣ
    • Ծ૝࣌ؒ10 = ݱ࣮࣌ؒ1ඵ / ղ૾౓0.1
    • Ծ૝࣌ؒ3 = ݱ࣮࣌ؒ0.3 / ղ૾౓0.1
    ςετΛ࣮ߦ͢ΔλΠϛϯάΛݱ࣮࣌ؒͰࢦఆ͢ΔͷͰ͸ͳ͘ɺ
    Ծ૝࣌ؒͰࢦఆ͢Δ͜ͱͰςετ࣮ߦΛݱ࣮࣌ؒʹґଘͤ͞ͳ͍Α͏ʹͰ͖͍ͯΔɻ

    View Slide

  23. ݱ࣮ͷ࣌ؒͰͪΜͨΒ࣮ߦΛ
    ଴ͭͷͰ͸ͳ͘ɺԾ૝࣌ؒͷதͰ
    ΠϕϯτΛॱ࣍ॲཧ͍ͯ͘͠…
    ʢRxSwift Ծ૝࣌ؒͷܦա͕࣮࣌ؒࡍʹͲ͏͍͏εϐʔυ͔͸෼͔Βͳ͍΋ͷͷʣ
    ͜Ε͸Կ͔ ͜͜Ζ͋ͨΓ͋Γ·͢ΑͶ….ʂ

    View Slide

  24. Πϝʔδ: SAO ΞϦγθʔγϣϯฤͷԾ૝ੈքʮΞϯμʔϫʔϧυʯ Ҿ༻: https://sao-alicization.net/
    SAOݱ࣮ੈք SAOԾ૝ੈքʮΞϯμʔϫʔϧυʯ

    View Slide

  25. ݱ࣮ੈքͷ࣌ؒʹ͍ͨͯ͠ഒ཰Λ͔͚ΒΕͨ
    ࣌ؒʹΑͬͯՃ଎ͯ͠ੈքΛߏங͍ͯ͠Δ
    Πϝʔδ: SAO ΞϦγθʔγϣϯฤͷԾ૝ੈքʮΞϯμʔϫʔϧυʯ Ҿ༻: https://sao-alicization.net/
    SAOݱ࣮ੈք SAOԾ૝ੈքʮΞϯμʔϫʔϧυʯ

    View Slide

  26. ͱ͍͏Θ͚Ͱ RxSwift ͱൺֱͭͭͦ͠
    ͷҧ͍Λ੔ཧ͢Δͱ

    View Slide

  27. RxSwift ͷεέδϡʔϥ͸
    SAO ΞϯμʔϫʔϧυతʹԾ૝࣌ؒͱͯ͠ѻ͏ɻ
    CombineScheduler ͸
    ϝσΟΞϓϨΠϠʔతʹ࣌ؒΛ
    ੍ޚͯ͠ඈ͹͢ɻ

    View Slide

  28. ༨ஊ

    View Slide

  29. SAO ݱ࣮ੈքͷهऀ SAO ݱ࣮ੈքʹϩϘମͰ࿈Εͯ͜ΒΕͨ
    ΞϯμʔϫʔϧυਓͷΞϦε͞Μ
    Ҿ༻: https://sao-alicization.net/

    View Slide

  30. -> هऀձݟ։͘ΜͳΒ಄֖։͍ͯAIͬͯূ໌ͯ͠
    SAO ݱ࣮ੈքͷهऀ SAO ݱ࣮ੈքʹϩϘମͰ࿈Εͯ͜ΒΕͨ
    ΞϯμʔϫʔϧυਓͷΞϦε͞Μ
    Ҿ༻: https://sao-alicization.net/

    View Slide

  31. -> هऀձݟ։͘ΜͳΒ಄֖։͍ͯAIͬͯূ໌ͯ͠
    ͡Ό͋ͦͬͪ΋಄֖։͍ͯਓؒͬͯূ໌ͯ͠ <-
    SAO ݱ࣮ੈքͷهऀ SAO ݱ࣮ੈքʹϩϘମͰ࿈Εͯ͜ΒΕͨ
    ΞϯμʔϫʔϧυਓͷΞϦε͞Μ
    Ҿ༻: https://sao-alicization.net/

    View Slide

  32. -> هऀձݟ։͘ΜͳΒ಄֖։͍ͯAIͬͯূ໌ͯ͠
    ͡Ό͋ͦͬͪ΋಄֖։͍ͯਓؒͬͯূ໌ͯ͠ <-
    ΞϯμʔϫʔϧυਓΛ <-
    ਓ޻෺ݺ͹ΘΓ͚ͯͬ͠Ͳ͞ʙ
    ͓લΒͷੈքͷͦͷ্ʹ͸
    Կ΋ͳ͍ͱݴ͍੾ΕΔΜ͔ʁ
    ͓લΒͷ૑଄ओ͕͍ͯɺ͓લΒࣗମ
    ਓ޻తʹͭ͘ΒΕͨΜ͡Όͳ͍ͬͯ
    ͦ͏͍͏ͷূ໌Ͱ͖Μͷ͔ʙ
    SAO ݱ࣮ੈքͷهऀ SAO ݱ࣮ੈքʹϩϘମͰ࿈Εͯ͜ΒΕͨ
    ΞϯμʔϫʔϧυਓͷΞϦε͞Μ
    Ҿ༻: https://sao-alicization.net/

    View Slide

  33. -> هऀձݟ։͘ΜͳΒ಄֖։͍ͯAIͬͯূ໌ͯ͠
    ͡Ό͋ͦͬͪ΋಄֖։͍ͯਓؒͬͯূ໌ͯ͠ <-
    ΞϯμʔϫʔϧυਓΛ <-
    ਓ޻෺ݺ͹ΘΓ͚ͯͬ͠Ͳ͞ʙ
    ͓લΒͷੈքͷͦͷ্ʹ͸
    Կ΋ͳ͍ͱݴ͍੾ΕΔΜ͔ʁ
    ͓લΒͷ૑଄ओ͕͍ͯɺ͓લΒࣗମ
    ਓ޻తʹͭ͘ΒΕͨΜ͡Όͳ͍ͬͯ
    ͦ͏͍͏ͷূ໌Ͱ͖Μͷ͔ʙ
    SAO ݱ࣮ੈքͷهऀ SAO ݱ࣮ੈքʹϩϘମͰ࿈Εͯ͜ΒΕͨ
    ΞϯμʔϫʔϧυਓͷΞϦε͞Μ
    ΞϯμʔϫʔϧυͰ฻Β͢ੜ໋ମ͸
    ࣗ෼͕ͨͪSAOݱ࣮ੈքਓʹΑͬͯਓ޻తʹ
    ͭ͘ΒΕͨͳΜͯࢥͬͯͳ͍Θ͚
    Ҿ༻: https://sao-alicization.net/

    View Slide

  34. લ൒ऴΘΓ

    View Slide

  35. ޙ൒
    ͦ΋ͦ΋CombineͰͷScheduler
    ͷ໾ׂ΍ಈ࡞

    View Slide

  36. • combine-schedulers͕ԿΛ΍ͬͯΔ͔஌Γ͍ͨ
    • ͦ΋ͦ΋CombineͷSchedulerͱ͸Կͳͷ͔Λઌʹ஌Βͳ͍ͱ͍͚
    ͳ͍
    • ͦ΋ͦ΋PublisherͱSubscriberͷ΍ΓͱΓ͔Β͓͞Β͍
    • Schedulerϓϩτίϧͷϝιου͕ݺ͹ΕΔ͜ͱͷجૅ

    View Slide

  37. pointfreeco/combine-schdulers ͕
    Ͳ͏΍ͬͯ೚ҙʹ࣌ؒΛ
    ੍ޚͰ͖Δͷ͔ͷͨΊͷجૅ

    View Slide

  38. Schedulerʹؔ͢ΔΑ͋͘Δઆ໌ͷྫ…
    Scheduler͸ʮUpstreamͷʯʮDownstreamͷʯ
    ॲཧεϨουΛ੾Γସ͑Δ

    View Slide

  39. Schedulerʹؔ͢ΔΑ͋͘Δઆ໌ͷྫ…
    Scheduler͸ʮUpstreamͷʯʮDownstreamͷʯ
    ॲཧεϨουΛ੾Γସ͑Δ
    ͱ͍͏ͷΛਂ۷Γͭͭ͠આ໌Λ͠·͢

    View Slide

  40. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }

    View Slide

  41. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }

    View Slide

  42. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }
    subscribe(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    UpstreamͱDownstreamεϨου͕੾ΓସΘΔ

    View Slide

  43. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }
    subscribe(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    UpstreamͱDownstreamεϨου͕੾ΓସΘΔ

    View Slide

  44. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }
    subscribe(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    UpstreamͱDownstreamεϨου͕੾ΓସΘΔ

    View Slide

  45. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }
    subscribe(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    UpstreamͱDownstreamεϨου͕੾ΓସΘΔ
    receive(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    DownstreamͷεϨου͕੾ΓସΘΔ

    View Slide

  46. subscribe(on:)ͱreceive(on:)
    let cancellable = publisher
    .flatMap { … }
    .subscribe(on: DispatchQueue.global())
    .map { String($0) }
    .receive(on: DispatchQueue.main)
    .sink {
    print($0)
    }
    subscribe(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    UpstreamͱDownstreamεϨου͕੾ΓସΘΔ
    receive(on:)Ͱࢦఆͨ͠εέδϡʔϥʹΑΓɺ
    DownstreamͷεϨου͕੾ΓସΘΔ
    subscribe(on:)͸Downstream ʹ΋Өڹ͢Δ

    View Slide

  47. ਖ਼֬͞ͷͨΊͷิ଍
    • subscribe(on:)
    • UpstreamͷεϨουΛ੾Γସ͑Δ͕ɺDownstremʹ΋Өڹ͕͋Δ
    • receive(on:)
    • DownstreamͷΈεϨουΛ੾Γସ͑Δ

    View Slide

  48. ਖ਼֬͞ͷͨΊͷิ଍
    • subscribe(on:)
    • UpstreamͷεϨουΛ੾Γସ͑Δ͕ɺDownstremʹ΋Өڹ͕͋Δ
    • receive(on:)
    • DownstreamͷΈεϨουΛ੾Γସ͑Δ
    ͜ΕΒ͸୯ͳΔϧʔϧͰ͸ͳ͘ɺ
    ࣮ࡍ͸ཧղ͢Ε͹௚ײͰΘ͔ΔΘ͚Α

    View Slide

  49. WWDC19ͷCombineͷηογϣϯ
    ͜͜ͰSchedulerʹ͍ͭͯͷಈ࡞͕͋ΔͷͰͦΕͰิ଍͢Ε͹ྑͦ͞͏

    View Slide

  50. /05&
    4VCTDSJQUJPOͷಈ࡞͸೚ҙͷͨΊɺ
    ͜ͷྫͰ͸͜͏͍͏ಈ࡞Λ
    ͍ͯ͠Δͱ͍͏ྫͰ͔͠ͳ͍Ͱ͢ɻ

    View Slide

  51. /05&
    4VCTDSJQUJPOͷಈ࡞͸೚ҙͷͨΊɺ
    ͜ͷྫͰ͸͜͏͍͏ಈ࡞Λ
    ͍ͯ͠Δͱ͍͏ྫͰ͔͠ͳ͍Ͱ͢ɻ
    Publisher͕.subscribe(on: scheduler)
    ͞Ε͍ͯΕ͹ɺTVCTDSJCF΍SFDFJWF͞Εͨࡍ
    ࢦఆ͞Εͨ4DIFEVMFSͷϓϩτίϧͷϝιουͰ
    ॲཧΛ࣮ߦ͢Δ͜ͱͰΩϡʔΛ੾Γସ͑Δɻ
    ˣ
    1VCMJTIFSͷΠϕϯτॲཧٴͼɺͦͷޙͷॲཧ΋
    ੾Γସ͑ΒΕͨΩϡʔͰҾ͖ଓ͖࣮ߦ͞ΕΔɻ

    View Slide

  52. /05&
    4VCTDSJQUJPOͷಈ࡞͸೚ҙͷͨΊɺ
    ͜ͷྫͰ͸͜͏͍͏ಈ࡞Λ
    ͍ͯ͠Δͱ͍͏ྫͰ͔͠ͳ͍Ͱ͢ɻ
    Publisher͕
    .receive(on: scheduler)
    ͞Ε͍ͯΕ͹ɺSFDFJWF࣌ʹ
    ࢦఆ͞Εͨ4DIFEVMFS͕
    ͦͷΩϡʔͰॲཧΛ࣮ߦ͢Δɻ
    ˣ
    ͦͷޙͷॲཧ΋ͦͷΩϡʔͰ
    Ҿ͖ଓ͖࣮ߦ͞ΕΔɻ
    Publisher͕.subscribe(on: scheduler)
    ͞Ε͍ͯΕ͹ɺTVCTDSJCF΍SFDFJWF͞Εͨࡍ
    ࢦఆ͞Εͨ4DIFEVMFSͷϓϩτίϧͷϝιουͰ
    ॲཧΛ࣮ߦ͢Δ͜ͱͰΩϡʔΛ੾Γସ͑Δɻ
    ˣ
    1VCMJTIFSͷΠϕϯτॲཧٴͼɺͦͷޙͷॲཧ΋
    ੾Γସ͑ΒΕͨΩϡʔͰҾ͖ଓ͖࣮ߦ͞ΕΔɻ

    View Slide

  53. Schedulerϓϩτίϧͷඞਢϝιου
    • schedule(options:_:)
    • schedule(after:tolerance:options:_:)
    • schedule(after:interval:tolerance:options:_:)
    https://developer.apple.com/documentation/combine/scheduler

    View Slide

  54. Scheduler ͷඞਢϝιου scheduler(options:_:)
    https://github.com/pointfreeco/combine-schedulers/blob/0.1.2/Sources/CombineSchedulers/TestScheduler.swift
    var scheduled: [(sequence: UInt, date: SchedulerTimeType, action: () -> Void)] = []

    View Slide

  55. ਖ਼֬͞ͷͨΊͷิ଍ -> ཧ۶͕Θ͔ͬͨ͸ͣ
    • subscribe(on:)
    • UpstreamͷεϨουΛ੾Γସ͑Δ͕ɺDownstremʹ΋Өڹ͕͋Δ
    • subscribe͞Εͨࡍ΍request͞Εͨࡍʹಈ࡞͢ΔεέδϡʔϥΛܾΊΔʢ࣮͸΋͏গ͠
    ࡉ͔͘Ωϟϯηϧ͞Εͨࡍ΋ͦͷεέδϡʔϥ͕ಈ͘ʣ
    • receive(on:)
    • DownstreamͷΈεϨουΛ੾Γସ͑Δ
    • Subscriber͕receiveͨ͠ࡍʹಈ࡞͢ΔεέδϡʔϥΛܾΊΔ
    https://developer.apple.com/documentation/combine/publishers/handleevents/subscribe(on:options:)

    View Slide

  56. ͳΜͰ͜Μͳ࿩ͯ͠Δ͔

    View Slide

  57. pointfreeco/combine-schdulers
    ͸Ͳ͏΍ͬͯ
    ࣌ؒΛ੍ޚͯ͠Δ͔ͱ͔ͷ࿩

    View Slide

  58. combine-schedulersͷ
    advance(by:)
    ͕ԿΛ΍ͬͯΔͷ͔ΛݟͯΈΔ

    View Slide

  59. // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    now nextDate
    finalDate
    advance(by:)

    View Slide

  60. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    now nextDate
    finalDate
    advance(by:)

    View Slide

  61. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // ݱࡏ࣌ؒ <= ਐΊͨ࣌ؒͳΒ ͦͷؒϧʔϓʢͭ·Γݱࡏ࣌ؒ͸ਐΊΒΕΔʣ
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    now nextDate
    finalDate
    advance(by:)

    View Slide

  62. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // ݱࡏ࣌ؒ <= ਐΊͨ࣌ؒͳΒ ͦͷؒϧʔϓʢͭ·Γݱࡏ࣌ؒ͸ਐΊΒΕΔʣ
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ >= εέδϡʔϧ͞ΕͨΠϕϯτ࣌ؒ
    now nextDate
    finalDate
    advance(by:)

    View Slide

  63. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // ݱࡏ࣌ؒ <= ਐΊͨ࣌ؒͳΒ ͦͷؒϧʔϓʢͭ·Γݱࡏ࣌ؒ͸ਐΊΒΕΔʣ
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ͸ɺ·ͩεέδϡʔϧ͞ΕͨΠϕϯτͷ࣌ؒʹಧ͍ͯͳ͍ͷͰ
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ >= εέδϡʔϧ͞ΕͨΠϕϯτ࣌ؒ
    now nextDate
    finalDate
    advance(by:)

    View Slide

  64. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // ݱࡏ࣌ؒ <= ਐΊͨ࣌ؒͳΒ ͦͷؒϧʔϓʢͭ·Γݱࡏ࣌ؒ͸ਐΊΒΕΔʣ
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ͸ɺ·ͩεέδϡʔϧ͞ΕͨΠϕϯτͷ࣌ؒʹಧ͍ͯͳ͍ͷͰ
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒʹͯ͠ advance(by:)Λऴྃ
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ >= εέδϡʔϧ͞ΕͨΠϕϯτ࣌ؒ
    now nextDate
    finalDate
    advance(by:)

    View Slide

  65. // ݱࡏ͔࣌ؒΒࢦఆ࣌ؒΛਐΊͨ࣌ؒ finalDate
    // ݱࡏ࣌ؒ <= ਐΊͨ࣌ؒͳΒ ͦͷؒϧʔϓʢͭ·Γݱࡏ࣌ؒ͸ਐΊΒΕΔʣ
    // scheduledऔΓग़ͤͨΒΞΫγϣϯΛ࣮ߦͯ͠࡟আ͓ͯ͘͠
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ͸ɺ·ͩεέδϡʔϧ͞ΕͨΠϕϯτͷ࣌ؒʹಧ͍ͯͳ͍ͷͰ
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒʹͯ͠ advance(by:)Λऴྃ
    // ݱࡏ࣌ؒΛεέδϡʔϧ͞ΕͨΠϕϯτ࣌ؒ·ͰਐΊΔ
    // ݱࡏ࣌ؒΛਐΊͨ࣌ؒ >= εέδϡʔϧ͞ΕͨΠϕϯτ࣌ؒ
    now nextDate
    finalDate
    advance(by:)

    View Slide

  66. • ͦ΋ͦ΋PublisherΛSubscribe͞ΕΔͱ
    • SchedulerΛݺͼग़͍ͯ͠ΔॲཧΩϡʔΛม͑ΔΘ͚͚ͩͲ
    • ΧελϜSchedulerΛ࡞ΔͱɺΠϕϯτͷൃՐ࣌ؒ·Ͱऔಘ͢Δ
    ͜ͱ ΋ Ͱ͖Δ

    View Slide

  67. TestScheduler
    pointfreeco/combine-schedulers
    https://github.com/pointfreeco/combine-schedulers/blob/0.1.2/Sources/CombineSchedulers/TestScheduler.swift

    View Slide

  68. https://github.com/pointfreeco/swift-composable-architecture/blob/0.8.0/Examples/Search/Search/SearchView.swift
    debounceΦϖϨʔλ͸࣮ࡍ͸
    UpstreamΛsubscribeͯ͠Δɻ
    ͦͷͱ͖
    0.3ඵޙͱ͍͏৘ใΛ͍࣋ͬͯΔɻ
    εέδϡʔϥ͸Πϕϯτͷ
    ΩϡʔʹͦΕΛอ࣋ͯ͠Δ
    લ൒Ͱࣔͨ͠ςετίʔυΛݟฦͯ͠ΈΑ͏

    View Slide

  69. ͭ·Γ…

    View Slide

  70. TestScheduler͸Πϕϯτ͕Կඵޙʹ
    ى͜Δ͔ΛCombineͷ࢓૊Έ্஌Δ
    ͜ͱ͕Ͱ͖Δ

    View Slide

  71. TestScheduler͸advanceϝιουͰ
    ೚ҙͷ࣌ؒʹਐΊΔ͜ͱ͕Ͱ͖Δ

    View Slide

  72. ͳͷͰɺTCA͸Πϕϯτ͕೚ҙͷ࣌ؒ
    ʹ࣮ߦ͞ΕΔͷΛݟӽͨ͠ςετίʔ
    υΛॻ͘͜ͱ͕Ͱ͖Δʢඇಉظ࣮ߦΛ
    Ϝμʹ଴ͨͳ͍͍ͯ͘ʣ

    View Slide

  73. ·ͱΊ
    • CombineͷScheduler͸ΩϡʔΛ੾Γସ͑ΒΕΔΑ͏ʹͳ͍ͬͯΔ
    ͕ɺ͍ͭͰʹΠϕϯτͷ࣮ߦ࣌ؒΛऔಘͰ͖Δ
    • combine-schedulersͰCombine͸ςετίʔυͷ࣌ؒΛ੍ޚͰ͖Δ
    • RxSwiftͷςετίʔυ͸࣌ؒΛԾ૝తʹѻ͑Δ
    • CombineͷSchedulerͰ΋Ծ૝࣌ؒతʹѻ͑Δ͔ʁͱ͍͏ͷ͸΍Ε͹
    Ͱ͖ͦ͏Ͱ͸͋Δ͕ɺ΍Δඞཁੑ͸ͳ͍

    View Slide