Swift 3 - How To Call Rest Service w/ Basic HTTP Authentication

I'm building a new IOS 10 application and I need to call a rest service which uses classic HTTP basic authentication (prompts for username/password when using a brower). The only code I've found online uses Swift 2 but I'm using Swift 3. Could someone please finish the code <at line 14>?


        let username = "username"
        let password = "password"
        let loginString = String(format: "%@:%@", username, password)
        let loginData = loginString.data(using: String.Encoding.utf8)!
        let base64LoginString = loginData.base64EncodedString()
     
        let url = URL(string: "http://192.168.1.2/rest")
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
     
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
       **** WHAT GOES HERE ****?????


The code compiles okay but what do I call on the URLSession object to call the rest service and fetch the data (which is XML)?


Thanks!

I was in the same boat as you and I searched forever and put a few posts together to make the following. I built this based on calling into a WebAPI I made and it worked great so hopefully it works for whatever you're calling into. I updated it with your information...


        let bodyStr = "username=username&password=password&grant_type=password"
     
        let myURL = NSURL(string: "http://192.168.1.2/rest"
        let request = NSMutableURLRequest(url: myURL as URL)
        request.httpMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.httpBody = bodyStr.data(using: String.Encoding.utf8)!
     
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            (data, response, error) -> Void in
            if let unwrappedData = data {
             
                do {
                    let tokenDictionary:NSDictionary = try JSONSerialization.jsonObject(with: unwrappedData, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
                 
                    let token = tokenDictionary["access_token"] as? String
                }
                catch {
                    self.emailTextField.text = ""
                    self.passwordTextField.text = ""
                 
                    let alertView = UIAlertController(title: "Login failed",
                                                      message: "Wrong username or password." as String, preferredStyle:.alert)
                    let okAction = UIAlertAction(title: "Try Again!", style: .default, handler: nil)
                    alertView.addAction(okAction)
                    self.present(alertView, animated: true, completion: nil)
                    return
                }
            }
        }
        task.resume()


In line 17 above, your token should be in the token variable. You can then store it (I found a lot of examples for KeychainWrapper, etc., to store it) and use it later to access "values," etc. from the WebAPI (or at least, that's what I was using it for).


Hope this helps!

I know its been some time since this question was asked but im having trouble with this example. The error I keep getting is

Error: [Assert] Cannot be called with asCopy = NO on non-main thread.

Error: UI api called on a background thread: -[UITextField setText:] PID: 7515, TID:193240. Thread name: (none), Queue name: NSOperationQueue 0x7fd83457b600 (QOS: UNSPECIFIED), Qos: 0


But I've added

catch {

DispatchQueue.main.async { // Correct

self.Email.text = ""

self.Pw.text = ""

}


And its still not working. Any suggestions?

Swift 3 - How To Call Rest Service w/ Basic HTTP Authentication
 
 
Q