Share
Embed
Transcript
46 slides
-
#if DEBUG DispatchQueue.global().async { // ϞοΫσʔλΛ࡞ let user = User.mockData()
// ݁Ռॲཧ } #else let request = URLRequest(url: URL(string: "https://api.test.com/ users/foo")!) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in // ݁Ռॲཧ } task.resume() #endif -
URL Loading System The URL loading system is a set
of classes and protocols that allow your app to access content referenced by a URL. At the heart of this technology is the NSURL class, which lets your app manipulate URLs and the resources they refer to. https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ URLLoadingSystem/URLLoadingSystem.html -
URL loading system͕αϙʔ τ͍ͯ͠Δϓϩτίϧ • ftp:// • http:// • https://
• file:/// • data: -
Foundation͕ఏڙ͍ͯ͠ΔΫϥ ε • URLͷίϯςϯπΛϩʔυ • αʔόʹσʔλΛΞοϓϩʔυ • ΫοΩʔετϨʔδͷཧ • ϨεϙϯεΩϟογϡͷ੍ޚ
• ΞϓϦέʔγϣϯݻ༗ͷํ๏ͰͷΫϨσϯγϟϧετϨʔδͱೝ ূͷॲཧ • ΧελϜϓϩτίϧͷ֦ு -
URLProtocol An NSURLProtocol object handles the loading of protocol-specific URL
data. The NSURLProtocol class itself is an abstract class that provides the infrastructure for processing URLs with a specific URL scheme. You create subclasses for any custom protocols or URL schemes that your app supports. https://developer.apple.com/documentation/foundation/urlprotocol -
ͲͷΑ͏ͳతͰ͏͔ • ΧελϜϨεϙϯεΛฦ͢ʢςετతͷελϒʣ • ωοτϫʔΫΛεΩοϓͯ͠ϩʔΧϧσʔλΛฦ͢ʢΩϟο γϡʣ • ϦμΠϨΫτʢϓϩΩγʣ • ϢʔβʔΤʔδΣϯτͷมߋ
• ΧελϜϓϩτίϧ https://www.raywenderlich.com/76735/using-nsurlprotocol-swift -
ඞ࣮ͣ͠ͳ͍ͱ͍͚ͳ͍ͷ • class func canInit(with request: URLRequest) - > Bool
• class func canonicalRequest(for request: URLRequest) -> URLRequest • func startLoading() • func stopLoading() -
ͲͷΑ͏ͳతͰ͏͔ • ΧελϜϨεϙϯεΛฦ͢ʢςετతͷελϒʣ • ωοτϫʔΫΛεΩοϓͯ͠ϩʔΧϧσʔλΛฦ͢ʢΩϟο γϡʣ • ϦμΠϨΫτʢϓϩΩγʣ • ϢʔβʔΤʔδΣϯτͷมߋ
• ΧελϜϓϩτίϧ https://www.raywenderlich.com/76735/using-nsurlprotocol-swift -
• ϦΫΤετΛϋϯυϦϯά͢Δ߹ `true` Λฦ͢ • ΠϯελϯεԽ͞Εͯ௨৴ॲཧ • `false`Λฦͨ͠߹ଞͷURLProtocolॲཧ ͕ҠΔ override
class func canInit(with request: URLRequest) -> Bool { return true } -
• 'canonical'ͳϦΫΤετΛฦ͢ • ඞཁͳ߹͜͜Ͱ'canonical'ͳܗࣜʹมߋ ͢Δ • ඞཁͳ͚Εͦͷ··ฦ͢ override class func
canonicalRequest(for request: URLRequest) -> URLRequest { return request } -
override func startLoading() { // ϞοΫσʔλΛऔಘʢྫ͑Bundle͔ΒJSONσʔλΛऔಘʣ guard let path =
Bundle.main.path(forResource: "user", ofType: "json"), let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else { // Τϥʔॲཧ } let client = self.client let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: ["Content-Type" : "application/ json;"]) // ϨεϙϯεΛฦ͢ client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: .notAllowed) // σʔλΛฦ͢ client?.urlProtocol(self, didLoad: data) // ௨৴Λऴྃ client?.urlProtocolDidFinishLoading(self) } -
override func startLoading() { ... // Τϥʔॲཧ let client =
self.client let response = HTTPURLResponse(url: request.url!, statusCode: 500, httpVersion: "HTTP/1.1", headerFields: ["Content-Type" : "application/ json;"]) // ϨεϙϯεΛฦ͢ client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: .notAllowed) // ΤϥʔΛ࡞ͯ͠௨৴Λऴྃ let error = NSError(domain: "CustomURLProtocolError", code: 10001, userInfo: nil) client?.urlProtocol(self, didFailWithError: error) return .... } -
URLProtocolClient • URLProtocolͷαϒΫϥε͕"URL Loading System"ͱΓͱΓ͢Δϓϩτίϧ • func urlProtocol(URLProtocol, didReceive: URLResponse,
cacheStoragePolicy: URLCache.StoragePolicy) • func urlProtocol(URLProtocol, didLoad: Data) • func urlProtocolDidFinishLoading(URLProtocol) • func urlProtocol(URLProtocol, didFailWithError: Error) • func urlProtocol(URLProtocol, didReceive: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, didCancel: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, wasRedirectedTo: URLRequest, redirectResponse: URLResponse) • func urlProtocol(URLProtocol, cachedResponseIsValid: CachedURLResponse) -
URLProtocolClient • URLProtocolͷαϒΫϥε͕"URL Loading System"ͱΓͱΓ͢Δϓϩτίϧ • func urlProtocol(URLProtocol, didReceive: URLResponse,
cacheStoragePolicy: URLCache.StoragePolicy) • func urlProtocol(URLProtocol, didLoad: Data) • func urlProtocolDidFinishLoading(URLProtocol) • func urlProtocol(URLProtocol, didFailWithError: Error) • func urlProtocol(URLProtocol, didReceive: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, didCancel: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, wasRedirectedTo: URLRequest, redirectResponse: URLResponse) • func urlProtocol(URLProtocol, cachedResponseIsValid: CachedURLResponse) ޭ࣌ -
URLProtocolClient • URLProtocolͷαϒΫϥε͕"URL Loading System"ͱΓͱΓ͢Δϓϩτίϧ • func urlProtocol(URLProtocol, didReceive: URLResponse,
cacheStoragePolicy: URLCache.StoragePolicy) • func urlProtocol(URLProtocol, didLoad: Data) • func urlProtocolDidFinishLoading(URLProtocol) • func urlProtocol(URLProtocol, didFailWithError: Error) • func urlProtocol(URLProtocol, didReceive: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, didCancel: URLAuthenticationChallenge) • func urlProtocol(URLProtocol, wasRedirectedTo: URLRequest, redirectResponse: URLResponse) • func urlProtocol(URLProtocol, cachedResponseIsValid: CachedURLResponse) ࣦഊ࣌ -
• ྫ͑ `application(_: didFinishLaunchingWithOptions:)`Ͱొ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool { // ༻ొ URLProtocol.registerClass(CustomURLProtocol.self) return true } URL Loading Systemʹొ -
• Կҙࣝ͠ͳͯ͘ྑ͍ • ϦϦʔε༻ίʔυͦͷ··ͷ࣮Ͱྑ͍ let request = URLRequest(url: URL(string: "https://api.test.com/users/
foo")!) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in // ݁Ռॲཧ } task.resume() ϦΫΤετॲཧ -
• ྫ͑ίϯύΠϧFlagsͰ࣮Λ͚Δඞཁ͕ ͳ͍ #if DEBUG let path = Bundle.main.path(forResource: "user",
ofType: "json")! let data = try! Data(contentsOf: URL(fileURLWithPath: path)) DispatchQueue.global().async { // ݁Ռॲཧ } #else let request = URLRequest(url: URL(string: "https://api.test.com/users/foo")!) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in // ݁Ռॲཧ } task.resume() #endif -
• Կҙࣝ͠ͳͯ͘ྑ͍ • ϦϦʔε༻ίʔυͦͷ··ͷ࣮Ͱྑ͍ • ྫ͑ίϯύΠϧFlagsͰ࣮Λ͚Δඞཁ͕ͳ͍ let request = URLRequest(url:
URL(string: "https://api.test.com/users/ foo")!) let task = URLSession.shared.dataTask(with: request) { (data, response, error) in // ݁Ռॲཧ } task.resume() ϦΫΤετॲཧ -
• ྫ͑ `application(_: didFinishLaunchingWithOptions:)`Ͱొ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool { // ༻ొ URLProtocol.registerClass(CustomURLProtocol.self) return true } URL Loading Systemʹొ -
URLSession.shared • The shared session uses the shared NSURLCache, NSHTTPCookieStorage,
and NSURLCredentialStorage objects, uses a shared custom networking protocol list (configured with registerClass(_:) and unregisterClass(_:)), and is based on a default configuration. • In other words, if you’re doing anything with caches, cookies, authentication, or custom networking protocols, you should probably be using a default session instead of the shared session. https://developer.apple.com/documentation/foundation/urlsession/1409000-shared -
• URLSessionConfigurationͷ var protocolClasses: [AnyClass]? ʹઃఆ let config = URLSessionConfiguration.default
config.protocolClasses = [CustomURLProtocol.self] let session = URLSession(configuration: config) let task = session.dataTask(with: urlRequest) { (data, response, error) in ... } ಛఆͷϦΫΤετͷΈར༻ -
• ΧελϜURLProtocolΛઃఆͨ͠URLSessionConfigurationΛݩʹ SessionManagerΛੜͯ͠ར༻ • ()࡞ͨ͠SessionManagerͲ͔͜Ͱอ͓࣋ͯ͘͠ඞཁ͋Γ let config = URLSessionConfiguration.default config.protocolClasses
= [CustomURLProtocol.self] self.manager = SessionManager(configuration: config) // อ࣋͢Δ manager.request(url).response { response in ... } AlamofireͰར༻ -
• ΧελϜURLProtocolΛઃఆͨ͠URLSessionConfigurationΛݩʹ URLSessionAdapterɺSessionΛੜͯ͠ར༻ let config = URLSessionConfiguration.default config.protocolClasses = [CustomURLProtocol.self]
let adapter = URLSessionAdapter(configuration: config) let session = Session(adapter: adapter) session.send(request) { (result) in ... } APIKitͰར༻ -
Appendix • [URL Loading System]: https://developer.apple.com/library/content/ documentation/Cocoa/Conceptual/URLLoadingSystem/ URLLoadingSystem.html • [URLProtocol]:
https://developer.apple.com/documentation/foundation/ urlprotocol • [Using NSURLProtocol with Swift]: https://www.raywenderlich.com/76735/ using-nsurlprotocol-swift • [iOS Advent Calendar 2011 5 / NSURLProtocolͷ͍ํ]: http:// faultier.blog.jp/archives/1762587.html • [Using NSURLProtocol for Testing]: https://yahooeng.tumblr.com/post/ 141143817861/using-nsurlprotocol-for-testing