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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
3.1k
iOS 14の位置情報系アップデート
tattn
0
22k
Other Decks in Technology
See All in Technology
システム標準化PMOから ガバメントクラウドCoEへ
techniczna
1
150
詳解 強化学習 / In-depth Guide to Reinforcement Learning
prinlab
0
340
スピンアウト講座01_GitHub管理
overflowinc
0
270
Phase01_AI座学_基礎
overflowinc
0
810
【Λ(らむだ)】最近のアプデ情報 / RPALT20260318
lambda
0
130
Phase06_ClaudeCode実践
overflowinc
0
390
テストプロセスにおけるAI活用 :人間とAIの共存
hacomono
PRO
0
110
20260321_エンベディングってなに?RAGってなに?エンベディングの説明とGemini Embedding 2 の紹介
tsho
0
130
スピンアウト講座06_認証系(API-OAuth-MCP)入門
overflowinc
0
220
Copilot 宇宙へ 〜生成AIで「専門データの壁」を壊す方法〜
nakasho
0
130
Tebiki Engineering Team Deck
tebiki
0
27k
ガバメントクラウドにおけるAWSの長期継続割引について
takeda_h
2
5.4k
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
290
Visualization
eitanlees
150
17k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Ruling the World: When Life Gets Gamed
codingconduct
0
180
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
210
Building the Perfect Custom Keyboard
takai
2
720
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
110
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
240
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ͷਐԽɾվળࢭ ·Βͳ͍Ͱ͢Ͷʂ !
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ʂ