Search code examples
iosnsmutableurlrequest

cancel NSURLConnection in ios


I am calling webservice on mapView drag/regionChange. I want to keep some delay in the web service calls. So I want that whenever the user drags the map multiple times, all previous web service calls should be cancelled and only last drag web service call should be fired.

How do I do this?

Following is my code:

{ .... NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];

        NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[data length]];

        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:data];

        [request setHTTPMethod:@"POST"];
        NSMutableDictionary __block *dictResponse;
    [[NSOperationQueue mainQueue] cancelAllOperations];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

            if(connectionError == nil){

                dictResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];
                }

Solution

  • You cannot cancel a sendAsynchronousRequest. If you used a delegate-based NSURLConnection request, then you could cancel it, but (a) that's more coding than you probably want to bother with; (b) NSURLConnection is deprecated, so you should be NSURLSession anyway; and (c) NSURLSession allows you to cancel the task using the NSURLSessionTask reference that is returned to you:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setHTTPBody:data];
    [request setHTTPMethod:@"POST"];
    
    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"connection error = %@", error);
            return;
        }
        NSError *parseError;
        NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
        if (!responseObject) {
            NSLog(@"parse error = %@", parseError);
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // use response here; e.g., updating UI or model objects
        });
    }];
    [task resume];
    

    If you need to cancel this request, just call [task cancel]. So save this NSURLSessionTask in some weak variable if you want to keep track of it and cancel it later.