I need to fetch a redirecting URL but prevent redirection in Swift. From other posts and Apple docs I understand I must implement the delegate method URLSession(session:, task:, willPerformHTTPRedirection response:, request:, completionHandler:)
and return nil
via the completion closure. But I can't find examples in swift, nor figure out the right way to do it. The code below reproduces my issue in playground: the delegate does not seem to get executed.
import Foundation
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
class MySession: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate {
// trying to follow instructions at https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionTaskDelegate_protocol/index.html#//apple_ref/occ/intfm/NSURLSessionTaskDelegate/URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:
// to prevent redirection -- DOES NOT SEEM TO GET CALLED
func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest!) -> Void) {
println("in URLSession delegate") // NEVER PRINTS
completionHandler(nil) // NO EFFECT
}
// fetch data from URL with NSURLSession
class func getDataFromServerWithSuccess(myURL: String, success: (response: String!) -> Void) {
var session = NSURLSession.sharedSession()
let loadDataTask = session.dataTaskWithURL(NSURL(string: myURL)!) { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
// OMITTING ERROR CHECKING FOR BREVITY
success(response: NSString(data: data!, encoding: NSASCIIStringEncoding) as String)
}
loadDataTask.resume()
}
// extract data from redirect
class func getRedirectionInfo(url: String) {
getDataFromServerWithSuccess(url) {(data) -> Void in
if let html = data {
if html.rangeOfString("<html><head><title>Object moved</title>", options: .RegularExpressionSearch) != nil {
println("success: redirection was prevented") // SHOULD PRINT THIS
} else {
println("failure: redirection went through") // INSTEAD PRINTS THIS
}
}
}
}
}
MySession.getRedirectionInfo("http://bit.ly/filmenczer") // ex. redirecting link
Please be gentle, I am a newbie. Thank you in advance for any assistance!
UPDATE: With many thanks to @nate I got it to work. The key insight is that in order for the delegate to be called, one must pass the delegate class to the NSURLSession()
initializer, rather than using NSURLSession.sharedSession()
. Passing nil
as the delegate yields the customary behavior (with redirection). Here is working version of the code:
import Foundation
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
class MySession: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate {
// to prevent redirection
func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest!) -> Void) {
completionHandler(nil)
}
// fetch data from URL with NSURLSession
class func getDataFromServerWithSuccess(myURL: String, noRedirect: Bool, success: (response: String!) -> Void) {
var myDelegate: MySession? = nil
if noRedirect {
myDelegate = MySession()
}
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: myDelegate, delegateQueue: nil)
let loadDataTask = session.dataTaskWithURL(NSURL(string: myURL)!) { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
// OMITTING ERROR CHECKING FOR BREVITY
success(response: NSString(data: data!, encoding: NSASCIIStringEncoding) as String)
}
loadDataTask.resume()
}
// extract data from redirect
class func getRedirectionInfo(url: String) {
getDataFromServerWithSuccess(url, noRedirect: true) {(data) -> Void in
if let html = data {
if html.rangeOfString("<html>\n<head><title>Bitly</title>", options: .RegularExpressionSearch) != nil {
println("success: redirection was prevented")
} else {
println("failure: redirection went through")
}
}
}
}
}
MySession.getRedirectionInfo("http://bit.ly/filmenczer")
if(url=="redirected url")
.