Hi there, i am new to mac os application development. Actually i am trying to decode one json object but getting error " Type Missmatch" i do not know how to create a proper structure for parsing json. I have following codes:-
JSON FROM SERVER:
--------------------------
{
"message": "Student Found",
"student": {
"studentID": "ST000000195",
"name": "RAVI VARMA",
"phone": "7873500016",
"email": "ravi@gmail.com",
"specialisation": "SP002",
"yearOfJoining": "2015",
"keyCode": "1111111111",
"schoolID": "BS00001",
"registrationID": "UNOX001",
"batchID": "BA000000001",
"usingOS": "Windows",
"loginID": "LU000000317",
"course": "CO0000001",
"macID": "0.0.0.0",
"bulkUpload": null,
"createdBy": "LU000000011",
"createdOn": "2018-08-07T12:08:55",
"updatedBy": "LU000000011",
"updatedOn": "2018-08-14T00:00:00",
"address": "KARNOOL, AP",
"gender": "Female",
"status": 1
}
}
Serialization
if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
if(responseJSON.count == 2){
self.parseJSON(data: data!)
My structure
struct StudentLogin: Decodable
{
struct StudentLoginMessage{
public var message:String
}
struct StudentLoginData{
public var studentID:String
public var name:String
public var phone:String
public var email:String
public var specialisation:String
public var yearOfJoining:String
public var keyCode:String
public var schoolID:String
public var registrationID:String
public var batchID:String
public var usingOS:String
public var loginID:String
public var course:String
public var macID:String
public var bulkUpload:String
public var createdBy:String
public var createdOn:Date
public var updatedBy:String
public var updatedOn:Date
public var address:String
public var gender:String
public var status:String
}
}
var studentdata = [StudentLogin]()
I am trying to do like this
func parseJSON(data: Data){
do {
let decoder = JSONDecoder()
self.studentdata = try decoder.decode([StudentLogin].self, from: data)
} catch let error {
print(error as? Any)
}
}
Can anyone suggest me the proper way to parse the json correctly please.
First of all, your JSON FROM SERVER represents a single JSON object, which is outlined as follows:
{
"message": "Student Found",
"student": {
...
}
}
It has two key-value pairs, one "message" with a JSON string, another "student" with a JSON object.
If you want to represent it as a Decodable Swift struct, you need two properties, but your `StudentLogin` has no properties.
You may need something like this:
struct StudentLogin: Decodable {
var message: String
var student: Student
}
With Student defined as:
struct Student: Decodable {
var studentID: String
var name: String
var phone: String
var email: String
var specialisation: String
var yearOfJoining: String
var keyCode: String
var schoolID: String
var registrationID: String
var batchID: String
var usingOS: String
var loginID: String
var course: String
var macID: String
var bulkUpload: String? //<- can be null
var createdBy: String
var createdOn: Date
var updatedBy: String
var updatedOn: Date
var address: String
var gender: String
var status: Int //<- JSON number
}
Better modify your deserializing code like this to clarify what may cause problem:
do {
guard let data = data else {
print("data is nil")
return
}
let responseJSON = try JSONSerialization.jsonObject(with: data)
if let response = responseJSON as? [String: Any], response.count == 2 {
self.parseJSON(data: data)
print(self.studentdata)
} else {
print("response was not a JSON object")
//...
}
} catch {
print(error)
//...
}
The response is not a JSON array, so the result type should not be an Array type like `[StudentLogin]`.
And the date format in you JSON cannot be recognized as `Date` with `JSONDecoder`.
So your `parseJSON` would look like this:
var studentdata: [StudentLogin] = [] //<- I guessed your `studentdata` is an Array of `StudentLogin`
func parseJSON(data: Data) {
do {
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.current //<- You may need to change this
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let studentFound = try decoder.decode(StudentLogin.self, from: data) //<- Not `[StudentLogin].self`
self.studentdata = [studentFound]
} catch let error {
print(error)
}
}
The code above would not work becaused I needed to fill many parts by guess. You should better include all relevant info and error messages.