title: How To Make Authenticated HTTPS Post In Swift?
body: <p>In an iPhone app, I'd like to collect JSON output from an authenticated HTTPS post of image data. That is, something equivalent to:</p>
  
  <pre><code>curl -u "username":"password" \
       -X POST \
       -F "file=@image.png" \
       "https://server.com/blah?param=value"
  </code></pre>
  
  <p>This command is verified to work with the real URL and not this dummy one given for the sake of asking a question. The server expects basic authentication.</p>
  
  <p>Following the "Uploading MultipartFormData" example in the <a href="https://github.com/Alamofire/Alamofire" rel="nofollow noreferrer">Alamofire readme</a> and <a href="https://stackoverflow.com/questions/34375376/how-to-upload-multipartformdata-with-authentication-using-alamofire">this stackoverflow example</a>, my first attempt uses Alamofire like so:</p>
  
  <pre><code>// 'username' and 'password' are string literals. 'img' is a valid UIImage.
  let url =  NSURL("https://server.com/blah?param=value")
  let dat = UIImagePNGRepresentation(img)
  let credentialData = "\(username):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
  let base64Credentials = credentialData.base64EncodedStringWithOptions([])
  let headers = ["Authorization": "Basic \(base64Credentials)"]
  Alamofire.upload(
          Alamofire.Method.POST,
          url!,
          headers: headers,
          multipartFormData: { multipartFormData in
              multipartFormData.appendBodyPart(data:dat!, name:"file")
          },
          encodingCompletion: { encodingResult in
              switch encodingResult {
  
              case .Success(let upload, _, _):
                  upload.responseString { response in
                      //JSON = response.result.value! as String
                      debugPrint(response)
                  }
              case .Failure(let encodingError):
                  print(encodingError)
              }
          })
  </code></pre>
  
  <p>Again, this code snippet uses the dummy url but I run the code with the real url. This leads to an SSL error:</p>
  
  <pre><code>2015-12-31 05:28:34.733 AutoAlbum[13518:249313] _BSMachError: (os/kern) invalid capability (20)
  2015-12-31 05:28:34.733 AutoAlbum[13518:249682] _BSMachError: (os/kern) invalid name (15)
  2015-12-31 05:28:35.413 AutoAlbum[13518:249708] CFNetwork SSLHandshake failed (-9824)
  2015-12-31 05:28:35.415 AutoAlbum[13518:249708] NSURLSession/NSURLConnection  HTTP load failed (kCFStreamErrorDomainSSL, -9824)
  [Request]: &lt;NSMutableURLRequest: 0x7fdeda835040&gt; { URL: https://server.com/blah?param=value }
  [Response]: nil
  [Data]: 0 bytes
  [Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fdeda84bd90 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://server.com/blah?param=value, NSErrorFailingURLStringKey=https://server.com/blah?param=value, _kCFStreamErrorDomainKey=3}
  </code></pre>
  
  <p>This error happens on xcode's iPhone 5s simulator, when there is a network connection.</p>
  
  <p>My second approach is:</p>
  
  <pre><code>let PasswordString = "username:password"
  let PasswordData = PasswordString.dataUsingEncoding(NSUTF8StringEncoding)
  let base64EncodedCredential = PasswordData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
  let urlPath: String = "https://server.com/blah?param=value"
  let url: NSURL = NSURL(string: urlPath)!
  var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
  request.setValue("Basic \(base64EncodedCredential)", forHTTPHeaderField: "Authorization")
  request.HTTPMethod = "POST"
  let config = NSURLSessionConfiguration.defaultSessionConfiguration()
  let authString = "Basic \(base64EncodedCredential)"
  config.HTTPAdditionalHeaders = ["Authorization" : authString]
  let session = NSURLSession(configuration: config)
  let img:UIImage = getAsset(asset, size: PHImageManagerMaximumSize)
  let dat = String(UIImagePNGRepresentation(img))
  let qstr = "file=\(dat)"
  request.HTTPBody = qstr.dataUsingEncoding(NSUTF8StringEncoding)
  var dataString = ""
  session.dataTaskWithRequest(request) {
      (let data, let response, let error) in
      if let httpResponse = response as? NSHTTPURLResponse {
          dataString = String(data: data!, encoding: NSUTF8StringEncoding)!
          print(dataString)
      }
      else {
          print(error)
      }
  }.resume()
  </code></pre>
  
  <p>This led to the same ssl error:</p>
  
  <pre><code>AutoAlbum[15614:316266] CFNetwork SSLHandshake failed (-9824)
  2015-12-31 15:47:51.142 AutoAlbum[15614:316266] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
  Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." 
  </code></pre>
  
  <p>Following <a href="https://stackoverflow.com/questions/30720813/cfnetwork-sslhandshake-failed-ios-9">this example</a>, I tried setting the minimum tls version to 1.0 like so:
  <a href="https://i.stack.imgur.com/p9r2K.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/p9r2K.png" alt="enter image description here"></a></p>
  
  <p>but ran into the same errors.</p>
  
  <p>Can anybody spot a problem in my code, or does anybody have a recommendation for how to use iOS technologies to do what that <code>curl</code> command does?</p>