10

我不明白为什么这这么难。网上所有的教程和文章好像都在讲1.0的api,没什么用。

我尝试了几种不同的方法,得到了不同的结果。我究竟做错了什么?

  1. 上传任务 - 这似乎没有使用多部分表单,wtf?

    NSMutableURLRequest *request = [self.manager.requestSerializer multipartFormRequestWithMethod:@"POST"
                                                                                      URLString:[[NSURL URLWithString:url relativeToURL:[NSURL URLWithString:ApiBaseUrl]] absoluteString]
                                                                                     parameters:@{}
                                                                      constructingBodyWithBlock:nil];
    
    NSProgress *progress;
    NSURLSessionUploadTask *task = [self.manager uploadTaskWithRequest:request
                                                            fromData:data
                                                            progress:&progress
                                                   completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
                                                     if (error) {
                                                       NSLog(@"[error description] = %@", [error description]);
                                                     } else {
                                                       NSLog(@"success!");
                                                     }
                                                   }];
    
    [task resume];
    
  2. 用块发布 - 这似乎没有附加任何东西

    [self.manager POST:url
               parameters:@{}
    constructingBodyWithBlock:^(id <AFMultipartFormData> formData) {
        [formData appendPartWithFileData:data
                                    name:@"post[picture]"
                                fileName:@"picture.jpg"
                                mimeType:@"image/jpeg"];
    }
                  success:^(NSURLSessionDataTask *task, id response) {
                    NSLog(@"Success");
                  }
                  failure:^(NSURLSessionDataTask *task, NSError *error) {
                    NSLog(@"Error: %@", error);
                  }];
    
  3. 简单的帖子 - 这似乎几乎可以工作......但不是

    [self.manager POST:url
            parameters:@{@"post[picture][]":data}
               success:^(NSURLSessionDataTask *task, id response) {
                 NSLog(@"Success");
               }
               failure:^(NSURLSessionDataTask *task, NSError *error) {
                 NSLog(@"Error: %@", error);
               }];
    

我很想 1 工作,但我不知道为什么它不工作。

4

2 回答 2

14

对于正确形成的“multipart/form-data”主体,您需要在创建请求时使用主体构造块。否则上传任务使用原始数据作为主体。例如,在您的 AFHTTPSessionManager 子类中:

NSString *urlString = [[NSURL URLWithString:kPhotoUploadPath relativeToURL:self.baseURL] absoluteString];
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:urlString parameters:params constructingBodyWithBlock:^(id <AFMultipartFormData> formData) {
    [formData appendPartWithFileData:photo.data name:@"photo" fileName:@"photo.jpg" mimeType:@"image/jpeg"];
}];

NSURLSessionUploadTask *task = [self uploadTaskWithStreamedRequest:request progress:progress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
    if (error) {
        if (failure) failure(error);
    } else {
        if (success) success(responseObject);
    }
}];
[task resume];

或者,如果您不需要跟踪上传进度,您可以简单地使用:

[self POST:kPhotoUploadPath parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileData:photo.data name:@"photo" fileName:@"photo.jpg" mimeType:@"image/jpeg"];
} success:^(NSURLSessionDataTask *task, id responseObject) {
    if (success) success(responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    if (failure) failure(error);
}];
于 2013-10-18T17:53:15.943 回答
5

Ray Lillywhite 所描述的效果非常好(我会在他的帖子上发表评论,但我的声誉太低了)。

  1. 获取正确版本的 AFNetworking,其中包含使用多部分请求时更新进度的此修复程序。在撰写本文时,该版本是 HEAD。
  2. NSMutableURLRequest在 的帮助下创建一个multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:
    • 借助其中一种appendPartWith...方法构建表单数据。
  3. 通过调用正确的uploadTaskWith...方法获取(上传)数据任务。如果uploadTaskWithStreamedRequest:progress:completionHandler:要使用NSProgress输入参数,则需要使用。
于 2014-01-10T10:37:37.167 回答