URLProtocolとMethod Swizzlingの話 #potatotips 37
௨৴ॲཧΛࠩ͠ସ͑ͯΈͨ
View Slide
ࣗݾհ• ాதୡ (@tattn)• Ϡϑʔͷ2016৽ଔ
Qiitaͱ͔Twitterͱ͔ͬͯ·͢• ։ൃ͕രʹͳΔSwift༻XcodeϓϥάΠϯΛ·ͱΊͯΈͨ• ͏ͱख์ͤͳ͘ͳΔSwift Extensionू (Swift3൛)@tanakasan2525
APIͷϢχοτςετͲ͏ͯ͠·͔͢ʁ
DIʁ ϥΠϒϥϦʁ
MockingjayศརͰ͢ΑͶ
Mockingjayhttps://github.com/kylef/Mockingjaylet body = [ "user": "Kyle" ]stub(uri("/{user}/{repository}"), json(body))
Ͳ͏͍͏ΈͰಈ͍ͯΔΜͩΖ͏ !
ௐͯΈΔͱ
URLProtocolͱMethod SwizzlingΛͬͯ௨৴ॲཧΛࠩ͠ସ͍͑ͯ·ͨ͠
URLProtocolhttps://developer.apple.com/reference/foundation/urlprotocolαϙʔτ֎ͷϓϩτίϧͰ௨৴͢Δ߹ϦΫΤετΛಠࣗͷํ๏Ͱॲཧ͢Δ࣌ʹ͏Ϋϥεɻ
Mock༻ͷURLProtocolpublic 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.mockconfiguration.protocolClasses?.insert(MockURLProtocol.self, at: 0)URLProtocol.registerClass(MockURLProtocol.self)return configuration}}
ֶ͔ͤͬ͘ΜͩͷͰϥΠϒϥϦԽ͠·ͨ͠ !
Replacerhttps://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 injson = 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-3665Fix @discardableResult when invoking function with explicitnamespace #7201
SwiftͷਐԽɾվળࢭ·Βͳ͍Ͱ͢Ͷʂ !
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