Home > Back-end >  Swift POST to api
Swift POST to api

Time:11-23

I have an odd issue and I am hoping you guys can help me.

The Task: I want to post json to a API rest call.

And I am sure the rest API works - I have copied the json from print() in Swift and tried it in postman, and the works just fine.

When I try to post via Swift i get 400 Bad request. The code:

   func postMobileContacts(serverURL: String, jsonToPost: String){
    
    // Prepare URL
    let url = URL(string: serverURL)
    guard let requestUrl = url else { fatalError() }
    // Prepare URL Request Object
    var request = URLRequest(url: requestUrl)
    request.httpMethod = "POST"
     
    // Set HTTP Request Body
    request.httpBody = Data(jsonToPost.utf8);
    
    
    // Set HTTP Request Header
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Authorization", forHTTPHeaderField: String(data: KeychainHelper.standard.read(service: "access-token", account: "store")!, encoding: .utf8)!)
    // Perform HTTP Request
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            
            // Check for Error
            if let error = error {
                print("Error took place \(error)")
                return
            }
     
            // Convert HTTP Response Data to a String
            if let data = data, let dataString = String(data: data, encoding: .utf8) {
                print("Response data string:\n \(dataString)")
            }
    }
    task.resume()
}

CodePudding user response:

This line is definitely wrong:

request.setValue("Authorization", forHTTPHeaderField: String(data: KeychainHelper.standard.read(service: "access-token", account: "store")!, encoding: .utf8)!)

it should be the other way around.

request.setValue(String(data: KeychainHelper.standard.read(service: "access-token", account: "store")!, encoding: .utf8)!, forHTTPHeaderField: "Authorization")

You mixed up the value with the header name.

CodePudding user response:

Made some edits to your code

Currently the data is not directly sent to the request as said in comments. JSONEncodable can be send to the request after encoding to data.

    func postMobileContacts(serverURL: String, jsonToPost: Encodable) { //<--here
        
        // Prepare URL
        let url = URL(string: serverURL)
        guard let requestUrl = url else { fatalError() }
        
        let data = try! JSONEncoder().encode(jsonToPost) //<-Changed here
        
        // Prepare URL Request Object
        var request = URLRequest(url: requestUrl)
        request.httpMethod = "POST"
         
        // Set HTTP Request Body
        request.httpBody = data;  //<-- and here
   
        
        // Set HTTP Request Header
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Authorization", forHTTPHeaderField: String(data: KeychainHelper.standard.read(service: "access-token", account: "store")!, encoding: .utf8)!)
        // Perform HTTP Request
        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
                
                // Check for Error
                if let error = error {
                    print("Error took place \(error)")
                    return
                }
         
                // Convert HTTP Response Data to a String
                if let data = data, let dataString = String(data: data, encoding: .utf8) {
                    print("Response data string:\n \(dataString)")
                }
        }
        task.resume()
    }
  • Related