web-dev-qa-db-fra.com

Swift Codable devrait décoder Dictionary <String, Any> mais a trouvé une chaîne / des données à la place

Je travaille avec le protocole Codable

Voici mon fichier JSON:

    {  
   "Adress":[  

   ],
   "Object":[  
      {  
         "next-date":"2017-10-30T11:00:00Z",
         "text-sample":"Some text",
         "image-path":[  
            "photo1.png",
            "photo2.png"
         ],
         "email":"[email protected]",
         "id":"27"
      },
      {  
         "next-date":"2017-10-30T09:00:00Z",
         "text-sample":"Test Test",
         "image-path":[  
            "image1.png"
         ],
         "email":"[email protected]",
         "id":"28"
      }
   ]
}

Je n'ai qu'à me concentrer sur le tableau Object, et le tableau "image-path" peut contenir 0, 1 ou 2 chaînes.

Voici donc mon implémentation:

struct Result: Codable {
    let Object: [MyObject]
}

struct MyObject: Codable {

    let date: String
    let text: String
    let image: [String]
    let email: String
    let id: String

    enum CodingKeys: String, CodingKey {
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    }

    init() {
        self.date = ""
        self.text = ""
        self.image = []
        self.email = ""
        self.id = ""
    }
}

Je l'appelle depuis ma classe de service après avoir demandé et obtenu les données JSON de cette façon:

if let data = response.data {
                let decoder = JSONDecoder()
                let result = try! decoder.decode(Result, from: data)
                dump(result.Object)
            }

Tout fonctionne sauf le [String] pour la propriété image

Mais il ne peut pas être compilé, ou j'obtiens une erreur "Attendu pour décoder ...".

Comment dois-je gérer le scénario de données nul/nul?

10
user7219266

J'ai apporté une petite modification à votre MyObject struct, C'est-à-dire,

1. Marqué tout properties comme optionals

2. Supprimé init() (Je ne pense pas qu'il y ait d'exigence de init() ici.)

3. Utilisez Result.self Au lieu de Result dans la méthode decoder.decode(...)

struct MyObject: Codable
{
    let date: String?
    let text: String?
    let image: [String]?
    let email: String?
    let id: String?

    enum CodingKeys: String, CodingKey
    {
        case date = "next-date"
        case text = "text-sample"
        case image = "image-path"
        case email = "email"
        case id = "id"
    }
}

Pour tester ce qui précède, j'ai utilisé le code ci-dessous et cela fonctionne très bien.

    let jsonString = """
        {"Adress": [],
        "Object": [{"next-date": "2017-10-30T11:00:00Z",
        "text-sample": "Some text",
        "image-path": ["photo1.png", "photo2.png"],
        "email": "[email protected]",
        "id": "27"},
      {"next-date": "2017-10-30T09:00:00Z",
       "text-sample": "Test Test",
       "image-path": ["image1.png"],
       "email": "[email protected]",
       "id": "28"}
       ]
        }
    """
    if let data = jsonString.data(using: .utf8)
    {
        let decoder = JSONDecoder()
        let result = try? decoder.decode(Result.self, from: data) //Use Result.self here
        print(result)
    }

Voici la valeur du résultat que j'obtiens:

enter image description here

5
PGDev