roland
roland

Reputation: 950

Why doesn't NSURLConnection's currentRequest indicate the correct URL after redirection?

By my reading of the docs for NSURLConnection, the currentRequest method should reflect any redirection that may have occurred while loading:

As the connection performs the load, the request may change as a result of protocol canonicalization or due to following redirects. This method is be used to retrieve the current value.

However, when I inspect the currentRequest in connectionDidFinishLoading: it always has the URL of the original request, even though examining the response data shows that the redirection completed successfully. (see contrived example below)

My question is this: why doesn't currentRequest return the actual current request? Am I doing something wrong or is this expected behavior? If this is the expected behavior then what is currentRequest supposed to be useful for?

@interface AppDelegate : UIResponder <UIApplicationDelegate, NSURLConnectionDataDelegate>
@property (strong, nonatomic) NSURLConnection *connection;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSURL *url = [[NSURL alloc] initWithString:@"http://jigsaw.w3.org/HTTP/300/301.html"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    return YES;
}

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
    NSLog(@"willSendRequest // request: %@ // currentRequest: %@", request, [connection currentRequest]);
    return request;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"didFinishLoading // originalRequest: %@ // currentRequest: %@", [connection originalRequest], [connection currentRequest]);
}

@end

Running this example gives me the following output:

2012-12-18 15:18:44.949 ConnectionTest[12534:c07] willSendRequest // request: <NSURLRequest http://jigsaw.w3.org/HTTP/300/301.html> // currentRequest: <NSURLRequest http://jigsaw.w3.org/HTTP/300/301.html>
2012-12-18 15:18:44.954 ConnectionTest[12534:c07] willSendRequest // request: <NSURLRequest http://jigsaw.w3.org/HTTP/300/Overview.html> // currentRequest: <NSURLRequest http://jigsaw.w3.org/HTTP/300/301.html>
2012-12-18 15:18:44.955 ConnectionTest[12534:c07] didFinishLoading // originalRequest: <NSURLRequest http://jigsaw.w3.org/HTTP/300/301.html> // currentRequest: <NSURLRequest http://jigsaw.w3.org/HTTP/300/301.html>

My expectation is that the last call to currentRequest would show the page URL ending in Overview.html, but instead it still shows 301.html.

Upvotes: 4

Views: 1163

Answers (3)

roland
roland

Reputation: 950

I'm just going to chalk this one up to Apple having to confusing documentation. I can get the final request URL by examining the response object, but to me something called currentRequest should reflect the last request made after there's been a redirection.

Upvotes: 3

Cocoanetics
Cocoanetics

Reputation: 8247

How does the redirection occur? Is the http server returning a redirect status?

The original URL request is probably not a mutable one and because of this the system cannot modify the URL.

You would have to make a new request for each redirection as explained by the answer here: Handling redirects correctly with NSURLConnection

You get the final URL not from the connection, but from the response object. See for example this URL unshortener I made: http://www.cocoanetics.com/2012/06/mine-is-longer-than-yours/

Upvotes: 2

Bertrand Caron
Bertrand Caron

Reputation: 2657

I'm no Iphone Developper (just Mac), but it seems like most NSURLConnectionDelegate methods have been deprecated in iOS5, and NSURLDownload (and its delegate) seems to be the new way to do this : NSURLConnectionDelegate NSURLDownloadDelegate

Upvotes: 0

Related Questions