通常在项目中上传的图片如果内容不大,数量不多就直接转化成NSData 或者NSString 的形式作为参数提交给后台,然而当需要上传的图片数量很大,则需要专门的方法进行处理了:采用数据流的概念方法就是一个很好的途径,方法如下:
//**开始队列并发上传文件流 图片有N个的情况
-(void)beginFiles:(NSMutableArray *)dataArr fileNameS:(NSArray *)nameArr source:(NSString *)source success:(file_SuccessBlock)success fail:(file_FailBlock)fail{
if(!self.totalResultArr)
self.totalResultArr = [NSMutableArray arrayWithCapacity:0];
else
[self.totalResultArr removeAllObjects];
_mySuccessBlock = success;//**记录下
_myFailBlock = fail;
if(!dataArr||![dataArr count]){
NSLog(@"dataArr is empty.........");
return;
}
if([nameArr count]!=[dataArr count]){
NSLog(@"nameArr count not the same to dataArr count");
return;
}
if(EMPTY_NIL_STR(source)){
NSLog(@"miss source .......");
return;
}
self.subThreadCount = [dataArr count];
//**建立上传队列
self.myQueue = [[NSOperationQueue alloc]init];
[self.myQueue setMaxConcurrentOperationCount:-1];//**-1并发数量无限制
NSLog(@"dataArr count::%tu",[dataArr count]);
NSInteger i = 0;
for(NSData *eachData in dataArr){
NSString *name = [nameArr objectAtIndex:i];
i++;
NSBlockOperation *eachOperation =[NSBlockOperation blockOperationWithBlock:^(void){
//**建立长连接
[self httpKeepAliveConnectionFileName:name source:source data:eachData];
}];
[self.myQueue addOperation:eachOperation];
}
}
/*********************以下是HTTP 长连接操作********************************/
-(void)httpKeepAliveConnectionFileName:(NSString *)fileName source:(NSString *)source data:(NSData *)data{
//NSLog(@"图片名称::%@---二进制流:::%@",fileName,data);
NSString *finalUrlS = [self returnUrlString:fileName source:source];
NSInputStream *eachInStream = [NSInputStream inputStreamWithData:data];
eachInStream.delegate = self;
[eachInStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
MY_Request *request = [MY_Request requestWithURL:[NSURL URLWithString:finalUrlS]];
[request setHTTPMethod:@"POST"];
//[request setValue: @"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"];//**content设置成流类型
request.requestName = fileName;//**标记每个请求
//**setHTTPBodyStream: 和 setHTTPBody: 互斥 不可同时设置
//[request setHTTPBodyStream:eachInStream];//**ios8中本方法传递图片数据出现错乱,丢失现象。
[request setHTTPBody:data];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
while (self.needRun) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[connection setDelegateQueue:self.myQueue];
[connection start];
//**这里输入流不能打开
//[self.inputStream open];
}
//**拼接图片上传地址
-(NSString *)returnUrlString:(NSString *)fileName source:(NSString *)source{
if(EMPTY_NIL_STR(fileName)||EMPTY_NIL_STR(source)){
NSLog(@"miss param please check it out ......");
return nil;
}
NSString *passwordFlag = [[SharedInstance sharedInstance] userToken];
if(EMPTY_NIL_STR(passwordFlag))
passwordFlag = [[NSUserDefaults standardUserDefaults]objectForKey:@"userToken"];
NSMutableString *paramString = [NSMutableString stringWithCapacity:0];
[paramString appendString:File_Upload_Server];
[paramString appendString:@"?"];
[paramString appendFormat:@"userId=%@",[SharedInstance sharedInstance].userId];
[paramString appendString:@"&"];
[paramString appendFormat:@"userToken=%@",passwordFlag];
[paramString appendString:@"&"];
[paramString appendFormat:@"fileName=%@",fileName];
[paramString appendString:@"&"];
[paramString appendFormat:@"busiSource=%@",source];
paramString = [NSMutableString stringWithString:[paramString urlEnconding]];
// NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingMacChineseSimp);
//NSData *textdata = [paramString dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion: YES];
return paramString;
}
//**以下是网络连接代理接口
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"connection response:::%@",response);
}
static NSMutableData *totalData = nil;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if(!totalData)
totalData = [NSMutableData dataWithCapacity:0];
[totalData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite{
NSLog(@"图片总长度::%tu--已上传长度::%tu---正在上传:%tu",totalBytesExpectedToWrite,totalBytesWritten,bytesWritten);
NSLog(@"connection send data.....");
}
//**connection 代理
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response{
NSURLRequest *newRequest = request;
if (response) {
NSLog(@"redirect!!!"); //如,请求google的网站时会有跳转发生
newRequest = nil; //拒绝跳转
}
return newRequest;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
MY_Request *currentR =(MY_Request *)connection.currentRequest;
NSString *currentBlockName = currentR.requestName;
NSLog(@"当前完成的请求是::%@",currentBlockName);
self.subThreadCount--;
NSString *finalS = [[NSString alloc]initWithData:totalData encoding:NSUTF8StringEncoding];
NSLog(@"connection finish finalS::%@",finalS);
[totalData setData:nil];//**清空
NSMutableDictionary *resultDic = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary *)[finalS JSONValue]];
[resultDic setObject:currentBlockName?currentBlockName:@"" forKey:@"fileName"];//**把当前上传成功的文件名称和FileId关联到一块
NSString *code = Value(resultDic, @"code");
NSString *errorMessage = Value(resultDic, @"message");
NSLog(@"operationCount:::%tu",self.subThreadCount);
if([code isEqualToString:@"200"])
[self.totalResultArr addObject:resultDic];
//**最后一个
if([code isEqualToString:@"200"]&&!self.subThreadCount&&!self.existFail){
if(!self.alreadyCallBack){
_mySuccessBlock(resultDic,YES,self.totalResultArr);
self.alreadyCallBack = YES;
}
self.needRun = NO;
}
//**若存在线程提交失败
else if(![code isEqualToString:@"200"]){
if(!self.alreadyCallBack){
_mySuccessBlock(errorMessage,NO,nil);
self.alreadyCallBack = YES;
}
self.existFail = YES;
self.needRun = NO;
[self.myQueue cancelAllOperations];
}
}
//**属于网络请求失败
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"connection error:::%@",error);
self.subThreadCount--;
self.existFail = YES;
self.needRun = NO;
if(!self.alreadyCallBack){
self.alreadyCallBack = YES;
_myFailBlock(error,NO);
}
[self.myQueue cancelAllOperations];
}