Slide 1

Slide 1 text

ϝϧΧϦΞοςͷ RxSwift࣮૷ΨΠυ Souzoh iOS Talk 2017 Oct 11 1

Slide 2

Slide 2 text

ࣗݾ঺հ • Ԭా༸ฏ(@parakeety) • 2017 Jan 1ೖࣾ • ϝϧΧϦ ΞοςͷiOSΞϓϦΛ։ൃ 2

Slide 3

Slide 3 text

ϝϧΧϦ Ξος • ։ൃ౰ॳ͔ΒRxSwiftΛ࠾༻ • ৭ʑࢼߦࡨޡ͠ͳ͕Β࣮૷ํ਑Λ໛ࡧ • ࠷ۙ͸େ͖ͳ໰୊ʹૺ۰͢Δࣄ΋ͳ͘ɺ͋Δఔ౓ํ਑͕ݻ·͖ͬͯͨ 3

Slide 4

Slide 4 text

RxSwiftΛ༻͍ͨ։ൃ ϝϧΧϦ ΞοςͰ༻͍͍ͯΔ࣮૷ΨΠυͷҰ ෦Λ঺հ 4

Slide 5

Slide 5 text

͓͠ͳ͕͖ 1. ViewModelͷ࣮૷ΨΠυ 2. Error Handling 5

Slide 6

Slide 6 text

ϝϧΧϦ ΞοςͷΞʔΩςΫνϟ • Model + View + ViewController + ViewModel • ViewControllerΛεϦϜʹอͭͷͱɺςετ͢ΔͨΊʹ ViewModelʹॲཧΛू໿ • ViewController͸ViewModelͱ1ର1ͷؔ܎ 6

Slide 7

Slide 7 text

1. ViewModel࣮૷ΨΠυ private var viewModel: ViewModel! private let refreshTrigger = PublishSubject() // view model΁ͷinput override func viewDidLoad() { super.viewDidLoad() viewModel = ViewModel(refreshTrigger: refreshTrigger.asDriver()) } 7 1. ViewModel΁ͷinput͸ViewModelͷinitializerͰશͯ౉͢

Slide 8

Slide 8 text

1. ViewModel࣮૷ΨΠυ class ViewModel { let offers: Driver<[Offer]> // view model͔Βͷoutput init(refreshTrigger: Driver) { offers = refreshTrigger.flatMap { _ in return APIClient.shared.responseFrom(SomeRequest) } } } 8 2. ViewModel͔Βͷoutput͸ViewModelͷpropertyͱͯ͠ఆٛ

Slide 9

Slide 9 text

1. ViewModel࣮૷ΨΠυ override func viewDidLoad() { super.viewDidLoad() viewModel = ViewModel(refreshTrigger: refreshTrigger.asDriver()) viewModel.offers .drive() .disposed(by: disposeBag) } 9

Slide 10

Slide 10 text

1. ViewModel࣮૷ΨΠυ 3. ViewModel΁ͷinput΋output΋DriverΛ࢖͏ - observableʹ஋͕ྲྀΕͯ͘Δͷ͕ઌ͔ɺsubscribe͕ઌ͔Ͱҙਤ͠ͳ͍ಈ ࡞͕ൃੜ͢Δ͜ͱ͕͋ͬͨ(subscribe͔ͯ͠Β஋͕ྲྀΕͯ͘Ε͹஋Λड͚ औΕΔ͕ɺ஋͕ྲྀΕ͖ͯͨޙʹsubscribeͯ͠΋஋Λड͚औΕͳ͍) - subscribeͷλΠϛϯά΍ॱ൪Λؾʹ͠ͳͯ͘΋ྑ͍Α͏ʹɺsubscribe͠ ͨ࣌ʹreplayͤ͞ΔΑ͏ʹͨ͠ 10

Slide 11

Slide 11 text

1. ViewModel࣮૷ΨΠυ 1. ViewModel΁ͷinput͸ViewModelͷinitializerͰશͯ౉͢ 2. ViewModel͔Βͷoutput͸ViewModelͷpropertyͱͯ͠ఆٛ͢Δ 3. ViewModel΁ͷinput΋output΋DriverΛ࢖͏ 11 ·ͱΊ

Slide 12

Slide 12 text

2. Error Handling αʔόʔʹϦΫΤετΛ౤͛ͯɺΤϥʔ͕ฦ͖ͬͯͨ ࣌ʹɺϢʔβʔʹΤϥʔϝοηʔδΛද͍ࣔͨ͠ 12

Slide 13

Slide 13 text

2. Error Handling observableʹerror͕ྲྀΕΔͱobservable͕ऴྃͯ͠͠ ·͏ => ΋͏Ұ౓subscribe͠௚͞ͳ͍ͱ͍͚ͳ͍ 13

Slide 14

Slide 14 text

2. Error Handling ਖ਼ৗܥͱΤϥʔͷstreamΛ෼཭͢Δ 14

Slide 15

Slide 15 text

2. Error Handling enum Result { case succeeded(Response) case failed(Error) } extension ObservableConvertibleType { func resultDriver() -> Driver> { return self.asObservable() .map { Result.succeeded($0) } .asDriver { Driver.just(Result.failed($0)) } } } 15

Slide 16

Slide 16 text

2. Errorͷऔѻ͍ extension SharedSequence { static func split(result: Driver>) -> (response: Driver, error: Driver) { let responseDriver = result.flatMap { result -> Driver in switch result { case .succeeded(let response): return Driver.just(response) case .failed: return Driver.empty() } } let errorDriver = result.flatMap { result -> Driver in switch result { case .succeeded: return Driver.empty() case .failed(let error): return Driver.just(error) } } return (responseDriver, errorDriver) } } 16

Slide 17

Slide 17 text

2. Errorͷऔѻ͍ let responseDriver = result.flatMap { result -> Driver in switch result { case .succeeded(let response): return Driver.just(response) case .failed: return Driver.empty() } } 17

Slide 18

Slide 18 text

2. Errorͷऔѻ͍ let errorDriver = result.flatMap { result -> Driver in switch result { case .succeeded: return Driver.empty() case .failed(let error): return Driver.just(error) } } 18

Slide 19

Slide 19 text

2. Errorͷऔѻ͍ extension SharedSequence { static func split(result: Driver>) -> (response: Driver, error: Driver) { let responseDriver = result.flatMap { result -> Driver in switch result { case .succeeded(let response): return Driver.just(response) case .failed: return Driver.empty() } } let errorDriver = result.flatMap { result -> Driver in switch result { case .succeeded: return Driver.empty() case .failed(let error): return Driver.just(error) } } return (responseDriver, errorDriver) } } 19

Slide 20

Slide 20 text

2. Errorͷऔѻ͍ class ViewModel { let offers: Driver<[Offer]> let error: Driver init(refreshTrigger: Driver) { let offerResult: Driver> = refreshTrigger .flatMap { _ in return APIClient.shared.responseFrom(OfferRequest) .resultDriver() } (offers, error) = Driver.split(result: offerResult) } } 20 ࢖͏ଆ(ViewModel)

Slide 21

Slide 21 text

2. Errorͷऔѻ͍ class ViewController: UIViewController { private var viewModel: ViewModel! private let refreshTrigger = PublishSubject() private let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() viewModel = ViewModel(refreshTrigger: refreshTrigger) viewModel.offers .drive() .disposed(by: disposeBag) viewModel.error .drive() // handle error i.e) show alert .disposed(by: disposeBag) } } 21 ࢖͏ଆ(ViewController)

Slide 22

Slide 22 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 22