1

我已经成功实现了 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 数据:{"成功":true,"数据":[{"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"}{"success":true,"data":[{"uuid":"8BE7DF37 -9DA1-44D2-B48C-D012F699A9B1","id":266626},{"uuid":"3406D865-1A41-4FC6-BA0B-0638F17757CC","id":266656}],"errors":[]," entityName":"LeadProfile"} 结束数据

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

有人认为这是因为苹果网站上提到的原因吗?(因为 NSData 对象通常是由许多不同的数据对象拼凑而成的,所以尽可能使用 NSData 的 enumerateByteRangesUsingBlock: 方法来遍历数据而不是使用 bytes 方法(它将 NSData 对象扁平化为单个内存块)开发人员。苹果网

4

4 回答 4

2

You ask:

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

It's undoubtedly because responseData was not instantiated properly or at the right time. (I tend to do it in didReceiveResponse.) Note, you're not looking at responseData in your didReceiveData. You're looking at data. I'd suggest checking responseData immediate after appending the data in didReceiveData, and I'm sure you'll see it doubled there, too. The question is why is it not correctly instantiated/initialized.

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)."

No, this is a completely unrelated issue. I'm sure the issue at play here is far more mundane.

Unfortunately, we don't have enough code here to diagnose the precise problem.

于 2014-08-02T03:39:33.847 回答
1

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

于 2014-07-17T16:50:19.350 回答
1

就像文档说的那样,接收到的数据可能是不连续的。

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

- (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是正确的。

于 2015-06-29T08:48:21.553 回答
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]]);

}
于 2014-07-18T10:02:18.607 回答