使用AFNetworking上传照片时出错
我正在上传一张照片使用AFNetworking,我得到臭名昭着的“请求身体stream枯竭”的错误。
这是我的代码:( _manager
是一个AFHTTPRequestOperationManager
)
NSData *imageData = UIImageJPEGRepresentation(image, 1.0); AFHTTPRequestOperation *operation = [_manager POST:address parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileData:imageData name:@"file" fileName:@"image.jpg" mimeType:@"image/jpeg"]; } success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Success!"); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { NSLog(@"Written: %lld", totalBytesWritten); }];
我的iPhone 5S和iPhone 4都出现了错误,都使用wifi和4G / 3G。 这个问题是一致的,每当上传完成时就会发生。 奇怪的是,它也用于这些手机,但前几天我突然开始出现错误。 另外,我的同事在他的iPhone 5上也没有问题,无论是在WiFi还是4G上,都运行相同的代码。 所有手机都运行iOS 7。
我知道有些人在3G上得到这个错误,而在这种情况下的解决方法是使用throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes delay:(NSTimeInterval)delay
方法。 但是,这在我的情况下没有任何影响,我得到了无线和移动的错误。
我可以使用来自同一networking上的计算机的curl
执行上载。
我终于在这个答案中find了一个解决scheme: https : //stackoverflow.com/a/21304062/569507
然而,我们不是像build议的AFHTTPRequestOperation
,而是简单地在它上面(或实际上在它的实现NSURLConnectionDataDelegate
协议的父类AFURLConnectionOperation
)上创build一个包含connection:needNewBodyStream
方法。 这是所有需要的。 我的代码的其余部分保持不变。
AFURLConnectionOperation + Recover.h
#import "AFURLConnectionOperation.h" @interface AFURLConnectionOperation (Recover) - (NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request; @end
AFURLConnectionOperation + Recover.m
#import "AFURLConnectionOperation+Recover.h" @implementation AFURLConnectionOperation (Recover) - (NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request { if ([request.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { return [request.HTTPBodyStream copy]; } return nil; } @end
NSData * imageData = UIImageJPEGRepresentation(img,1.0); long long testBytes = 0;
for (int i=0; i<[arrImages count];i++) { UIImage *img =[arrImages objectAtIndex:i]; img=[AppManager scaleDownImage:img]; NSData *imageData1 = UIImageJPEGRepresentation(img,1.0); testBytes +=[imageData1 length]+130; } AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer]; NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"%@%@",kBaseURL,kChallengeURL] parameters:aDic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileData:imageData name:kProfileImage fileName:@"myimage.jPEG" mimeType:@"image/jpeg"]; } error:nil]; // // [serializer multipartFormRequestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"%@%@",kBaseURL,kChallengeURL] // parameters:aDic // constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { // [formData appendPartWithFileData:imageData // name:@"attachment" // fileName:@"myimage.jpg" // mimeType:@"image/jpeg"]; // }]; // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created. AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { if ([[responseObject objectForKey:kStatus] intValue]==1) { NSArray *arrImages = [app.dicCreateChallangeDetail objectForKey:kProfileImage]; if ([arrImages count]==1) { [AppManager sharedManager].enCheckCreateService = eCreateWebserviceInStopped; [[NSNotificationCenter defaultCenter]postNotificationName:kNotificationEnableTabBarButton object:nil userInfo:nil]; self.view.userInteractionEnabled = YES; self.navigationItem.leftBarButtonItem.enabled = YES; [self performSelector:@selector(goToHomeScreen) withObject:nil afterDelay:0.0]; } else if ([arrImages count]>1) { [self uploadRestImages:[responseObject objectForKey:kChallengeId]]; } } else { [AppManager sharedManager].enCheckCreateService = eCreateWebserviceInStopped; self.view.userInteractionEnabled = YES; self.navigationItem.leftBarButtonItem.enabled = YES; [Utils showAlertView:kAlertTitle message:[responseObject objectForKey:kMessage] delegate:nil cancelButtonTitle:kAlertBtnOK otherButtonTitles:nil]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error){ //NSLog(@"Failure %@", error.description); [AppManager sharedManager].enCheckCreateService = eCreateWebserviceInStopped; self.view.userInteractionEnabled = YES; self.navigationItem.leftBarButtonItem.enabled = YES; [Utils showAlertView:kAlertTitle message:@"Failed. Try again" delegate:nil cancelButtonTitle:kAlertBtnOK otherButtonTitles:nil]; [[NSNotificationCenter defaultCenter]postNotificationName:kNotificationEnableTabBarButton object:nil userInfo:nil]; }]; // 4. Set the progress block of the operation. [operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite); NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%lld",totalBytesWritten],@"written",[NSString stringWithFormat:@"%lld",totalBytesExpectedToWrite],@"Totlal",nil]; [[NSNotificationCenter defaultCenter]postNotificationName:kNotificationRefreshHomePage object:dict userInfo:nil]; }]; // 5. Begin! [operation start];