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

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

yohei okada
October 11, 2017

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

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

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)