我已经成功实现了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}}
答案 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
的实施是正确的。