John Hass John Hass - 2 months ago 32
Swift Question

How to return final url to the delegator in swift?

I know how to capture the final url of a redirected url, but I don't know how to return the final url to the delegator.

That is

func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
request.url //send this final url back so that I can call it in another delegate
}


After we obtain the final url, I wanna pass the final url to another delegate function

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

Answer

If I understand our question correctly, you are looking for a way to set up a task based on the request passed back by this delegate function.

The way I have handled this in the past is to initiate a new task with the newRequest object. In my case it was a download task so, in the body of the willPerformHTTPRedirection function:

let newDownloadTask = session.downloadTaskWithRequest(request)
newDownloadTask.resume()

This new task will then initiate and start making delegate callbacks as before.

UPDATE:

Probably the best way to do this is to create a dictionary with active tasks and related URLs. I put the following together in playground - you can add the relevant URL as necessary:

import UIKit
import PlaygroundSupport

let currentPage = PlaygroundPage.current
currentPage.needsIndefiniteExecution = true

class downloader : NSObject, URLSessionDelegate, URLSessionDataDelegate {

    var session : URLSession!
    var tasks : [URLSessionDataTask : String] = [URLSessionDataTask : String]()

    func startDownloadWithDelegateHandler() {
        self.session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)

        let urlString : String = < PUT YOUR URL HERE >

        guard let url = URL(string: urlString) else { return }
        let request : URLRequest = URLRequest(url: url)

        let dataTask : URLSessionDataTask = session.dataTask(with: request)
        self.tasks[dataTask] = urlString

        dataTask.resume()
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        print("Data received")
        print(dataTask.description)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if error != nil {
            print(error)
        }
        else
        {
            print("Finished")
            if let urlString = self.tasks[task as! URLSessionDataTask] {
                print(urlString)
            }
        }
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
        print("Getting redirected")
        print(response)

        let newDataTask = self.session.dataTask(with: request)
        self.tasks[newDataTask] = String(describing: request.url)
        print(newDataTask.taskDescription)
        newDataTask.resume()
    }

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil)
    }

    func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
        if let _ = error {
            print(error!)
        }
    }
}

let myDownloader = downloader()
myDownloader.startDownloadWithDelegateHandler()

I hope you can follow the logic and this clears it up!