iosswiftrest

Error copying matching creds -- Swift (REST API call)


I'm trying to make an REST API call to a universal devices hub to turn a switch on. It seems like the call is going through, however I am getting an error that says I need credentials, which makes sense because there are credentials needed to get into the interface. However I am not sure how to make this work.

My code is the following:

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBOutlet weak var lightOn: UIButton!
@IBAction func lightOn(_ sender: Any) {
    
    guard let url = URL(string: "http://0.0.0.0/rest/nodes/ZW002_1/cmd/DFON") else { return }
    
    let userCredential = URLCredential(user: "admin",
                                       password: "admin",
                                       persistence: .permanent)
    
    URLCredentialStorage.shared.setDefaultCredential(userCredential, for: protectionSpace)
    
    // create URL session ~ defaulted to GET
    
    let session = URLSession.shared
    
    session.dataTask(with: url) { (data, response, error) in
        
        // optional chaining to make sure value is inside returnables and not not
        
        if let response = response {
            print(response)
        }
        
        if let data = data {
            
            // assuming the data coming back is Json -> transform bytes into readable json data
            
            do {
                
                let json = try JSONSerialization.jsonObject(with: data, options: [])
                
                print(json)
                
            }   catch {
                
                print("error")
            }
        }
        
        }.resume() // if this is not called this block of code isnt executed
    
}

}

I tried piecing together a couple examples online, and the ones I have seen use protectionSpace but when I use it the code returns:

Use of unresolved identifier 'protectionSpace'

Also overall whenever I actually run the simulator I get this exact error:

2017-12-26 13:28:58.656122-0600 hohmtest[6922:1000481] CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
atyp = http;
class = inet;
"m_Limit" = "m_LimitAll";
ptcl = http;
"r_Attributes" = 1;
sdmn = "/";
srvr = "192.168.1.73";
sync = syna;
}
<NSHTTPURLResponse: 0x60400042a3e0> 
{ URL:         
http://192.168.1.73/rest/nodes/ZW002_1/cmd/DON/ } { Status Code: 401, 
Headers {
"Cache-Control" =     (
    "max-age=3600, must-revalidate"
);
Connection =     (
    "Keep-Alive"
);
"Content-Length" =     (
    0
);
"Content-Type" =     (
    "text/html; charset=UTF-8"
);
EXT =     (
    "UCoS, UPnP/1.0, UDI/1.0"
);
"Last-Modified" =     (
    "Tue, 26 Dec 2017 11:26:15 GMT"
);
"Www-Authenticate" =     (
    "Basic realm=\"/\""
);
} }
error

Solution

  • This solution worked for me. This is how I called a REST API that required a username and password. For those wondering, I put this code inside my IBAction button and didn't have to do anything else other than making the button.

    let username = "admin"
    let password = "admin"
    let loginData = String(format: "%@:%@", username, password).data(using: String.Encoding.utf8)!
    let base64LoginData = loginData.base64EncodedString()
    
    // create the request
    let url = URL(string: "http:/rest/nodes/ZW002_1/cmd/DFON")!
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")
    
    //making the request
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("\(error)")
            return
        }
    
        if let httpStatus = response as? HTTPURLResponse {
            // check status code returned by the http server
            print("status code = \(httpStatus.statusCode)")
            // process result
        }
    }
    task.resume()
    

    ********* EXTRA NOTE *************

    If yours does not have a username and password and you are trying to call a REST API call in swift here is some code that can help you! BOTH ARE GET REQUESTS!

    @IBAction func onGetTapped(_ sender: Any) {
    
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { return }
    
        // create URL session ~ defaulted to GET
    
        let session = URLSession.shared
    
        session.dataTask(with: url) { (data, response, error) in
    
            // optional chaining to make sure value is inside returnables and not not
    
            if let response = response {
                print(response)
            }
    
            if let data = data {
    
                // assuming the data coming back is Json -> transform bytes into readable json data
    
                do {
    
                    let json = try JSONSerialization.jsonObject(with: data, options: [])
    
                    print(json)
    
                }   catch {
    
                    print("error")
                }
            }
    
            }.resume() // if this is not called this block of code isnt executed
    
    }