objective-casp.net-web-apinsurlsessionnsmutableurlrequestnsurlsessionconfiguration

NSMutableURLRequest sending 2 times while using NSURLSession


I am using NSMutableURLRequest is working correct when I am using

- (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))completionHandler {
    NSURLRequest* request = [self createPostRequest];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:completionHandler];
}
-(NSURLRequest*)createPostRequest {
        NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
             [request setHTTPMethod:@"POST"];
             [request setHTTPBody:[self encodeParamsForUpload]];
             return request;  
}

But the issue is when my app is in background mode it won't work.

Here is my HttpRequest class method:

+(id)requestWithRelativePath:(NSString*)docpath {
    return [[HttpRequest alloc] initWithRelativePath:docpath server:server username:email password:password];
}  
-(id)initWithRelativePath:(NSString*)docpath server:(NSString*)server username:(NSString*)username password:(NSString*)password {
    if (self = [super init]) {
        docpath = [docpath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
        _request = [self createRequestWithDocPath:docpath server:server username:username password:password];
    }
    return self;
}

- (NSMutableURLRequest*)createRequestWithDocPath:(NSString*)docpath server:(NSString*)server username:(NSString*)username password:(NSString*)password {
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@%@", server, docpath]];
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setTimeoutInterval:120.0];
    if ((username != nil) && (password != nil)){
        NSString *authStr = [NSString stringWithFormat:@"%@:%@", username, password];
        NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
        NSString *authValue = [NSString stringWithFormat:@"Basic %@", [self base64Encoding:authData]];
        [request setValue:authValue forHTTPHeaderField:@"Authorization"];
    }
    return request;
}

From, stack overflow I found NSURLSession to work API calls in background. So I used NSURLSession. Here is my updated code which I did:

- (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))completionHandler {
    NSURLRequest* request = [self createPostRequest];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:completionHandler];
}
-(NSURLRequest*)createPostRequest {
    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];

    NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[self encodeParamsForUpload]];
    //Create task
    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        //Handle your response here
        [[NSURLSession sharedSession]invalidateAndCancel];
    }];

    [dataTask resume];
    return request; 
}

But, when I am using NSURLSession the request is sending two times I already put the breakpoints in NSMutableURLRequestline but it call only once.

Please, help me to solve the issue.


Solution

  • Your createPostRequest is creating a request and submitting it via NSURLSession. But it also returns the NSURLRequest and postAsynchronousOnQueue proceeds to submit it again, this time through the deprecated NSURLConnection.

    Remove the NSURLConnection code and just rely upon NSURLSession to issue the request.


    For example:

    - (void)postAsynchronousOnQueue:(NSOperationQueue*)queue completionHandler:(void (^)(NSData *, NSURLResponse*, NSError*))completionHandler {
        NSURLSession *defaultSession = [NSURLSession sharedSession];
    
        NSMutableURLRequest* request = [[HttpRequest requestWithRelativePath:@"/photo"] toNSMutableURLRequest];
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:[self encodeParamsForUpload]];
    
        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            //Handle your response here
            [queue addOperationWithBlock:^{
                completionHandler(data, response, error);
            }];
        }];
    
        [dataTask resume]; 
    }