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
3k
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
1.1k
GTXiLibで小さく始めるAccessibility Testing
satoshin21
0
4.8k
iPhoneのカメラで写真撮影から現像までの技術を紐解く
satoshin21
4
3k
try! swift-sh
satoshin21
2
800
Reduxを取り入れて開発はpairs開発はどう変わったか
satoshin21
0
340
レガシーなアプリケーションの 60fps化を目指す為にやっていること
satoshin21
13
3.7k
Introducing CodeLayout with Tips
satoshin21
6
1.5k
World of No Interface Builder
satoshin21
0
1.7k
What I've done to attend WWDC
satoshin21
0
83
Other Decks in Technology
See All in Technology
JBUG岡山 #6 WordCamp男木島の チームビルディング
takeshifurusato
0
150
[NIKKEI Tech Talk]Bias for Action!! 実践から学ぶための仕組とコミュニティ / Community for Practice and Learning
kanamasa
0
280
【基調講演】変える、今ここから ― IoTとAIで紡ぐ未来
soracom
PRO
0
320
「単なる OAuth 2.0 を認証に使うと、車が通れるほどのどでかいセキュリティー・ホールができる」のか検証してみた
terara
0
380
AWSでRAGを作る法方
sonoda_mj
1
140
Azure OpenAI Service Dev Day / LLMでできる!使える!生成AIエージェント
masahiro_nishimi
3
810
スタートアップにおける組織設計とスクラムの長期戦略 / Scrum Fest Kanazawa 2024
yoshikiiida
13
3.6k
Luupの開発組織におけるインシデントマネジメントの変遷 ver.RoadtoSRENEXT2024
grimoh
1
270
エンジニアリングマネージャーはどう学んでいくのか #devsumi / How Do Engineering Managers Continue to Learn and Grow?
expajp
4
1.3k
LINE WORKSへ簡単通知!Incoming Webhookアプリの紹介
mmclsntr
0
110
サービス開発を前に進めるために 新米リードエンジニアが 取り組んだこと / Steps Taken by a Novice Lead Engineer to Advance Service Development
nologyance
0
180
ABEMAにおけるLLMを用いたコンテンツベース推薦システム導入と効果検証
cyberagentdevelopers
PRO
1
760
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
35
4.4k
How GitHub Uses GitHub to Build GitHub
holman
471
290k
Why Our Code Smells
bkeepers
PRO
332
56k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
502
140k
The Power of CSS Pseudo Elements
geoffreycrofte
64
5.2k
Fantastic passwords and where to find them - at NoRuKo
philnash
42
2.7k
Bash Introduction
62gerente
607
210k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
23
1.9k
StorybookのUI Testing Handbookを読んだ
zakiyama
15
4.9k
Infographics Made Easy
chrislema
238
18k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Making Projects Easy
brettharned
111
5.7k
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