Загрузите изображение с помощью AFNetworking 2.0
Я не могу понять, почему это так сложно. Все учебники и статьи в Интернете, похоже, говорят об 1,0 api, что довольно бесполезно.
Я пробовал несколько разных способов и получал разные результаты. Что я делаю неправильно?
-
задача загрузки - похоже, не используется многочастная форма, 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];
-
сообщение с блоком - это, кажется, не придает ничего
[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);
}];
-
простая запись - кажется, почти работает... но не
[self.manager POST:url
parameters:@{@"post[picture][]":data}
success:^(NSURLSessionDataTask *task, id response) {
NSLog(@"Success");
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"Error: %@", error);
}];
Мне бы очень понравилось работать, но я не уверен, почему это не так.
Ответы
Ответ 1
Для правильно сформированного тела "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);
}];
Ответ 2
То, что описывает Ray Lillywhite, прекрасно работает (я бы сделал комментарий к его сообщению, но моя репутация слишком низкая).
- Получить правильную версию AFNetworking, содержащую это исправление для обновления прогресса при использовании многопользовательских запросов. На момент написания этой версии это HEAD.
- Создайте
NSMutableURLRequest
с помощью multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:
.
- Создайте данные формы с помощью одного из методов
appendPartWith...
.
- Получить (загрузить) задачу данных, вызвав правильный метод
uploadTaskWith...
. Вам нужно использовать uploadTaskWithStreamedRequest:progress:completionHandler:
, если вы хотите использовать входной параметр NSProgress
.