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
650
Better use of SwiftUI
tattn
0
450
Swift Concurrencyによる安全で快適な非同期処理
tattn
2
1.3k
iOSアプリの技術選択2022
tattn
7
3.9k
Widget Suggestions 対応と ヤフーの新OS対応
tattn
1
1.3k
WidgetKitで良い体験を作るには / Good experience with WidgetKit
tattn
2
1.7k
既存アプリにSwiftUIをどう組み込んでいくか
tattn
8
2.4k
iOS 14からのアプリ内課金
tattn
5
2.9k
iOS 14の位置情報系アップデート
tattn
0
22k
Other Decks in Technology
See All in Technology
KotlinConf 2025_イベントレポート
sony
1
140
Android Audio: Beyond Winning On It
atsushieno
0
2.4k
会社紹介資料 / Sansan Company Profile
sansan33
PRO
6
380k
[ JAWS-UG 東京 CommunityBuilders Night #2 ]SlackとAmazon Q Developerで 運用効率化を模索する
sh_fk2
3
450
Firestore → Spanner 移行 を成功させた段階的移行プロセス
athug
1
490
はじめてのOSS開発からみえたGo言語の強み
shibukazu
3
890
バイブスに「型」を!Kent Beckに学ぶ、AI時代のテスト駆動開発
amixedcolor
2
580
Snowflake Intelligenceにはこうやって立ち向かう!クラシルが考えるAI Readyなデータ基盤と活用のためのDataOps
gappy50
0
270
Codeful Serverless / 一人運用でもやり抜く力
_kensh
7
450
「全員プロダクトマネージャー」を実現する、Cursorによる仕様検討の自動運転
applism118
22
12k
DroidKaigi 2025 Androidエンジニアとしてのキャリア
mhidaka
2
370
これでもう迷わない!Jetpack Composeの書き方実践ガイド
zozotech
PRO
0
1k
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
26
1.9k
Balancing Empowerment & Direction
lara
3
620
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
The Pragmatic Product Professional
lauravandoore
36
6.9k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
139
34k
How STYLIGHT went responsive
nonsquared
100
5.8k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
19k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Rails Girls Zürich Keynote
gr2m
95
14k
Docker and Python
trallard
46
3.6k
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ͷਐԽɾվળࢭ ·Βͳ͍Ͱ͢Ͷʂ !
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ʂ