AFNetworking - 下载文件,意外消息格式'Raw'

时间:2013-10-17 19:46:48

标签: ios objective-c afnetworking nsurlrequest

我基本上是在尝试下载一个可以从PDF到PNG的文件。我正在使用AFNetworking 1.x。

然而,我收到一个错误:

NSURL *baseURL = [NSURL URLWithString:@"https://myserver.com/webservices/Services/"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
//NSLog(@"Formatted URL: %@", formattedURL);
//NSMutableURLRequest *photoRequest = [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[httpClient defaultValueForHeader:@"Accept"];
[httpClient setParameterEncoding:AFFormURLParameterEncoding];

[parameters setObject:[NSNumber numberWithInteger:@"10772"] forKey:@"FileId"];
[parameters setObject:[NSNumber numberWithBool:YES] forKey:@"requireUnCompression"];
NSMutableURLRequest *fileRequest = [httpClient requestWithMethod:@"POST" path:@"FileService.svc/DownloadFile" parameters:parameters];
//[fileRequest setHTTPBody:<#(NSData *)#>]
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:fileRequest];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Successss!");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Failed: %@", [operation error]);
}];

[httpClient enqueueHTTPRequestOperation:operation];

然而,我收到一个错误:

Failed: Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 400" UserInfo=0x12112770 {NSLocalizedRecoverySuggestion={"faultType":"InvalidOperationException","message":"The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details."}, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest: 0xc865c40> { URL: https://myserver.com/webservice/Services/FileService.svc/DownloadFile }, NSErrorFailingURLKey=https://myserver.com/webservices/Services/FileService.svc/DownloadFile, NSLocalizedDescription=Expected status code in (200-299), got 400, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xc8696a0> { URL: https://myserver.com/webservices/Services/FileService.svc/DownloadFile } { status code: 400, headers { "Cache-Control" = private; "Content-Length" = 327; "Content-Type" = "application/xml; charset=utf-8"; Date = "Thu, 17 Oct 2013 19:45:07 GMT"; "Persistent-Auth" = true; Server = "Microsoft-IIS/8.0"; "X-AspNet-Version" = "4.0.30319"; "X-Powered-By" = "ASP.NET"; } }}

提前谢谢!

1 个答案:

答案 0 :(得分:1)

我在没有AFNetworking的情况下在我的应用程序中下载PDF /图像/ WordDocs,我也遇到了问题,所以我决定只是好旧的NSURLConnection。我的NSURLRequest不使用POST数据,但我在这里为POST数据修改了NSURLRequest。

文件下载完成后,我会展示一个QLPreviewController来显示它。 (这可以处理显示PDF,图像或文字文档。如果你想看到它还需要更多的代码)

在.h中声明4个属性:

@property (strong, nonatomic) NSNumber *reportLength;
@property (strong, nonatomic) NSURLConnection *reportConnection;
@property (strong, nonatomic) NSMutableData *reportData;
@property (strong, nonatomic) NSString *reportURL;

还将NSURLConnectionDelegate添加到您的代理列表

然后在.m:

- (void)downloadReport:(NSString *)reqUID
{
    NSString *file = [NSString stringWithFormat:@"%@GetReport.ashx?requestUID=%@&deviceUID=%@&token=%@", _globals.baseURL, reqUID, [MySingleton getDeviceID], _globals.token];
    NSURL *fileURL = [NSURL URLWithString:file];

    NSMutableURLRequest *req = [NSURLRequest requestWithURL:fileURL];
    [req setHTTPMethod:@"POST"];
    NSString *postString = @"FileID=10772&requireUnCompression=1";
    [req setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

    _reportConnection = [NSURLConnection connectionWithRequest:req delegate:self];
    _reportData = [NSMutableData data];
    [_reportConnection start];

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [_reportData setLength:0];
    NSLog(@"didReceiveResponse %@: %@", [response URL], [(NSHTTPURLResponse*)response allHeaderFields]);
    _reportLength = [NSNumber numberWithLongLong:[response expectedContentLength]];

    if(_reportLength.longLongValue == 0)
    {
        [_reportConnection cancel];

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty Report" message:@"The report you requested is empty. " delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil, nil];
        [alert show];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[_reportData length]];
    [_reportData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSString *msg = [NSString stringWithFormat:@"Error"];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"There was an issue downloading the attachment. Please try again." message:msg delegate:self cancelButtonTitle:@"Not Now" otherButtonTitles: @"Yes", nil];
    [alert show];
}

//when finished save in documents directory
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,    NSUserDomainMask, YES);
    _reportURL = [NSString stringWithFormat:@"%@/%@", [dirArray objectAtIndex:0], [NSString stringWithFormat:@"%@.pdf", _currentRequestUID]];

    NSError *err;
    if ([_reportData writeToFile:_reportURL options:NSAtomicWrite error:&err] == NO) {
        NSLog(@"writeToFile error: %@", _reportURL);

        NSString *msg = [NSString stringWithFormat:@"There was an issue saving the attachment. Please try again."];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert show];
    }
    else //pdf downloaded, display using QLPreviewController
    {        
        NSLog(@"Written: _reportURL: %@", _reportURL);
        QLPreviewController *previewController=[[QLPreviewController alloc]init];
        previewController.delegate=self;
        previewController.dataSource=self;
        UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(btnCloseQLTouch:)];
        [previewController.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects:btn, nil]];
        [self presentViewController:previewController animated:YES completion:nil];
    }
}

编辑

要让QLPreviewController首先工作,请将<QuickLook.framework>添加到您的项目中,然后在.h中添加这些deletages:

QLPreviewControllerDataSource, QLPreviewControllerDelegate

以下是显示文件所需的数据源/委托方法:

//quicklook datasource/ delegate

- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
    return 1;
}

- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
    return [NSURL fileURLWithPath:_reportURL];
}