使用AFNetworking上传照片时出错

时间:2014-07-20 16:54:19

标签: ios cocoa-touch afnetworking multipartform-data afnetworking-2

我正在使用AFNetworking上传照片,并且我收到臭名昭着的“请求正文流已用尽”错误。

这是我的代码: (_managerAFHTTPRequestOperationManager

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执行上传。

2 个答案:

答案 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];