saoudrizwan / Disk

Easily persist structs, images, and data on iOS
MIT License
3.11k stars 172 forks source link

Object with nil data if model class has CodingKeys #49

Closed ElyDantas closed 6 years ago

ElyDantas commented 6 years ago

Below class only get saved into Disk if CodingKeys are removed

class Agendamento: Codable{

    var response: String?
    var serialNumber: String?
    var nome: String?
    var ativo = false
    var programacoes = [Programacao]()

    init(nome: String, ativo: Bool = false){
        self.nome = nome
        self.ativo = ativo
        self.programacoes = [Programacao]()
    }

    init(){}

    private enum CodingKeys: String, CodingKey {

        case response = "RES"
        case serialNumber = "SN"
        case programacoes = "P"

    }

}
saoudrizwan commented 6 years ago

You are likely getting nil because you saved this structure to the same file location without the CodingKeys first. If you try decoding this raw JSON data using this updated structure with CodingKeys, then it will fail since that's not what was used to encode the JSON data in the first place.

To be sure, try using a full do, try, catch block and see exactly what error you're getting when trying to decode.

If you would like to use CodingKeys, make sure that you first remove any previously encoded file from the desired file location first before trying to save again with the new CodingKeys.

Some things to keep in mind:

When this enumeration is present, its cases serve as the authoritative list of properties that must be included when instances of a codable type are encoded or decoded. The names of the enumeration cases should match the names you've given to the corresponding properties in your type.

Omit properties from the CodingKeys enumeration if they won't be present when decoding instances, or if certain properties shouldn't be included in an encoded representation. A property omitted from CodingKeys needs a default value in order for its containing type to receive automatic conformance to Decodable or Codable. Source: https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

ElyDantas commented 6 years ago

This was my mistake: "A property omitted from CodingKeys needs a default value in order for its containing type to receive automatic conformance to Decodable or Codable.". Implementing decoder's init method and initializing all properties fixed the problem.

init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let nome = try? container.decode(String.self, forKey: .nome){ 
              self.nome = nome
        }else { 
              self.nome = nil
        }       
         ...
    }