如何在 AFNetworking 2 中使用 POST + 参数下载经过身份验证的文件?

Posted

技术标签:

【中文标题】如何在 AFNetworking 2 中使用 POST + 参数下载经过身份验证的文件?【英文标题】:How download a authenticated file with a POST + params in AFNetworking 2? 【发布时间】:2014-01-13 22:45:49 【问题描述】:

我需要下载经过身份验证的文件。我在 python 端有这个:

@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def downloadData(request):
    schema = request.user.company.username
    db = dbSync(schema)

    filePath = db.dbPath()

    tables = [(db.getTable('location'), 0)]

    if db.copyTables(filePath, tables):
        wrapper = FileWrapper(file(filePath))
        response = HttpResponse(wrapper, content_type='application/x-sqlite3')
        response['Content-Length'] = os.path.getsize(filePath)
        response['Content-Disposition'] = 'attachment; filename="tables.db"'
        response['Content-Transfer-Encoding'] = 'binary'
    else:
        response = HttpResponseNotModified()

    return response

使用 python 请求库/浏览器时可以正常工作。

然后我在 ios 中有这个:

[self.session POST:@"sync/tables/" parameters:tables
           success:^(NSURLSessionDataTask *task, id responseObject) 
               DDLogInfo(@"%@", responseObject);
               handler(nil);
           
           failure:^(NSURLSessionDataTask *task, NSError *error) 
               DDLogCError(@"%@",error);

              handler(error);
           ];

请求通过,但是responseObject是nil

所以我尝试:

NSURL *URL = [NSURL URLWithString:@"http://localhost:8000/sync/tables/"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];

    [request setValue:self.token forHTTPHeaderField:@"AUTHORIZATION"];
    [request setHTTPMethod:@"POST"];

    NSMutableString *params = [NSMutableString string];

    [tables enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) 
        [params appendFormat:@"%@=%@", key, obj];
    ];

    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) 

        NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"temp.db"];

        return [NSURL fileURLWithPath:path];
     completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) 
        DDLogInfo(@"File downloaded to: %@", filePath);

        if (error) 
            DDLogError(@"%@", error);
        
        handler(error);
    ];
    [downloadTask resume];

这是很多重复。所以:

1) 是否可以使用 NSURLSessionDownloadTask 并能够像 self.session POST 一样发送参数?

2) 或self.session POST 并获取文件?

【问题讨论】:

您可能会发现this question 的答案很有帮助。 【参考方案1】:

AFHTTPSessionManager 公开一个 requestSerializer 属性,默认情况下是一个 AFHTTPRequestSerializer 实例。

AFHTTPRequestSerializer 反过来提供-requestWithMethod:URLString:parameters:error:

-requestWithMethod:URLString:parameters:error: 返回一个NSMutableURLRequest,您可以将其提供给NSURLSession-downloadTaskWithRequest: 或变体。

希望这能满足您的需求。

【讨论】:

以上是关于如何在 AFNetworking 2 中使用 POST + 参数下载经过身份验证的文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AFNetworking 2 中执行 AFHTTPRequestOperation

如何使用 AFNetworking 2.0 下载文件

如何在 AFNetworking 2 中使用 POST + 参数下载经过身份验证的文件?

AFNetworking 2.0 中的 AFHTTPRequestOperationManager 如何传递 HTTPBody 标签

如何在上传带参数的图像时使用 AFNetworking 2.0 设置 cookie?

如何使用 AFNetworking 2.0 处理 Parse.com Rest API 错误