title: Send POST request using NSURLSession
body: <p><strong>Update:</strong> Solution found. You can read it at the end of the post.</p>
  
  <p>I'm trying to perform a POST request to a remote REST API using <code>NSURLSession</code>. The idea is to make a request with two parameters: <code>deviceId</code> and <code>textContent</code>.</p>
  
  <p>The problem is that those parameters are not recognized by the server. The server part works correctly because I've sent a POST using POSTMAN for Google Chrome and it worked perfectly.</p>
  
  <p>This is the code I'm using right now:</p>
  
  <pre><code>NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
  NSString *textContent = @"New note";
  NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&amp;textContent=%@", deviceID, textContent];
  
  NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
  sessionConfiguration.HTTPAdditionalHeaders = @{
                                                 @"api-key"       : @"API_KEY",
                                                 @"Content-Type"  : @"application/json"
                                                 };
  NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
  NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
  request.HTTPMethod = @"POST";
  NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
      // The server answers with an error because it doesn't receive the params
  }];
  [postDataTask resume];
  </code></pre>
  
  <p>I've tried the same procedure with a <code>NSURLSessionUploadTask</code>:</p>
  
  <pre><code>// ...
  NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPMethod = @"POST";
  NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[noteDataString dataUsingEncoding:NSUTF8StringEncoding] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
      // The server answers with an error because it doesn't receive the params
  }];
  [uploadTask resume];
  </code></pre>
  
  <p>Any ideas?</p>
  
  <h2>Solution</h2>
  
  <p>The problem with my approach was that I was sending the incorrect <code>Content-Type</code> header with all my requests. So the only change needed for the code to work correctly is to remove the <code>Content-Type = application/json</code> HTTP header. So the correct code would be this:</p>
  
  <pre><code>NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
  NSString *textContent = @"New note";
  NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&amp;textContent=%@", deviceID, textContent];
  
  NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
  sessionConfiguration.HTTPAdditionalHeaders = @{
                                                 @"api-key"       : @"API_KEY"
                                                 };
  NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
  NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
  request.HTTPMethod = @"POST";
  NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
      // The server answers with an error because it doesn't receive the params
  }];
  [postDataTask resume];
  </code></pre>
  
  <h2>Sending images along with other parameters</h2>
  
  <p>If you need to post images along with other parameters using <code>NSURLSession</code> here you have an example:</p>
  
  <pre><code>NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
  NSString *textContent = @"This is a new note";
  
  // Build the request body
  NSString *boundary = @"SportuondoFormBoundary";
  NSMutableData *body = [NSMutableData data];
  // Body part for "deviceId" parameter. This is a string.
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"deviceId"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"%@\r\n", deviceID] dataUsingEncoding:NSUTF8StringEncoding]];
  // Body part for "textContent" parameter. This is a string.
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"textContent"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"%@\r\n", textContent] dataUsingEncoding:NSUTF8StringEncoding]];
  // Body part for the attachament. This is an image.
  NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"ranking"], 0.6);
  if (imageData) {
      [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:imageData];
      [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
  }
  [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  
  // Setup the session
  NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
  sessionConfiguration.HTTPAdditionalHeaders = @{
                                                 @"api-key"       : @"55e76dc4bbae25b066cb",
                                                 @"Accept"        : @"application/json",
                                                 @"Content-Type"  : [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]
                                                 };
  
  // Create the session
  // We can use the delegate to track upload progress
  NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
  
  // Data uploading task. We could use NSURLSessionUploadTask instead of NSURLSessionDataTask if we needed to support uploads in the background
  NSURL *url = [NSURL URLWithString:@"URL_TO_UPLOAD_TO"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  request.HTTPMethod = @"POST";
  request.HTTPBody = body;
  NSURLSessionDataTask *uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
      // Process the response
  }];
  [uploadTask resume];
  </code></pre>