POST multipart / données de formulaire avec Objective-C

Donc, ce code HTML soumet les données dans le format correct pour moi.

Name:
Email:
Password:
Avatar:

J’ai examiné un bon nombre d’articles sur la façon de faire un POST multipart / form-data sur iOS, mais aucun n’explique vraiment ce qu’il faut faire s’il y a des parameters normaux ainsi que le téléchargement du fichier.

Pourriez-vous s’il vous plaît m’aider avec le code pour POST ceci dans Obj-C?

Merci!

Le processus est le suivant:

  1. Créez un dictionnaire avec les userName , userEmail et userPassword .

     NSDictionary *params = @{@"userName" : @"rob", @"userEmail" : @"rob@email.com", @"userPassword" : @"password"}; 
  2. Déterminez le chemin de l’image:

     NSSsortingng *path = [[NSBundle mainBundle] pathForResource:@"avatar" ofType:@"png"]; 
  3. Créez la demande:

     NSSsortingng *boundary = [self generateBoundarySsortingng]; // configure the request NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; [request setHTTPMethod:@"POST"]; // set content type NSSsortingng *contentType = [NSSsortingng ssortingngWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; // create body NSData *httpBody = [self createBodyWithBoundary:boundary parameters:params paths:@[path] fieldName:fieldName]; 
  4. C’est la méthode utilisée ci-dessus pour construire le corps de la requête:

     - (NSData *)createBodyWithBoundary:(NSSsortingng *)boundary parameters:(NSDictionary *)parameters paths:(NSArray *)paths fieldName:(NSSsortingng *)fieldName { NSMutableData *httpBody = [NSMutableData data]; // add params (all params are ssortingngs) [parameters enumerateKeysAndObjectsUsingBlock:^(NSSsortingng *parameterKey, NSSsortingng *parameterValue, BOOL *stop) { [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8SsortingngEncoding]]; }]; // add image data for (NSSsortingng *path in paths) { NSSsortingng *filename = [path lastPathComponent]; NSData *data = [NSData dataWithContentsOfFile:path]; NSSsortingng *mimetype = [self mimeTypeForPath:path]; [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, filename] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [httpBody appendData:data]; [httpBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; } [httpBody appendData:[[NSSsortingng ssortingngWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; return httpBody; } 
  5. Ce qui précède utilise les méthodes utilitaires suivantes:

     @import MobileCoreServices; // only needed in iOS - (NSSsortingng *)mimeTypeForPath:(NSSsortingng *)path { // get a mime type for an extension using MobileCoreServices.framework CFSsortingngRef extension = (__bridge CFSsortingngRef)[path pathExtension]; CFSsortingngRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL); assert(UTI != NULL); NSSsortingng *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType)); assert(mimetype != NULL); CFRelease(UTI); return mimetype; } - (NSSsortingng *)generateBoundarySsortingng { return [NSSsortingng ssortingngWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDSsortingng]]; } 
  6. Ensuite, soumettez la demande. Il y a beaucoup, beaucoup d’options ici.

    Par exemple, si vous utilisez NSURLSession , vous pouvez créer NSURLSessionUploadTask :

     NSURLSession *session = [NSURLSession sharedSession]; // use sharedSession or create your own NSURLSessionTask *task = [session uploadTaskWithRequest:request fromData:httpBody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { NSLog(@"error = %@", error); return; } NSSsortingng *result = [[NSSsortingng alloc] initWithData:data encoding:NSUTF8SsortingngEncoding]; NSLog(@"result = %@", result); }]; [task resume]; 

    Ou vous pouvez créer une NSURLSessionDataTask :

     request.HTTPBody = httpBody; NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { NSLog(@"error = %@", error); return; } NSSsortingng *result = [[NSSsortingng alloc] initWithData:data encoding:NSUTF8SsortingngEncoding]; NSLog(@"result = %@", result); }]; [task resume]; 

    Ce qui précède suppose que le serveur renvoie simplement une réponse textuelle. Il est préférable que le serveur retourne JSON, auquel cas vous utiliseriez NSJSONSerialization plutôt que la méthode NSSsortingng initWithData .

    De même, j’utilise les rendus de blocs d’achèvement de NSURLSession ci-dessus, mais vous NSURLSession utiliser les rendus plus riches basés sur des delegates. Mais cela semble au-delà de la scope de cette question, alors je vous laisse cela.

Mais j’espère que cela illustre l’idée.


Je m’en voudrais de ne pas vous dire que, beaucoup plus facile que ci-dessus, vous pouvez utiliser AFNetworking , en répétant les étapes 1 et 2 ci-dessus, mais en appelant simplement:

 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // only needed if the server is not returning JSON; if web service returns JSON, remove this line NSURLSessionTask *task = [manager POST:urlSsortingng parameters:params constructingBodyWithBlock:^(id formData) { NSError *error; if (![formData appendPartWithFileURL:[NSURL fileURLWithPath:path] name:@"avatar" fileName:[path lastPathComponent] mimeType:@"image/png" error:&error]) { NSLog(@"error appending part: %@", error); } } progress:nil success:^(NSURLSessionTask *task, id responseObject) { NSLog(@"responseObject = %@", responseObject); } failure:^(NSURLSessionTask *task, NSError *error) { NSLog(@"error = %@", error); }]; if (!task) { NSLog(@"Creation of task failed."); } 

