Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift4 Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(Data?, URLResponse?, Error?)

func DoLogin(_ email:String, _ password:String)
{
    struct User: Decodable {
        let sfname: String
        let slname: String
        let email: String
        let sid: Int
    }

    let url = URL(string: "http://URL")!
    var request = URLRequest(url: url)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let postString = "email=" + email + "&password=" + password + ""
    request.httpBody = postString.data(using: .utf8)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
            print(error!)
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print(response!)
        }

       if let responseString = String(data: data, encoding: .utf8){
        let myStruct = try JSONDecoder().decode(User.self, from: responseString)
        }
    }

    task.resume()
}

So the aim is to decode the HTTP response responseString in order to save the information into the properties of User, but I keep getting the same error popping up after inserting the line of code in order to decode the HTTP response (myStruct). I feel it has something to do with Do Try Catch error handling but can't manage to figure it out.

Thanks in advance for the help :)

like image 499
Josh Mustafa Avatar asked Feb 09 '18 19:02

Josh Mustafa


1 Answers

Here's your problem:

let myStruct = try JSONDecoder().decode(User.self, from: responseString)

The completion handler of

URLSession.shared.dataTask(with: URLRequest, completionHandler: (Data?, URLResponse?, Error?) -> Void)

does not allow throwing or re-throwing exceptions. If it had, the signature would be something like this instead:

URLSession.shared.dataTask(with: URLRequest, completionHandler: (Data?, URLResponse?, Error?) throws -> Void)

(note the throws in the method signature)

Also, you need to make sure you change responseString to data. The decode method takes a Data object, not a String. Converting data to a String is actually not needed at all, so you can remove this if statement from your code:

if let responseString = String(data: data, encoding: .utf8)

Try doing something like this instead:

do {
    let myStruct = try JSONDecoder().decode(User.self, from: data)
    //do something with myStruct
} catch let error as NSError {
    //do something with error
}

or this:

if let myStruct = try? JSONDecoder().decode(User.self, from: data) {
    //do something with myStruct
} else {
    //handle myStruct being nil
}
like image 85
Jake Avatar answered Sep 30 '22 17:09

Jake