我正在使用AFNetworking上传照片,并且我收到臭名昭着的“请求正文流已用尽”错误。
这是我的代码:
(_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
方法。但是,这对我的情况没有任何影响,我在wifi和移动设备上都会出错。
我可以使用位于同一网络的计算机上的curl
执行上传。
答案 0 :(得分:2)
我终于在这个答案中找到了一个解决方案: https://stackoverflow.com/a/21304062/569507
然而,我没有按照建议对AFHTTPRequestOperation
进行子类化,而是简单地在其上创建了一个类别(实际上在其父类AFURLConnectionOperation
上实现了NSURLConnectionDataDelegate
协议),其中包含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
答案 1 :(得分:0)
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];