Essayez de l’utiliser pour les données vidéo et image avec différents types MIME.

 NSDictionary *param; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 1. Create `AFHTTPRequestSerializer` which will create your request. AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer]; NSMutableURLRequest *request; NSData *fileData; if ([objDoc.url containsSsortingng:@".mp4"]) { manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"application/json"]; [serializer setValue:@"video/mp4" forHTTPHeaderField:@"Content-Type"]; manager.requestSerializer = serializer; } // 2. Create an `NSMutableURLRequest`. NSLog(@"filename =%@",objDoc.url); request= [serializer multipartFormRequestWithMethod:@"POST" URLSsortingng:strUrl parameters:param constructingBodyWithBlock:^(id formData) { if ([objDoc.url containsSsortingng:@".mp4"]) { [formData appendPartWithFileData:fileData name:@"File" fileName:@"video.mp4" mimeType:@"video/mp4"]; }else{ [formData appendPartWithFileData:fileData name:@"File" fileName:@"image.jpeg" mimeType:@"image/jpeg"]; } } error:nil]; // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created. self.objeDocument.isUploading = [NSNumber numberWithInt:1]; self.operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Success %@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error!" message:@"The document attached has failed to upload." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; [self.operation cancel]; NSLog(@"Failure %@", error.description); }]; // 4. Set the progress block of the operation. [self.operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite); float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite; }]; // 5. Begin! [self.operation start]; 

POST plusieurs images à l’aide de plusieurs parties ou de données de formulaire avec Objective-C

 -(void)multipleimageandssortingng { NSSsortingng *urlSsortingng=@"URL NAME"; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ; [request setURL:[NSURL URLWithSsortingng:urlSsortingng]]; [request setHTTPMethod:@"POST"]; NSMutableData *body = [NSMutableData data]; NSSsortingng *boundary = @"---------------------------14737809831466499882746641449"; NSSsortingng *contentType = [NSSsortingng ssortingngWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request addValue:contentType forHTTPHeaderField:@"Content-Type"]; // file float low_bound = 0; float high_bound =5000; float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);//image1 int intRndValue = (int)(rndValue + 0.5); NSSsortingng *str_image1 = [@(intRndValue) ssortingngValue]; UIImage *chosenImage1=[UIImage imageNamed:@"Purchase_GUI_curves-12 copy.png"]; NSData *imageData = UIImageJPEGRepresentation(chosenImage1, 90); [body appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"files\"; filename=\"%@.png\"\r\n",str_image1] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[NSData dataWithData:imageData]]; [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"name\"\r\n\r\n"] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[@"Nilesh" dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"apipassword\"\r\n\r\n"] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithSsortingng:app.password] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithFormat:@"Content-Disposition: form-data; name=\"adminId\"\r\n\r\n"] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[[NSSsortingng ssortingngWithSsortingng:app.adminId] dataUsingEncoding:NSUTF8SsortingngEncoding]]; [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8SsortingngEncoding]]; // close form [body appendData:[[NSSsortingng ssortingngWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8SsortingngEncoding]]; // set request body [request setHTTPBody:body]; //return and test NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSSsortingng *returnSsortingng = [[NSSsortingng alloc] initWithData:returnData encoding:NSUTF8SsortingngEncoding]; NSLog(@"%@", returnSsortingng); } 

J’ai eu du mal avec cela pendant un moment, si vous cherchez à télécharger plusieurs images ou tout autre type de fichier, vous pouvez effectuer les opérations suivantes à l’aide d’ AFNetworking 3.0

 NSDictionary *params = @{key : value, ..... etc }; NSSsortingng *urlSsortingng = @"http://..... your endpoint url"; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // only needed if the server is not returning JSON; NSURLSessionTask *task = [manager POST:urlSsortingng parameters:params constructingBodyWithBlock:^(id formData) { for (int x = 0 ; x< contentArray.count; x++) { AttachmentsModel *model = contentArray[x]; if(model.type == ImageAttachmentType){ [formData appendPartWithFileData:model.data name:model.name fileName:model.fileName mimeType:model.mimeType]; }else if(model.type == AudioAttachmentType){ NSURL *urlVideoFile = [NSURL fileURLWithPath:model.path]; [formData appendPartWithFileURL:urlVideoFile name:model.name fileName:model.fileName mimeType:model.mimeType error:nil]; }else{ [formData appendPartWithFileURL:model.url name:model.name fileName:model.fileName mimeType:model.mimeType error:nil]; } } } progress:nil success:^(NSURLSessionTask *task, id responseObject) { [Utility stopLoading]; NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; NSLog(@"result = %@", result); id json = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; if (block) { //your response comes here } } failure:^(NSURLSessionTask *task, NSError *error) { NSLog(@"error = %@", error); }]; if (!task) { NSLog(@"Creation of task failed."); } 

Et voici à quoi ressemble mon AttachmentsModel:

 // AttachmentsModel.h typedef enum AttachmnetType{ ImageAttachmentType, AudioAttachmentType, VideoAttachmentType } AttachmnetType; @interface AttachmentsModel : NSObject @property (strong, nonatomic) NSSsortingng *path; @property (strong, nonatomic) NSData *data; @property (strong, nonatomic) NSSsortingng *mimeType; @property (strong, nonatomic) NSSsortingng *name; @property (strong, nonatomic) NSSsortingng *fileName; @property (strong, nonatomic) NSURL *url;