Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
AKIBA.swift: Layered ArchitectureにおけるRxSwiftを用い...
Search
Takeshi Ihara
April 17, 2017
Programming
2.5k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AKIBA.swift: Layered ArchitectureにおけるRxSwiftを用いたErrorの伝搬
https://classmethod.connpass.com/event/53603/
Takeshi Ihara
April 17, 2017
More Decks by Takeshi Ihara
See All by Takeshi Ihara
iOSDC20200921: Feature Flagを適切に分類することでA/Bテストの運用コストを下げる
nonchalant
3
1.4k
iOSDC 20190906: 動画アプリの投げ銭機能における 消耗型課金の仕組みと実装
nonchalant
3
6.5k
iOSDC 20190906: 動画アプリの投げ銭機能における 消耗型課金の仕組みと実装 with 発表ノート
nonchalant
2
650
Sign In with Apple
nonchalant
1
2.5k
iOSDC RejectCon 20180915: Factoryの自動生成によりテストを書きやすくする
nonchalant
1
760
iOSDC 20180902: 小さくはじめる端末管理
nonchalant
2
1k
devsap 20180728: コード生成のススメ
nonchalant
0
150
potatotips #50: iOSは自動生成の夢を見るか?
nonchalant
0
2k
try! Swift Tokyo 2018: Best Docker Container in Swift
nonchalant
1
1.4k
Other Decks in Programming
See All in Programming
速習iPhone Duo対応
yuukiw00w
2
960
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
34
15k
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
AWSに止められる覚悟してますか?
morizo_1984
2
510
ジョジョの世界をXRで再現する
mofurune
0
110
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
440
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
phperだってパンチカードでコーディングしたい
o0h
PRO
0
200
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.5k
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.4k
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
160
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.8k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
620
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
320
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Agile that works and the tools we love
rasmusluckow
331
22k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
350
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
Transcript
Layered Architectureʹ͓͚Δ RxSwiftΛ༻͍ͨErrorͷൖ Kyobashi.swift Recruit Marketing Partners
ࣗݾհ • Takeshi Ihara / @nonchalant0303 • Recruit Marketing Partners
• iOS Engineer
RxSwiftʹContribute͠·ͨ͠
Layered Architecture *OGSB 1SFTFOUBUJPO %PNBJO
Layered Architecture *OGSB "1*3FRVFTU %# 1SFTFOUBUJPO 6* %PNBJO ϏδωεϩδοΫ
Error *OGSB 1SFTFOUBUJPO %PNBJO $POOFDUJPO 6OBVUIPSJ[FE 4FSWFS&SSPS -PHJD 5SBOTMBUJPO
*OGSB 1SFTFOUBUJPO %PNBJO $POOFDUJPO 4FSWFS&SSPS -PHJD 5SBOTMBUJPO 6OBVUIPSJ[FE "MFSU'BMMCBDL "MFSU3FUSZ
Each Error, Each Process
͜ͷ֤ͷErrorΛͲ͏ͬͯ RxSwiftΛͬͯ ϋϯυϦϯά͢Δ͔͕ࠓճͷ
RxSwift Rx is a generic abstraction of computation expressed through
Observable<Element> interface. This is a Swift version of Rx.
class ViewController: UIViewController { … override func viewDidLoad() { super.viewDidLoad()
presenter.prepare() .subscribe( onNext: { domainModel in // Viewʹө }, onError: { error in // Τϥʔॲཧ } ) .addDisposableTo(disposeBag) } } subscribe - onError Ͳ͜Ͱى͖ͨΤϥʔ͔͔Βͳ͍ʜ
·ͣ
֤ͷΤϥʔΛఆٛ [Infra] enum InfrastructureError: Error { case connection case anthorization
} extension InfrastructureError { static func create(error: Error) -> InfrastructureError { ... return infraError } }
֤ͷΤϥʔΛఆٛ [Domain] enum DomainError: Error { case logic case translation
} extension DomainError { static func create(error: Error) -> DomainError { ... return domainError } }
֤ͷΤϥʔΛఆٛ [Presentation] enum PresentationError: Error { case connection case unknown
}
Layered Architecture x RxSwift *OGSB 1SFTFOUBUJPO %PNBJO 0CTFSWBCMF&OUJUZ 0CTFSWBCMF%PNBJO.PEFM "1*3FRVFTU
&WFOU 7JFXʹө
Layered Architecture x RxSwift *OGSB 1SFTFOUBUJPO %PNBJO 0CTFSWBCMF&OUJUZ 0CTFSWBCMF%PNBJO.PEFM "1*3FRVFTU
&WFOU 7JFXʹө *OGSB&SSPS %PNBJO&SSPS
public static func error(_ error: Swift.Error) -> Observable<E> { return
ErrorProducer(error: error) } Observable.error ObservableType.catchError public func catchError(_ handler: @escaping (Error) throws -> RxSwift.Observable<Self.E>) -> RxSwift.Observable<Self.E> 0CTFSWBCMFʹแΜͩΤϥʔΛੜ͢Δ 0CTFSWBCMFͷதͰൃੜͨ͠ΤϥʔΛ $BUDIͯ͠ճ෮ॲཧΛ͢Δ
protocol Repository { func find() -> Observable<Entity> } struct RepositoryImpl:
Repository { … func find() -> Observable<Entity> { return apiClient.send() .catchError { return Observable.error(InfrastructureError.create(error: $0)) } } } %PNBJOʹެ։͢Δ*OUFSGBDF ͜͜Ͱ"1*͔Βฦ͖ͬͯͨ&SSPSΛ *OGSB&SSPSʹม͍ͯ͠Δ *OGSB
struct Translator { static func translate(entity: Entity) throws -> DomainModel
{ ... throw DomainError.translation ... return domainModel } } protocol UseCase { func prepare() -> Observable<DomainModel> } struct UseCaseImpl: UseCase { … func prepare() -> Observable<DomainModel> { return repository.find() .map { try Translator.translate(entity: $0) } } } NBQͰUISPX͞ΕͨΒ 0CTFSWBCMFFSSPSʹͳΔ %PNBJO
struct Presenter { … func prepare() -> Observable<DomainModel> { return
useCase.prepare() .catchError { error in guard let infraError = error as? InfrastructureError else { return Observable.error(PresentationError.unknown) } switch infraError { case .connection: return Observable.error(PresentationError.connection) default: return Observable.error(PresentationError.unknown) } } } } 1SFTFOUBUJPO ಛఆͷ&SSPSܕͷͱ͖ʹ ಛผͳΤϥʔΛฦ͢
͋ͱPresentationErrorͷܕ ΛݟͯݸผͷॲཧΛ͢Ε
*OGSB 1SFTFOUBUJPO %PNBJO $POOFDUJPO 4FSWFS&SSPS -PHJD 5SBOTMBUJPO 6OBVUIPSJ[FE "MFSU'BMMCBDL "MFSU3FUSZ
Each Error, Each Process
·ͱΊ • Layered Architecture x RxSwiftͷΤϥʔ ൖʹ͍ͭͯͷҰྫΛߟ͑ͨ • catchErrorerrorΛฦͣ͞ճ෮ॲཧॻ͚ ΔͷͰҟৗܥ͔Βਖ਼ৗܥʹΔ͜ͱՄೳ