在iOS中parsing图像下载的多部分响应

在我的应用程序中,我从服务器下载图像作为多部分内容。 在我的回复数据中,我得到了2个部分:一个是json内容,另一个是下载的文件。 回应的格式如下。

--poa89012-3212-1232-9201-fdsakjkj921 Content-Type: application/json; charset=utf-8 Content-Disposition: inline; name=info { //json content } --poa89012-3212-1232-9201-fdsakjkj921 Content-Disposition: file; name=file; filename=photo.png Content-Type: application/octet-stream // File data ˘íë77íí77Í¥2008:02:11 11:32:512008:02:1 ------ 

我无法处理这个有2个部分的响应,当我尝试在didReceiveResponse中获取标题时:它给出了内容types为multipart / mixed的整个响应的标题。请向我展示处理此响应的方法通过分裂json内容和文件内容。

我也有http-multipart响应的问题 。 我为NSData写了一个类。 代码如下:

的NSData + MultipartResponses.h

 #import <Foundation/Foundation.h> @interface NSData (MultipartResponses) - (NSArray *)multipartArray; - (NSDictionary *)multipartDictionary; @end 

的NSData + MultipartResponses.m

 #import "NSData+MultipartResponses.h" @implementation NSData (MultipartResponses) static NSMutableDictionary *parseHeaders(const char *headers) { NSMutableDictionary *dict=[NSMutableDictionary dictionary]; int max=strlen(headers); int start=0; int cursor=0; while(cursor<max) { while((headers[cursor]!=':')&&(headers[cursor]!='=')) { cursor++; } NSString *key=[[NSString alloc] initWithBytes:(headers+start) length:(cursor-start) encoding:NSASCIIStringEncoding]; cursor++; while(headers[cursor]==' ') { cursor++; } start=cursor; while(headers[cursor]&&(headers[cursor]!=';')&&((headers[cursor]!=13)||(headers[cursor+1]!=10))) { cursor++; } NSString *value; if((headers[start]=='"')&&(headers[cursor-1]=='"')) { value=[[NSString alloc] initWithBytes:(headers+start+1) length:(cursor-start-2) encoding:NSASCIIStringEncoding]; } else { value=[[NSString alloc] initWithBytes:(headers+start) length:(cursor-start) encoding:NSASCIIStringEncoding]; } [dict setObject:value forKey:key]; if(headers[cursor]==';') { cursor++; } else { cursor+=2; } while(headers[cursor]==' ') { cursor++; } start=cursor; } return dict; } - (NSDictionary *)multipartDictionaryWithBoundary:(NSString *)boundary { NSMutableDictionary *dict=[NSMutableDictionary dictionary]; const char *bytes=(const char *)[self bytes]; const char *pattern=[boundary cStringUsingEncoding:NSUTF8StringEncoding]; int cursor=0; int start=0; int max=[self length]; int keyNo=0; while(cursor<max) { if(bytes[cursor]==pattern[0]) { int i; int patternLength=strlen(pattern); BOOL match=YES; for(i=0; i<patternLength; i++) { if(bytes[cursor+i]!=pattern[i]) { match=NO; break; } } if(match) { if(start!=0) { int startOfHeaders=start+2; int cursor2=startOfHeaders; while((bytes[cursor2]!=(char)0x0d)||(bytes[cursor2+1]!=(char)0x0a)||(bytes[cursor2+2]!=(char)0x0d)||(bytes[cursor2+3]!=(char)0x0a)) { cursor2++; if(cursor2+4==max) { break; } } if(cursor2+4==max) { break; } else { int lengthOfHeaders=cursor2-startOfHeaders; char *headers=(char *)malloc((lengthOfHeaders+1)*sizeof(char)); strncpy(headers, bytes+startOfHeaders, lengthOfHeaders); headers[lengthOfHeaders]=0; NSMutableDictionary *item=parseHeaders(headers); int startOfData=cursor2+4; int lengthOfData=cursor-startOfData-2; if(([item valueForKey:@"Content-Type"]==nil)&&([item valueForKey:@"filename"]==nil)) { NSString *string=[[NSString alloc] initWithBytes:(bytes+startOfData) length:lengthOfData encoding:NSUTF8StringEncoding]; keyNo++; [dict setObject:string forKey:[NSString stringWithFormat:@"%d", keyNo]]; } else { NSData *data=[NSData dataWithBytes:(bytes+startOfData) length:lengthOfData]; [item setObject:data forKey:@"data"]; keyNo++; [dict setObject:item forKey:[NSString stringWithFormat:@"%d", keyNo]]; } } } cursor=cursor+patternLength-1; start=cursor+1; } } cursor++; } return dict; } - (NSArray *)multipartArray { NSDictionary *dict=[self multipartDictionary]; NSArray *keys=[[dict allKeys] sortedArrayUsingSelector:@selector(localizedStandardCompare:)]; NSMutableArray *array=[NSMutableArray array]; for(NSString *key in keys) { [array addObject:dict[key]]; } return array; } - (NSDictionary *)multipartDictionary { const char *bytes=(const char *)[self bytes]; int cursor=0; int max=[self length]; while(cursor<max) { if(bytes[cursor]==0x0d) { break; } else { cursor++; } } char *pattern=(char *)malloc((cursor+1)*sizeof(char)); strncpy(pattern, bytes, cursor); pattern[cursor]=0x00; NSString *boundary=[[NSString alloc] initWithCString:pattern encoding:NSUTF8StringEncoding]; free(pattern); return [self multipartDictionaryWithBoundary:boundary]; } @end 

对我而言,你的代码不起作用。 相反,我重写了纯粹的Objective-C中的代码:请注意,代码中的(我的)边界总是具有附加的 – 在下一个边界和最终边界之前 – 被剥离。 一个NSArray返回一个NSDictionary为每个部分,包含作为NSDictionary的关键字“头”和NSData的“身体”

 - (NSArray *)multipartArrayWithBoundary:(NSString *)boundary { NSString *data = [[[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding] autorelease]; NSArray *multiparts = [data componentsSeparatedByString:[@"--" stringByAppendingString:boundary]]; // remove boundaries multiparts = [multiparts subarrayWithRange:NSMakeRange(1, [multiparts count]-2)]; // continued removing of boundaries NSMutableArray *toReturn = [NSMutableArray arrayWithCapacity:2]; for(NSString *part in multiparts) { part = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSArray *separated = [part componentsSeparatedByString:@"\n\n"]; NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithCapacity:3]; for(NSString *headerLine in [[separated objectAtIndex:0] componentsSeparatedByString:@"\n"]) { NSArray *keyVal = [headerLine componentsSeparatedByString:@":"]; [headers setObject:[[keyVal objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] forKey:[[keyVal objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; } [toReturn addObject:[NSDictionary dictionaryWithObjectsAndKeys:[[separated objectAtIndex:1] dataUsingEncoding:NSUTF8StringEncoding], @"body", headers, @"headers", nil]]; } return toReturn; }