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

メルカリアッテのRxSwift実装ガイド

Avatar for yohei okada yohei okada
October 11, 2017

 メルカリアッテのRxSwift実装ガイド

メルカリアッテで採用している実装ガイド

Avatar for yohei okada

yohei okada

October 11, 2017
Tweet

More Decks by yohei okada

Other Decks in Technology

Transcript

  1. ϝϧΧϦ ΞοςͷΞʔΩςΫνϟ • Model + View + ViewController + ViewModel

    • ViewControllerΛεϦϜʹอͭͷͱɺςετ͢ΔͨΊʹ ViewModelʹॲཧΛू໿ • ViewController͸ViewModelͱ1ର1ͷؔ܎ 6
  2. 1. ViewModel࣮૷ΨΠυ private var viewModel: ViewModel! private let refreshTrigger =

    PublishSubject<Void>() // view model΁ͷinput override func viewDidLoad() { super.viewDidLoad() viewModel = ViewModel(refreshTrigger: refreshTrigger.asDriver()) } 7 1. ViewModel΁ͷinput͸ViewModelͷinitializerͰશͯ౉͢
  3. 1. ViewModel࣮૷ΨΠυ class ViewModel { let offers: Driver<[Offer]> // view

    model͔Βͷoutput init(refreshTrigger: Driver<Void>) { offers = refreshTrigger.flatMap { _ in return APIClient.shared.responseFrom(SomeRequest) } } } 8 2. ViewModel͔Βͷoutput͸ViewModelͷpropertyͱͯ͠ఆٛ
  4. 1. ViewModel࣮૷ΨΠυ override func viewDidLoad() { super.viewDidLoad() viewModel = ViewModel(refreshTrigger:

    refreshTrigger.asDriver()) viewModel.offers .drive() .disposed(by: disposeBag) } 9
  5. 2. Error Handling enum Result<Response> { case succeeded(Response) case failed(Error)

    } extension ObservableConvertibleType { func resultDriver() -> Driver<Result<E>> { return self.asObservable() .map { Result.succeeded($0) } .asDriver { Driver.just(Result.failed($0)) } } } 15
  6. 2. Errorͷऔѻ͍ extension SharedSequence { static func split(result: Driver<Result<Response>>) ->

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

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

    in switch result { case .succeeded: return Driver.empty() case .failed(let error): return Driver.just(error) } } 18
  9. 2. Errorͷऔѻ͍ extension SharedSequence { static func split(result: Driver<Result<Response>>) ->

    (response: Driver<Response>, error: Driver<Error>) { let responseDriver = result.flatMap { result -> Driver<Response> in switch result { case .succeeded(let response): return Driver.just(response) case .failed: return Driver.empty() } } let errorDriver = result.flatMap { result -> Driver<Error> in switch result { case .succeeded: return Driver.empty() case .failed(let error): return Driver.just(error) } } return (responseDriver, errorDriver) } } 19
  10. 2. Errorͷऔѻ͍ class ViewModel { let offers: Driver<[Offer]> let error:

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

    private let refreshTrigger = PublishSubject<Void>() 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)