Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

俺コン Vol.1: Layered Architecture x RxSwiftを活用した適...

俺コン Vol.1: Layered Architecture x RxSwiftを活用した適切なエラーハンドリング

Takeshi Ihara

October 02, 2017
Tweet

More Decks by Takeshi Ihara

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • Takeshi Ihara • Recruit Marketing Partners • iOS

    Engineer • Twitter: @nonchalant0303 • GitHub: Nonchalant
  2. *OGSB 1SFTFOUBUJPO %PNBJO ϩάΠϯ public protocol PublishRepository { func login(email:

    String, password: String) throws -> User } public protocol LoginUseCase { func login(email: String, password: String) throws } public protocol LoginPresenter { func login(email: String, password: String) throws }
  3. *OGSB 1SFTFOUBUJPO %PNBJO ϩάΠϯ public protocol PublishRepository { func login(email:

    String, password: String) -> Result<User> } public protocol LoginUseCase { func login(email: String, password: String) -> Result<Void> } public protocol LoginPresenter { func login(email: String, password: String) -> Result<Void> }
  4. *OGSB 1SFTFOUBUJPO %PNBJO ϩάΠϯ public protocol PublishRepository { func login(email:

    String, password: String) -> Single<User> } public protocol LoginUseCase { func login(email: String, password: String) -> Completable } public protocol LoginPresenter { func login(email: String, password: String) -> Completable }
  5. *OGSBTUSVDUVSF&SSPS %PNBJO&SSPS 1SFTFOUBUJPO&SSPS DPOOFDUJPO DPOOFDUJPO DPOOFDUJPO QFSNJTTJPO QFSNJTTJPO UFNQPSBSZ1BTTXPSE &YQJSFE

    UFNQPSBSZ1BTTXPSE &YQJSFE BQJ3FQPOTF SFTQPOTF SFTQPOTF JOUFSOBMTFSWFSFSSPS VOLOPXO VOLOPXO USBOTMBUJPO
  6. struct PublishRepositoryImpl: PublishRepository { func login(email: String, password: String) ->

    Single<User> { return apiClient.create( with: PublishRequest(email: email, password: password) ) } } Infrastructure
  7. struct LoginUseCaseImpl: LoginUseCase { func login(email: String, password: String) ->

    Completable { return repository.login(email: email, password: password) .asObservable() .catchError { error -> Observable<User> in return Observable.error(DomainError.create(with: error)) } .flatMap { user -> Observable<Never> in guard user.hasPermission else { throw DomainError.permission } guard !user.isTemporaryPasswordExpired else { throw DomainError.temporaryPasswordExpired } return Observable.empty() } .asCompletable() } } Domain
  8. struct LoginPresenterImpl: LoginPresenter { func login(email: String, password: String) ->

    Completable { return useCase.login(email: email, password: password) .catchError { error -> Completable in return Completable.error(PresentationError.create(with: error)) } } } Presentation