Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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.4k
iOSDC 20190906: 動画アプリの投げ銭機能における 消耗型課金の仕組みと実装 with 発表ノート
nonchalant
2
640
Sign In with Apple
nonchalant
1
2.5k
iOSDC RejectCon 20180915: Factoryの自動生成によりテストを書きやすくする
nonchalant
1
750
iOSDC 20180902: 小さくはじめる端末管理
nonchalant
2
1k
devsap 20180728: コード生成のススメ
nonchalant
0
140
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
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
240
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
1.1k
Press start. Python's next generation.
willingc
PRO
3
140
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
110
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
180
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
230
VibeCodingからAgenticWorkflowへ
starfish719
0
870
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
730
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
290
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
390
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
330
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
3
1.9k
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
The browser strikes back
jonoalderson
0
1.5k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
Statistics for Hackers
jakevdp
799
230k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
280
Rails Girls Zürich Keynote
gr2m
96
14k
Chasing Engaging Ingredients in Design
codingconduct
0
280
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
sira's awesome portfolio website redesign presentation
elsirapls
0
340
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Λฦͣ͞ճ෮ॲཧॻ͚ ΔͷͰҟৗܥ͔Βਖ਼ৗܥʹΔ͜ͱՄೳ