简体   繁体   中英

Swift4 - Error Domain=NSCocoaErrorDomain Code=4865

func DoLogin(_ email:String, _ password:String)
{

        struct user : Decodable {
            let userid: Int
            let sfname: String
            let slname: String
            let email: String
            let sid: Int
        }


    let url = URL(string: ".....")!
    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!)
        }

       let responseString = String(data: data, encoding: .utf8)
     print(responseString!)
        do {
            let myStruct = try JSONDecoder().decode(user.self, from: data)
            print(myStruct)


        } catch let error as NSError {
            print(error)

        }
    }


    task.resume()
}

So the aim is to save the JSON response into the 'user' class so i can use the variables to insert the data into an sql database. The problem I'm currently getting is the Error message...

"Error Domain=NSCocoaErrorDomain Code=4865 "No value associated with key userid ("userid")." UserInfo={NSCodingPath=( ), NSDebugDescription=No value associated with key userid ("userid").}"

I feel the problem is that the HTTP response is returning the data back in an array form which is then not being able to be decoded (HTTP response listed below which is the responseString which I've been using for testing purposes)

{"user":{"userid":2,"sfname":"John","slname":"Doe","email":"john@doe.com","sid":123456}}

Heres the PHP that is used to return the data.

    public function getUserByEmail($email)
{
    $stmt = $this->conn->prepare("SELECT userid, sfname, slname, email, sid FROM students WHERE email = ?");
    $stmt->bind_param("s", $email);
    $stmt->execute();
    $stmt->bind_result($userid, $sfname, $slname, $email, $sid);
    $stmt->fetch();
    $user = array();
    $user['userid'] = $userid;
    $user['sfname'] = $sfname;
    $user['slname'] = $slname;
    $user['email'] = $email;
    $user['sid'] = $sid;
    return $user;
}

Thanks in advance :D

As you already mention yourself the structure of your JSON doesn't match the structure of your user struct.

You could do two things: Try to figure out why the returned JSON is wrapped in another JSON object or you create a wrapper struct which matches the structure of the received JSON.

The second approach should result in somethin like this:

struct UserWrapper: Decodable {
  let user:user
}

Then when your create your user from the JSON simply to this

let wrapper = try JSONDecoder().decode(UserWrapper.self, from: data)
myStruct = wrapper.user

By the way: I would recommend you to read a Swift style guide. By convention function names should start with lowercases and class/struct names with uppercases. Also named parameters in functions are a very cool thing to document your code.

Something like

func doLogin(userWithMail email: String, andPassword password: String) {...}
// ... other stuff
// call
doLogin(userWithMail: "test@test.com", andPassword: "1234567")

could be more readable. Just in case you have to share your codebase in the future. ;D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM