简体   繁体   中英

Swift JSON Parsing Error

I am trying to parse my JSON response coming from rest api but constantly getting an error.

My request sending and JSON parsing code is below and also I added Xcode's error message.

I appreciate any help in advance.

My JSON format:

{
    "error":1,
    "name":"batuhan",
    "mail":"mymail@gmail.com",
    "password":"e10adc3949ba59abbe56e057f20f883e",
    "user_type":"user"
}

My code:

@IBAction func registerButton(_ sender: Any) {

    let name: String = self.name.text!
    let mail: String = self.mail.text!
    let password: String = self.password.text!


    var responseString: String = ""

    let url = URL(string: "http://my_webserver/index.php?process=register")!
    var request = URLRequest(url: url)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let postString = "mail=\(String(describing: mail))&name=\(String(describing: name))&password=\(String(describing: password))&register_type=user"
    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=\(String(describing: 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 = \(String(describing: response))")
        }

        responseString = String(data: data, encoding: .utf8)!

    }


    struct RegisteredUser: Codable {
        let error: String
        let name: String
        let mail: String
        let password: String
        let user_type: String
    }


    let jsonData = responseString.data(using: .utf8)!
    let decoder = JSONDecoder()
    let user_data = try! decoder.decode(RegisteredUser.self, from: jsonData)

    print(user_data.name)
    print(user_data.mail)


    task.resume()
}

The error:

fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}))): file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.65/src/swift/stdlib/public/core/ErrorType.swift, line 181

Your questions covers the problem a bit too much, it is clearly in the JSON decode which you should have isolated. Anyways: here comes the (trivial) answer.

In your JSON-data error is a number and in your class definition it is a String .

So you have two very simple paths to solve your problem, either you should define

error: Int

in your RegisteredUser or you put

"error":"1",

into your JSONdata .

If what you showed in the beginning was returned from your web service you will have to adapt the format of your RegisteredUser to match the JSON-data exactly. Remember: JSONDecoder.decode is very picky, as any good parser should be.

I would generally recommend to catch errors like this and not use try! if you are talking to the web since there are simply too many things that can go wrong. Although I have to admit that in this case error.localizedDescription was not terribly helpful at

The data couldn’t be read because it isn’t in the correct format.

This did however point me in the right direction since it made me read your input more closely.

Update (with code)

I successfully parsed your String in a playground as follows:

import Cocoa
struct RegisteredUser: Codable {
    let error: Int
    let name: String
    let mail: String
    let password: String
    let user_type: String
}

var str = """
{
"error":1,
  "name":"batuhan",
  "mail":"mymail@gmail.com",
  "password":"e10adc3949ba59abbe56e057f20f883e",
  "user_type":"user"
}
"""
let jsonData = str.data(using: .utf8)!
let decoder = JSONDecoder()

do {
    let user_data = try decoder.decode(RegisteredUser.self, from: jsonData)
    print(user_data)
} catch {
    print("error on decode: \(error.localizedDescription)")
}

This prints

RegisteredUser(error: 1, name: "batuhan", mail: "mymail@gmail.com", password: "e10adc3949ba59abbe56e057f20f883e", user_type: "user")

Please post the code that does not work (and what you expect it to do) if you would like us to help you.

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