Swift 3: UrlProtocol didCompleteWithError delegate never be called

1k views Asked by At

As title, I'm trying to build a custom url protocol. I found this and I followed the code provided completely.

However, this delegate

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)

is never be triggered or called.

Furthermore, compiler prompted a warning message said that it nearly matches the optionals requirement of URLSessionTaskDelegate, quick fix provided by compiler was to make it private.

So, How do I call the didCompleteWithError delegate, is the code provided in here missing out some parts? Or this is a known issue? Please let me know if there is any workaround solution or a better Swift 3 example of custom UrlProtocol. Thanks in advance!、

Edit 1:

class CustomURLProtocol: URLProtocol, URLSessionDataDelegate, URLSessionTaskDelegate {
private var dataTask: URLSessionDataTask?
private var urlResponse: URLResponse?
private var receivedData: NSMutableData?

class var CustomHeaderSet: String {
    return "CustomHeaderSet"
}

// MARK: NSURLProtocol

override class func canInit(with request: URLRequest) -> Bool {

    if (URLProtocol.property(forKey: CustomURLProtocol.CustomHeaderSet, in: request as URLRequest) != nil) {
        return false
    }

    return true
}

override class func canonicalRequest(for request: URLRequest) -> URLRequest {
    return request
}

override func startLoading() {

    let mutableRequest =  NSMutableURLRequest.init(url: self.request.url!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 240.0)//self.request as! NSMutableURLRequest

    //Add User Agent

    var userAgentValueString = "myApp"
    mutableRequest.setValue(userAgentValueString, forHTTPHeaderField: "User-Agent")

    print(mutableRequest.allHTTPHeaderFields ?? "")
    URLProtocol.setProperty("true", forKey: CustomURLProtocol.CustomHeaderSet, in: mutableRequest)
    let defaultConfigObj = URLSessionConfiguration.default
    let defaultSession = URLSession(configuration: defaultConfigObj, delegate: self, delegateQueue: nil)
    self.dataTask = defaultSession.dataTask(with: mutableRequest as URLRequest)
    self.dataTask!.resume()
    print("loaded")
}

override func stopLoading() {
    self.dataTask?.cancel()
    self.dataTask       = nil
    self.receivedData   = nil
    self.urlResponse    = nil
}

// MARK: NSURLSessionDataDelegate

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask,
                didReceive response: URLResponse,
                completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {

    self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)

    self.urlResponse = response
    self.receivedData = NSMutableData()

    completionHandler(.allow)
}

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    self.client?.urlProtocol(self, didLoad: data as Data)

    self.receivedData?.append(data as Data)
}

// MARK: NSURLSessionTaskDelegate

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

    print("completed")
    if error != nil { //&& error.code != NSURLErrorCancelled {
        self.client?.urlProtocol(self, didFailWithError: error! as! Swift.Error)
    } else {
        //saveCachedResponse()
        self.client?.urlProtocolDidFinishLoading(self)
    }
}

}

As the code posted there, those are the changes I made, the 'loaded' was called but 'completed' is never be called.

Edit 2:

Warning message prompted by compiler nearly matches optionals requirement of URLSessionTaskDelegate

0

There are 0 answers