¿Cómo envío un file adjunto de correo electrónico de foto en iOS usando la request POST a SendGrid?

Estoy usando NSMutableURLRequest para enviar datos POST a un script PHP del server que envía correos electrónicos usando SendGrid. Esto funciona muy bien. Sin embargo, no tengo idea de cómo empaquetar UIImagedata correctamente para enviar como file adjunto. Aquí está mi código actual:

// Choose an image from your photo library - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { chosenImage = info[UIImagePickerControllerEditedImage]; // chosenImage = UIImage pickedData = UIImagePNGRepresentation(chosenImage); // pickedData = NSData attachment = TRUE; [picker dismissViewControllerAnimated:YES completion:NULL]; } -(void)sendMail { toEmailAddress = @"blabla@blabla.com"; subject = @"Some Subject"; message = @"Some message..."; fullName = @"Mister Bla Bla"; if (attachment == TRUE) { // Create NSData object as PNG image data from camera image NSString *picAttachment = [NSString stringWithFormat:@"%lu",(unsigned long)[pickedData length]]; NSString *picName = @"Photo"; post = [NSString stringWithFormat:@"&toEmailAddress=%@&subject=%@&message=%@&fullName=%@&picAttachment=%@&picName=%@", toEmailAddress, subject, message, fullName, picAttachment, picName]; } else { post = [NSString stringWithFormat:@"&toEmailAddress=%@&subject=%@&message=%@&fullName=%@", toEmailAddress, subject, message, fullName]; } NSData * postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO]; NSString * postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]]; NSMutableURLRequest * request = [[[NSMutableURLRequest alloc] init] autorelease]; [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.someURL.com/sendgrid.php"]]]; [request setHTTPMethod:@"POST"]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; // send the POST request, and read the reply by creating a new NSURLSession: NSURLSession *conn = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; [[conn dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; NSLog(@"requestReply: %@", requestReply); // Return response from PHP script on server. }] resume]; } 

Si investiga esta pregunta, puede encontrar que existe una versión de envío de iOS SendGrid. Desafortunadamente, esta no es la respuesta. La gente de SendGrid me dice que no use la biblioteca debido a un problema de security.

Nueva respuesta:

Para cargar el file como adjunto de correo electrónico directamente a SendGrid, debe utilizar Web API v3 y crear una request como se describe en los documentos .

En primer lugar, debe agregar el encabezado de authentication a su request. En segundo lugar, necesita convertir sus datos al formatting JSON. Si estamos hablando de files, debe codificar los datos de file con Base64, tal como se describe en la sección de parameters del cuerpo :

 JSON PARAMETER: attachements/content TYPE: string REQUIRED: Yes The Base64 encoded content of the attachment. 

Además, eche un vistazo a los parameters de disposition y content_id : lo ayudarán a configurar la apariencia de su file en el correo.

Antigua respuesta:

La forma estándar de cargar ambos parameters y files está utilizando la request POST con posts multiparte . He cambiado el código para crear datos de este formatting:

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage* image = info[UIImagePickerControllerEditedImage]; NSDictionary* params = @{ @"toEmailAddress" : @"blabla@blabla.com", @"subject" : @"Some Subject", @"message" : @"Some message...", @"fullName" : @"Mister Bla Bla", }; [picker dismissViewControllerAnimated:YES completion:^{ [self sendMailWithParams:params image:image]; }]; } static NSStringEncoding const kEncoding = NSUTF8StringEncoding; - (void)sendMailWithParams:(NSDictionary*)params image:(UIImage*)image { NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; request.URL = [NSURL URLWithString:@"http://www.someURL.com/sendgrid.php"]; request.HTTPMethod = @"POST"; NSString *boundary = [NSUUID UUID].UUIDString; // define POST request as multipart NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; // prepare boundary NSString *middleBoundary = [NSString stringWithFormat:@"--%@\r\n", boundary]; NSData *middleBoundaryData = [middleBoundary dataUsingEncoding:kEncoding]; NSMutableData* body = [NSMutableData data]; // append params [params enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSString* value, BOOL* stop) { [body appendData:middleBoundaryData]; NSData* fieldData = [self dataForKey:key value:value]; [body appendData:fieldData]; }]; // append image if (image) { [body appendData:middleBoundaryData]; NSData* imageData = [self dataForImage:image imageName:@"photo.png"]; [body appendData:imageData]; } // add last boundary NSString* lastBoundary = [NSString stringWithFormat:@"--%@--\r\n", boundary]; NSData* lastBoundaryData = [lastBoundary dataUsingEncoding:kEncoding]; [body appendData:lastBoundaryData]; // set body to request request.HTTPBody = body; // add length of body NSString *length = [NSString stringWithFormat:@"%llu", (uint64_t)body.length]; [request setValue:length forHTTPHeaderField:@"Content-Length"]; // send request NSURLSession* session = [NSURLSession shanetworkingSession]; NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // handle as you want }]; [task resume]; } - (NSData*)dataForImage:(UIImage*)image imageName:(NSString*)imageName { NSString* fieldDescription = [NSString stringWithFormat: @"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n" @"Content-Type: image/png\r\n\r\n", imageName]; NSMutableData *data = [NSMutableData data]; [data appendData:[fieldDescription dataUsingEncoding:kEncoding]]; NSData* imageData = UIImagePNGRepresentation(image); [data appendData:imageData]; NSString* newLine = @"\r\n"; NSData* newLineData = [newLine dataUsingEncoding:kEncoding]; [data appendData:newLineData]; return data; } - (NSData*)dataForKey:(NSString*)key value:(NSString*)value { NSString* fieldDescription = [NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n" @"%@\r\n", key, value]; return [fieldDescription dataUsingEncoding:kEncoding]; } 

Puede usar las variables $ _POST y $ _FILES para get acceso a los datos cargados en su script PHP. Si desea get más información acerca de los posts multiparte, consulte los documentos aquí .