iOS NSURLSessionUploadTask响应数据

时间:2014-07-17 11:26:17

标签: ios ios7 nsurlsession nsurlsessionconfiguration nsurlsessionuploadtask

我已经成功实现了NSURLSessionUploadTask并在后台和前台工作。但是在阅读响应数据时会出现问题。

- (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);
    }
}

这些是上述两个NSLog的输出

  

1 DATA:   {"成功":真,"数据":[{"的uuid":" 8BE7DF37-9DA1-44D2-B48C-D012F699A9B1",& #34; ID":266626},{"的uuid":" 3406D865-1A41-4FC6-BA0B-0638F17757CC"" ID":266656}] "错误":[],"的entityName":" LeadProfile"}   结束数据

     

在最后数据:   {"成功":真,"数据":[{"的uuid":" 8BE7DF37-9DA1-44D2-B48C-D012F699A9B1",& #34; ID":266626},{"的uuid":" 3406D865-1A41-4FC6-BA0B-0638F17757CC"" ID":266656}] "错误":[],"的entityName":" LeadProfile"} {"成功":真,"数据&#34 ;:[{"的uuid":" 8BE7DF37-9DA1-44D2-B48C-D012F699A9B1"" ID":266626},{"的uuid&#34 ;:" 3406D865-1A41-4FC6-BA0B-0638F17757CC"" ID":266656}],"错误":[],"的entityName&# 34;:" LeadProfile"}   结束数据

我想知道为什么这会给我一个上传任务的两个不同的响应。每个位置的self.responseData如何不同?

有人认为这是因为Apple网站上提到的原因吗? (因为NSData对象通常由许多不同的数据对象拼凑在一起,只要有可能,使用NSData的enumerateByteRangesUsingBlock:方法迭代数据而不是使用bytes方法(将NSData对象展平为单个内存块){{ 3}}

4 个答案:

答案 0 :(得分:1)

您仅在部分中收到的数据。您的委托方法应该连接每个数据对象的内容,以使用NSMutableData对象为URL加载构建完整数据。

答案 1 :(得分:1)

你问:

  

我想知道为什么这会给我一个上传任务的两个不同的响应。每个位置的self.responseData如何不同?

毫无疑问,因为responseData没有在适当的时候正确地实例化。 (我倾向于在didReceiveResponse中执行此操作。)注意,您不是在responseData中查看didReceiveData。你在看data。我建议在responseData附加data之后立即检查didReceiveData,我相信你也会看到它加倍。问题是为什么没有正确实例化/初始化。

  

有人认为这是因为Apple网站上提到的原因吗?

     
    

“因为NSData对象通常由许多不同的数据对象拼凑在一起,所以尽可能使用NSData的{​​{1}}方法迭代数据而不是使用bytes方法(将enumerateByteRangesUsingBlock:对象展平为单个内存块)。“

  

不,这是一个完全不相关的问题。我相信这里的问题更加平凡。

不幸的是,我们这里没有足够的代码来诊断确切的问题。

答案 2 :(得分:0)

我找到了解决这个问题的方法。但这可能不是一个正确的答案。

- (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]]);

}

答案 3 :(得分:0)

documentation says类似,收到的数据可能不连续。

所以,这可能是一个可能的实现:

- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data
{
    if (!self.responseData)
    {
        NSUInteger capacity = 0;
        if (dataTask.response.expectedContentLength != NSURLResponseUnknownLength)
        {
            capacity = (NSUInteger)dataTask.response.expectedContentLength;
        }

        self.responseData = [[NSMutableData alloc] initWithCapacity:capacity];
    }

    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        [self.responseData appendBytes:bytes length:byteRange.length];
    }];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error的实施是正确的。