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
通信処理を差し替えてみた話
Search
Tatsuya Tanaka
February 15, 2017
Technology
5
2.5k
通信処理を差し替えてみた話
URLProtocolとMethod Swizzlingの話
#potatotips 37
Tatsuya Tanaka
February 15, 2017
Tweet
Share
More Decks by Tatsuya Tanaka
See All by Tatsuya Tanaka
iPhoneのセンサー情報をmacOSアプリでリアルタイム活用するための技術
tattn
1
720
Better use of SwiftUI
tattn
0
480
Swift Concurrencyによる安全で快適な非同期処理
tattn
2
1.4k
iOSアプリの技術選択2022
tattn
7
4k
Widget Suggestions 対応と ヤフーの新OS対応
tattn
1
1.4k
WidgetKitで良い体験を作るには / Good experience with WidgetKit
tattn
2
1.9k
既存アプリにSwiftUIをどう組み込んでいくか
tattn
8
2.5k
iOS 14からのアプリ内課金
tattn
5
3k
iOS 14の位置情報系アップデート
tattn
0
22k
Other Decks in Technology
See All in Technology
マルチプレーンGPUネットワークを実現するシャッフルアーキテクチャの整理と考察
markunet
2
250
社内レビューは機能しているのか
matsuba
0
130
20260311 ビジネスSWG活動報告(デジタルアイデンティティ人材育成推進WG Ph2 活動報告会)
oidfj
0
330
モブプログラミング再入門 ー 基本から見直す、AI時代のチーム開発の選択肢 ー / A Re-introduction of Mob Programming
takaking22
5
1.5k
プラットフォームエンジニアリングはAI時代の開発者をどう救うのか
jacopen
4
1.7k
It’s “Time” to use Temporal
sajikix
1
140
ランサムウエア対策してますか?やられた時の対策は本当にできてますか?AWSでのリスク分析と対応フローの泥臭いお話。
hootaki
0
130
JAWS DAYS 2026 楽しく学ぼう!ストレージ 入門
yoshiki0705
2
180
僕、S3 シンプルって名前だけど全然シンプルじゃありません よろしくお願いします
yama3133
1
210
SRE NEXT 2026 CfP レビュアーが語る聞きたくなるプロポーザルとは?
yutakawasaki0911
1
320
Go標準パッケージのI/O処理をながめる
matumoto
0
210
Scrumは歪む — 組織設計の原理原則
dashi
0
180
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
110k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
350
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
150
How STYLIGHT went responsive
nonsquared
100
6k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
180
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
21k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Optimising Largest Contentful Paint
csswizardry
37
3.6k
Scaling GitHub
holman
464
140k
Transcript
௨৴ॲཧΛࠩ͠ସ͑ͯΈͨ
ࣗݾհ • ాதୡ (@tattn) • Ϡϑʔͷ2016৽ଔ
Qiitaͱ͔Twitterͱ͔ͬͯ·͢ • ։ൃ͕രʹͳΔSwift༻XcodeϓϥάΠϯΛ·ͱΊͯΈͨ • ͏ͱख์ͤͳ͘ͳΔSwift Extensionू (Swift3൛) @tanakasan2525
APIͷϢχοτςετͲ͏ͯ͠·͢ ͔ʁ
DIʁ ϥΠϒϥϦʁ
MockingjayศརͰ͢ΑͶ
Mockingjay https://github.com/kylef/Mockingjay let body = [ "user": "Kyle" ] stub(uri("/{user}/{repository}"),
json(body))
Ͳ͏͍͏ΈͰಈ͍ͯΔΜͩΖ͏ !
ௐͯΈΔͱ
URLProtocolͱMethod Swizzling Λͬͯ௨৴ॲཧΛࠩ͠ସ͍͑ͯ·͠ ͨ
URLProtocol https://developer.apple.com/reference/foundation/urlprotocol αϙʔτ֎ͷϓϩτίϧͰ௨৴͢Δ߹ ϦΫΤετΛಠࣗͷํ๏Ͱॲཧ͢Δ࣌ʹ͏Ϋϥεɻ
Mock༻ͷURLProtocol public class MockURLProtocol: URLProtocol { override open func startLoading()
{ let jsonString = "{\"mock\": \"data\"}" let json = jsonString.data(using: .utf8)! self.client?.urlProtocol(self, didLoad: json) self.client?.urlProtocolDidFinishLoading(self) } // ͦͷଞϝιουলུ }
Method SwizzlingͰϞοΫ༻ͷURLProtocol ʹࠩ͠ସ͑ public extension URLSessionConfiguration { public class func
setup() { let `default` = class_getClassMethod(URLSessionConfiguration.self, #selector(getter: URLSessionConfiguration.default)) let swizzled = class_getClassMethod(URLSessionConfiguration.self, #selector(getter: URLSessionConfiguration.mock)) method_exchangeImplementations(`default`, swizzled) } private dynamic class var mock: URLSessionConfiguration { let configuration = self.mock configuration.protocolClasses?.insert(MockURLProtocol.self, at: 0) URLProtocol.registerClass(MockURLProtocol.self) return configuration } }
ֶ͔ͤͬ͘ΜͩͷͰϥΠϒϥϦԽ͠· ͨ͠ !
Replacer https://github.com/tattn/Replacer ௨৴ͷελϒԽMethod SwizzlingΛαϙʔτ͢ΔϥΠϒϥϦ
Method ChainͰΦϓγϣϯΛઃఆ͠·͢ self.urlStub .url("echo.jsontest.com/[a-z]+/.*") .httpMethod(.post) .json(["test": "data"]) .delay(1.5)
QuickͱAlamofireͰͷελϒԽ describe("Quick compatibility test") { it("returns mock data") { let
url = "http://echo.jsontest.com/key/value/one/two" var json: [String: String]? Alamofire.request(url, method: .post).responseJSON { response in json = response.result.value as? [String: String] } expect(json?["test"]).toEventually(equal("data")) } }
ओͳػೳ • ௨৴ͷελϒԽ • XCTestҎ֎ (Host ApplicationؚΉ) Ͱ༻Մೳ • Method
Swizzlingͷαϙʔτػೳ ͳͲͰ͢ɻ
ྑ͔ͬͨΒͬͯΈ͍ͯͩ͘͞ ! (ʁʁ)ʻ ܅⭐͕େ͖ͳϑϨϯζͳΜͩͶʂ
͋ɺͦ͏͍͑ɺɺɺ
࡞͍ͬͯΔ࣌ʹSwiftͷόάʹؾ͕͖·ͨ͠ ڥ: Xcode 8.2, Swift 3.0.2
άϩʔόϧఆٛ͞ΕͨؔʹϞδϡʔϧ໊Λ͚ Δͱɺ@discardableResult͕ਖ਼ৗʹಈ࡞͠ͳ͍
ઌఔௐͯΈΔͱɺमਖ਼͞ΕͨΈ͍ͨͰ͢ ! https://bugs.swift.org/browse/SR-3665 Fix @discardableResult when invoking function with explicit
namespace #7201
SwiftͷਐԽɾվળࢭ ·Βͳ͍Ͱ͢Ͷʂ !
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ʂ