Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Decodable parse part of JSON

Tags:

I'm trying to parse a json that looks like this using decodable:

    {
    "count": 1,
    "results": [
        {
            "title": 1,
            "content": "Bla"
        } ]
    }

My problem is that I don't want to make a class that has a count property just to be able to use the decoder. I want to parse only the results part I don't care about the count.

So my question is, can decodable.decode somehow only parse a part of the result json. I mean a certain key path instead of the whole json ? And I want to do it using Decodable.

In a nutshell I don't want this:

class IncidentWrapper: Codable{
    var count: Int
    var incident: [Incident]
}

What I would Imagine is to have this:

decodable.decode([Incident].self, from: response.data, forKey: "results")

Thanks

like image 231
Mostafa Mohamed Raafat Avatar asked Apr 13 '20 22:04

Mostafa Mohamed Raafat


People also ask

How do you parse JSON in Swift?

To parse JSON very easily into usable instances of Struct or Class that we create in Swift we use Codable protocol. So how it works? Basically we map JSON objects into Structs or Classes that we create in Swift and for each of these classes, it is going to represent different JSON object.

What is the difference between Codable and Decodable in Swift?

Understanding what Swift's Codable isWhen you only want to convert JSON data into a struct, you can conform your object to Decodable . If you only want to transform instances of your struct into Data , you can conform your object to Encodable , and if you want to do both you can conform to Codable .


1 Answers

let me see what I can suggest:

struct Result: Codeable {
   var id: Int
   var message: String
   var color: String
   var type: String

   enum CodingKeys: String, CodingKey {
      case results
   }

   enum NestedResultKeys: String, CodingKey {
      case id, message, color, type
   }
}

extension Result: Decodable {
   init(from decoder: Decoder) throws {
      let result = try decoder.container(keyedBy: CodingKeys.self)

      let nestedResult = try result.nestedContainer(keyedBy: NestedResultKeys.self, forKey: .result)
      id = try nestedResult.decode(Int.self, forKey: .id)
      message = try nestedResult.decode(String.self, forKey: .message)
      color = try nestedResult.decode(String.self, forKey: .color)
      type = try nestedResult.decode(String.self, forKey: .id)
   }
}

See this documentation for more insight

https://developer.apple.com/documentation/swift/swift_standard_library/encoding_decoding_and_serialization

Hope it helps your project!

like image 109
Mvrp Avatar answered Oct 01 '22 19:10

Mvrp