Search code examples
iosios7nsurlsessionnsurlsessionconfigurationnsurlsessionuploadtask

iOS NSURLSessionUploadTask response data


I have successfully implemented the NSURLSessionUploadTask and work in both background and foreground. But there is an issue when reading the response data.

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{

    NSLog(@"1 DATA:\n%@\nEND DATA\n", [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]);

    [self.responseData appendData:data];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    if (!error) {                        
        NSLog(@"AT THE END DATA:\n%@\nEND DATA\n", [[NSString alloc] initWithData: self.responseData encoding: NSUTF8StringEncoding]);

            [self parsingJSONResponse:self.responseData];

    } else {
        NSLog(@"HTTP uploading error : %@", error);
    }
}

These are the outputs for above two NSLogs

1 DATA: {"success":true,"data":[{"uuid":"8BE7DF37-9DA1-44D2-B48C-D012F699A9B1","id":266626},{"uuid":"3406D865-1A41-4FC6-BA0B-0638F17757CC","id":266656}],"errors":[],"entityName":"LeadProfile"} END DATA

AT THE END DATA: {"success":true,"data":[{"uuid":"8BE7DF37-9DA1-44D2-B48C-D012F699A9B1","id":266626},{"uuid":"3406D865-1A41-4FC6-BA0B-0638F17757CC","id":266656}],"errors":[],"entityName":"LeadProfile"}{"success":true,"data":[{"uuid":"8BE7DF37-9DA1-44D2-B48C-D012F699A9B1","id":266626},{"uuid":"3406D865-1A41-4FC6-BA0B-0638F17757CC","id":266656}],"errors":[],"entityName":"LeadProfile"} END DATA

I wonder why this is giving me two different responses for one upload task. How the self.responseData can be different in each location ?

Is anyone think this is because of the reason mention on Apple website? (Because the NSData object is often pieced together from a number of different data objects, whenever possible, use NSData’s enumerateByteRangesUsingBlock: method to iterate through the data rather than using the bytes method (which flattens the NSData object into a single memory block)developer.apple.com


Solution

  • I have found a way to overcome this. But this might not be a proper answer.

    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    
        //Get Hex string from 'data'. There can be a solution directly add bytes to NSData (using 'enumerateByteRangesUsingBlock') rather than convert to Hex string 
    
        NSMutableString *string = [NSMutableString stringWithCapacity:data.length * 3];
        [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop){
            for (NSUInteger offset = 0; offset < byteRange.length; ++offset) {
                uint8_t byte = ((const uint8_t *)bytes)[byteRange.location + offset];
                if (string.length == 0)
                    [string appendFormat:@"%02X", byte];
                else
                    [string appendFormat:@" %02X", byte];
            }
        }];
    
        //Hex string to NSdata
    
        NSString *command = string;
        command = [command stringByReplacingOccurrencesOfString:@" " withString:@""];
        NSMutableData *commandToSend= [[NSMutableData alloc] init];
        unsigned char whole_byte;
        char byte_chars[3] = {'\0','\0','\0'};
        for (int i = 0; i < ([command length] / 2); i++) {
            byte_chars[0] = [command characterAtIndex:i*2];
            byte_chars[1] = [command characterAtIndex:i*2+1];
            whole_byte = strtol(byte_chars, NULL, 16);
            [commandToSend appendBytes:&whole_byte length:1];
        }
    
        NSLog(@"1 >>>>>>>>>>>>>>>>>>> %@", [NSString stringWithUTF8String:[commandToSend bytes]]);
    
    }