103 lines
3.9 KiB
Swift
103 lines
3.9 KiB
Swift
//
|
|
// MyURLProtocol.swift
|
|
// Pods
|
|
//
|
|
// Created by Lorenzo on 12/10/18.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
class MyURLProtocol: URLProtocol {
|
|
|
|
struct Constants {
|
|
static let RequestHandledKey = "URLProtocolRequestHandled"
|
|
}
|
|
|
|
var session: URLSession?
|
|
var sessionTask: URLSessionDataTask?
|
|
static var URLProtocolDelegate: MyURLProtocolDelegate?
|
|
|
|
override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
|
|
super.init(request: request, cachedResponse: cachedResponse, client: client)
|
|
|
|
if session == nil {
|
|
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
|
|
}
|
|
}
|
|
|
|
override class func canInit(with request: URLRequest) -> Bool {
|
|
if MyURLProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
|
|
return request
|
|
}
|
|
|
|
override func startLoading() {
|
|
let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
|
|
MyURLProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest)
|
|
sessionTask = session?.dataTask(with: newRequest as URLRequest)
|
|
sessionTask?.resume()
|
|
}
|
|
|
|
override func stopLoading() {
|
|
sessionTask?.cancel()
|
|
}
|
|
}
|
|
|
|
extension MyURLProtocol: URLSessionDataDelegate {
|
|
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
|
|
client?.urlProtocol(self, didLoad: data)
|
|
}
|
|
|
|
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
|
|
let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed
|
|
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy)
|
|
MyURLProtocol.URLProtocolDelegate?.didReceiveResponse(response, from: dataTask.currentRequest)
|
|
completionHandler(.allow)
|
|
}
|
|
|
|
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
|
if let error = error {
|
|
client?.urlProtocol(self, didFailWithError: error)
|
|
} else {
|
|
client?.urlProtocolDidFinishLoading(self)
|
|
}
|
|
}
|
|
|
|
func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
|
|
client?.urlProtocol(self, wasRedirectedTo: request, redirectResponse: response)
|
|
completionHandler(request)
|
|
}
|
|
|
|
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
|
|
guard let error = error else { return }
|
|
client?.urlProtocol(self, didFailWithError: error)
|
|
}
|
|
|
|
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
|
let protectionSpace = challenge.protectionSpace
|
|
let sender = challenge.sender
|
|
|
|
if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
|
|
if let serverTrust = protectionSpace.serverTrust {
|
|
let credential = URLCredential(trust: serverTrust)
|
|
sender?.use(credential, for: challenge)
|
|
completionHandler(.useCredential, credential)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
|
|
client?.urlProtocolDidFinishLoading(self)
|
|
}
|
|
}
|
|
|
|
protocol MyURLProtocolDelegate {
|
|
func didReceiveResponse(_ response: URLResponse, from request: URLRequest?)
|
|
}
|