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
Moya+RxSwiftで実現する!ReactiveなAPIリクエスト
Search
satoshin21
October 02, 2017
Technology
0
2.9k
Moya+RxSwiftで実現する!ReactiveなAPIリクエスト
俺コン Vol.1 / Day. 1
https://orecon.connpass.com/event/63769/
satoshin21
October 02, 2017
Tweet
Share
More Decks by satoshin21
See All by satoshin21
少数精鋭で戦うための技術的改善について
satoshin21
3
990
GTXiLibで小さく始めるAccessibility Testing
satoshin21
0
4.7k
iPhoneのカメラで写真撮影から現像までの技術を紐解く
satoshin21
4
2.9k
try! swift-sh
satoshin21
2
750
Reduxを取り入れて開発はpairs開発はどう変わったか
satoshin21
0
330
レガシーなアプリケーションの 60fps化を目指す為にやっていること
satoshin21
13
3.6k
Introducing CodeLayout with Tips
satoshin21
6
1.4k
World of No Interface Builder
satoshin21
0
1.7k
What I've done to attend WWDC
satoshin21
0
73
Other Decks in Technology
See All in Technology
地理空間データ可視化・解析・活用ソリューション Pacific Spatial Solutions (PSS)
pacificspatialsolutions
0
300
オーナーシップを持つ領域を明確にする
konifar
13
3.2k
サーバー間 GraphQL と webmock-graphql の話 / server-to-server graphql and webmock-graphql
qsona
2
190
Azure Container Apps + Bicep 〜 こんな感じで運用しています
kaz29
2
480
プラットフォームってつくることより計測することが重要なんじゃないかという話 / Platform Engineering Meetup #8
taishin
1
370
Kernel MemoryでAzure OpenAI Serviceとお手軽データソース連携
mitsuzono
1
260
自己改善からチームを動かす! 「セルフエンジニアリングマネージャー」のすゝめ
shoota
6
800
Cloud Native Java with Spring Boot (CNCF Aarhus, April 2024)
thomasvitale
1
180
Delivering Millions of Messages within seconds @ Duolingo
pelelgrino
0
350
SIEMを用いて、セキュリティログ分析の可視化と分析を実現し、PDCAサイクルを回してみた
coconala_engineer
0
340
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
2.1k
非同期推論システムによるコスト削減と信頼性向上
koki_nishihara
0
260
Featured
See All Featured
Building Effective Engineering Teams - LeadDev
addyosmani
28
1.8k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
221
21k
Large-scale JavaScript Application Architecture
addyosmani
504
110k
The World Runs on Bad Software
bkeepers
PRO
61
6.7k
Building Your Own Lightsaber
phodgson
99
5.7k
Debugging Ruby Performance
tmm1
70
11k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
125
32k
Web development in the modern age
philhawksworth
202
10k
Building Flexible Design Systems
yeseniaperezcruz
319
37k
KATA
mclloyd
15
12k
A Tale of Four Properties
chriscoyier
151
22k
Transcript
Moya + RxSwi,Ͱ࣮ݱ͢Δʂ Reac%veͳAPIϦΫΤετ Զίϯ Vol.1 Day. 1 @satoshin21 @satoshin21
1
INTRODUCE • @satoshin21 • eureka, Inc. • Pairs JP iOS
Applica<on Engineer • created Chainable Anima<on Library "Anima" @satoshin21 2
@satoshin21 3
What's Moya? @satoshin21 4
Whats' Moya? • Network abstrac.on layer • RxSwi6, Reac.veSwi6ͱͷ࿈ܞ͕σϑΥϧτͰՄೳ •
encapsulates Alamofire • ϓϥάΠϯΛ࡞Մೳ • ίϛϡχςΟ͕׆ൃ ( ༷ʑͳExtension ) @satoshin21 5
How to implement Moya.TargetType public enum GitHub { case zen
case userProfile(String) case userRepositories(String) } @satoshin21 6
How to implement Moya.TargetType extension GitHub: TargetType { public var
baseURL: URL { return URL(string: "https://api.github.com")! } public var path: String { switch self { case .userProfile(let name): return "/users/\(name.urlEscaped)" ... } } public var method: Moya.Method = .get public var parameters: [String: Any]? { ... } } @satoshin21 7
How to request with RxSwi0 & Moya let githubProvider =
MoyaProvider<GitHub>() githubProvider.request(.userProfile("satoshin21")).subscribe { event in switch event { case let .next(response): let jsonString = try? response.mapString() message = jsonString ?? message case let .error(error): print(error) default: break } } @satoshin21 8
@satoshin21 9
That's it? @satoshin21 10
Sampleͷ՝ • enumʹTargetTypeΛ࣮ • ΤϯυϙΠϯτ͕૿͑Δͱࠈ • Observable<Moya.Response> • Response ParseΛຖߦ͏
• APIKitͷΑ͏ʹType SafeͰͳ͍ @satoshin21 11
ཧܗ DoSomething() .asDriver(onErrorJustReturn: nil) .drive(imageView.rx.image) .addDisposableTo(disposeBag) @satoshin21 12
Moya Customiza-on for Pairs(jp) • enum to struct • Type
safeͳObservable<E> • Type Erasure @satoshin21 13
@satoshin21 14
enum to struct enum API { } extension API {
enum Community {} } // Community API extension API.Community { /// ίϛϡχςΟใऔಘ struct GetSingle: PairsTargetType { ... } /// Search struct Search: PairsTargetType { ... } } @satoshin21 15
enum to struct let communitySearch = API.Community.Search() @satoshin21 16
PairsTargetType protocol PairsTargetType: TargetType, ObservableType { /// DecodedResponseType associatedtype D
/// ObservableType.EʹόΠϯυͤ͞ΔͨΊ associatedtype E /// Ϩεϙϯε͔ΒೝΊ͍ͯΔܗࣜσίʔυ͢ΔʢJSONͳͲʣ func decodeResponse(_ response: Moya.Response) throws -> D /// Ϩεϙϯεใ͔Βྃ·ͰͷObservableΛ࡞͢Δ func didDecodeData(_ responseData: D) -> Observable<E> } @satoshin21 17
implements PairsTargetType struct GetCampaign: PairsTargetType { // Moya.Response -> JSON
typealias D = JSON // JSON -> [Community] typealias E = [Community] func didDecodeData(_ responseData: JSON) -> Observable<[Community]> { // JSON͔Β[Community]ͷϚοϐϯάDBͷอଘͳͲ let communities = ... return communities } } @satoshin21 18
PairsTargetTypeͷObservableԽ extension PairsTargetType { func subscribe<O: ObserverType>(_ observer: O) ->
Disposable where O.E == E { // APIϦΫΤετ -> decodeResponse(response)ͰMoya.Response͔Βσίʔυ let requestData = Observable<D>.create { (observer) in let cancellable = API.provider.request(.init(target: self), completion: { (result) in switch result { case .success(let response): let responseData = try self.decodeResponse(response) observer.onNext(responseData) observer.onCompleted() } ) return Disposables.create(with: cancellable.cancel) } // σίʔυ͞ΕͨΦϒδΣΫτ(ओʹJSON)͔ΒϚοϐϯά͞ΕͨΦϒδΣΫτ return requestData .flatMap(self.didDecodeData) .subscribe(observer) } @satoshin21 19
RxMoyaProvider<AnyPairsTarget> extension API { fileprivate static let provider = API.Provider()
// PairsTargetTypeΛ࣮ͨ͠ϦΫΤετͷॲཧΛߦ͏ fileprivate class Provider: RxMoyaProvider<AnyPairsTarget> { init() { } } } @satoshin21 20
Binding API.Image.Get() .asDriver(onErrorJustReturn: nil) .drive(imageView.rx.image) .addDisposableTo(disposeBag) @satoshin21 21
How we use Moya in Pairs // ίϛϡχςΟͱΧςΰϦʔΛऔಘ Observable .zip(
API.Community.GetCommunities(), API.Community.GetCategories(), resultSelector: { $0 }) .subscribe( onNext: { (communities: [Community], categories: [Category]) in // do something! }).addDisposableTo(disposeBag) @satoshin21 22
Summary • Moyaࣗମڧྗ͕ͩɺΧελϚΠζͰΑΓReac)veʹ @satoshin21 23
@satoshin21 24