1

I am having difficulties parsing data (JSON-like I get from endpoint) to Swift structs. As it seems data I get from the endpoint is not a valid JSON (at least not all of it looking at the structure of object = (...)), so I can't decode ListStruct.

Should I parse it another way? Any advice much appreciated

Structs I prepared are:

struct Response:Codable {
    let message:String?
    let list:ListStruct?
    let error:Bool?
}

struct ListStruct:Codable {
    let object1:[Object1]?
    let object2:[Object2]?
    let object3:[Object3]?
}

struct Object1:Codable {
id:Int?
name:String?
}
...

Example of data I get from endpoint:

["message": <null>, "list": {
    object1 =     (
                {
            id = 1;
            name = "testing1";
        }
    );
    object2 =     (
                {
            files =             (
            );
            id = 1;
            name = "testing2-1";
            photos =             (
            );
        },
                {
            files =             (
            );
            id = 2;
            name = "testing2-2";
            photos =             (
            );
            systemId = 8;
        }
    );
    object3 =     (
                {
            id = 6;
            name = "testing3-1";
        },
                {

            id = 13;
            name = "testing3-2";
        }
    );
}, "error": 0]

EDIT

How I am trying do decode:

if let result = try JSONDecoder().decode(Response?.self, from: "\(response!)".data(using: .utf8)! ) {
                        print("\(result)")
                    }

Error I am getting:

Error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 6." UserInfo={NSDebugDescription=No string key for value in object around character 6.})))
10
  • 1
    Paste your json code here. Commented Apr 1, 2019 at 10:34
  • 1
    This is how JSON looks on Xcode console, there is no problem with that. Tell us the error you are getting while decoding it. Use the above link by @dahiya_boy to generate your model classes. Commented Apr 1, 2019 at 10:38
  • 3
    The output is neither JSON nor a collection type description. It's something out of both. Commented Apr 1, 2019 at 10:40
  • 1
    "Example of data I get from endpoint:": Where did you print that? If it was really JSON, seems to that is has already been parsed through JSONSerialization, and mixing Swift Dictionary, and "Objective-C" NSArray & NSDictionary. What is response exactly? Could you show the lines where you get it? I'd say that the method you use is already parsing it. Commented Apr 1, 2019 at 10:49
  • 1
    The cause of the error is most likely the nonsensical String Interpolation "\(response!)" which of course does not produce valid JSON. Where does response come from? Commented Apr 1, 2019 at 10:50

1 Answer 1

2

Most probably, you are passing the wrong data object by creating using string interpolation. If the response type is Data then you don't need to recreate it again in the below line,

if let result = try JSONDecoder().decode(Response?.self, from: "\(response!)".data(using: .utf8)! ) {

Try to pass the response as it is. Shown below,

if let result = try JSONDecoder().decode(Response?.self, from: response!) {

Here is a complete testable example where the correct data object is created using the json in question and error type in Response is changed from Optional Bool to Int,

struct Response:Codable {
    let message:String?
    let list:ListStruct?
    let error: Int?
}

struct ListStruct: Codable {
    let object1:[Object1]?
    let object2:[Object2]?
    let object3:[Object3]?
}

struct Object1: Codable {
    var id:Int?
    var name:String?
}

struct Object2: Codable {
    var id:Int?
    var name:String?
    var systemId: Int?
}

struct Object3: Codable {
    var id:Int?
    var name:String?
}

Usage:

let data = """
{"message": null,

"list": {
"object1": [
{
"id": 1,
"name": "testing1"
}
],
"object2" :     [
{
"files" :             [
],
"id" : 1,
"name" : "testing2-1",
"photos" :             [
]
},
{
"files" :            [
],
"id" : 2,
"name" : "testing2-2",
"photos" :             [
],
"systemId" : 8
}
],
"object3" :     [
{
"id" : 6,
"name" : "testing3-1",
},
{

"id" : 13,
"name" : "testing3-2",
}
]
},

"error": 0
}
""".data(using: .utf8)!

if let result = try! JSONDecoder().decode(Response?.self, from: data) {
        result.list?.object1?.forEach({ obj in
            print(obj.name)
        })
        result.list?.object2?.forEach({ obj in
            print(obj.name)
        })
        result.list?.object3?.forEach({ obj in
            print(obj.name)
        })
}

Output:

Optional("testing1")
Optional("testing2-1")
Optional("testing2-2")
Optional("testing3-1")
Optional("testing3-2")
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.