2013-10-09 5 views
10

Я не понимаю, почему это так сложно. Все учебники и статьи в Интернете, похоже, говорят об 1,0 api, что довольно бесполезно.Загрузить изображение с AFNetworking 2.0

Я пробовал несколько разных способов и получил разные результаты. Что я делаю не так?

  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, но я не уверен, почему это не так.

+0

Когда вы используете «NSURLSessionUploadTask» на шаге 1, откуда вы получаете данные? Я делаю что-то подобное (хотя и не многостраничное POST), сначала создавая запрос, а затем используя данные 'request.HTTPBody' как данные. –

+0

У вас была возможность решить эту проблему .. У меня такая же проблема .. Мне нужно отправить параметры со снимком тоже .. попробовал все три возможных способа .. вы упоминаете ... но никто не работает ... нет образца предоставленный afnetworking слишком ... – Rakesh

+0

Вы разрешили это. У меня есть аналогичный вопрос, можете ли вы мне помочь http://stackoverflow.com/questions/22180367/afnetworking-2-2-0-upload-image-on-server-issues –

ответ

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); 
}]; 
+0

Я боюсь, что первый ответ неверен, так как ' uploadTaskWithStreamedRequest: 'для * потоковых * запросов, то есть через постоянное URL-соединение. – jpsim

+0

Я не думаю, что это то, что «потоковое» означает в этом контексте.Вероятно, это просто ссылается на то, что это запрос с несколькими частями: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 Я понимаю, что тело запроса передано потоком , но соединение не является постоянным и закрывается после завершения запроса. Это стандартный тип запроса для загрузки файлов. 'uploadTaskWithStreamedRequest:' также используется средствами AFNetworkings '... constructingBodyWithBlock: ...'. –

+0

@RayLillywhite, но когда я проверяю свои фото.данные, это ничто, вы можете посмотреть в моем аналогичном вопросе http://stackoverflow.com/questions/22180367/afnetworking-2-2-0-upload-image-on-server- вопросы –

5

Что Рэй Lillywhite описывает отлично работает (я бы я сделал комментарий к его сообщению, но моя репутация слишком низкая).

  1. Получить правильную версию AFNetworking, содержащую this fix for updating progress when using multipart requests. На момент написания этой версии это HEAD.
  2. Создайте NSMutableURLRequest с помощью multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:.
    • Создайте свои данные формы с помощью одного из методов appendPartWith....
  3. Получить (загрузить) задачу данных, позвонив по правому методу uploadTaskWith.... НУЖНО использовать uploadTaskWithStreamedRequest:progress:completionHandler:, если вы хотите использовать входной параметр NSProgress.
Смежные вопросы