Reputation: 210
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":"[email protected]",
"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))®ister_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
Upvotes: 1
Views: 9160
Reputation: 4551
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.
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":"[email protected]",
"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: "[email protected]", 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.
Upvotes: 3