Swift 4 Codable Object Collections

I have a class Codablewith a variable that contains a dictionary with Stringkeys and values, which may be Strings, Intor custom structures that are appropriate Codable. My question is:

How to define a dictionary with values Codable?

I was hoping it would be enough to say

var data: [String: Codable] = [:]

but obviously my class no longer matches Codable. I think the problem here is the same as mine here, where I pass the protocol and not the object limited by the protocol

Using JSON Encoder to Encode a Variable with Codable as a Type

So, suppose I need a limited generic type, something like AnyObject<Codable>, but that is not possible.

EDIT: answer

Since this cannot be done in accordance with the accepted answer, I resort to a structure with dictionaries for each data type

struct CodableData {
    var ints: [String: Int]
    var strings: [String: String]
    //...

    init() {
       ints = [:]
       strings = [:]
    }
}

var data = CodableData()
+4
source share
3 answers

The Swift collection contains only one type, and in order for it to be Codable, this type had to be Codable - not the Codable type, but the adopter of the Codable protocol. You need a type here to be some specific Codable adopter.

Therefore, the only way to do what you describe is to basically come up with a new type of StringOrIntOrStruct that wraps a String or Int or struct and accepts Codable itself.

, , . , Swift, ; . . .

+2

, , Codable. , Codable :

class Foo: Codable {

    var data: [String:Codable] = [:]

    func encode(to encoder: Encoder) throws {
        // ...
    }

    required init(from decoder: Decoder) throws {
        // ...
    }
}

, data, . , :

enum Option: Codable {

    case number(Int)
    case string(String)

    func encode(to encoder: Encoder) throws {
        // ...
    }

    init(from decoder: Decoder) throws {
        if let num = try? Int(from: decoder) {
            self = .number(num)
        } else if let str = try? String(from: decoder) {
            self = .string(str)
        } else {
            throw something
        }
    }
}

class Foo: Codable {

    var data: [String:Option] = [:]
}
+1

- Generics Swift? :

public struct Response<T> where T : Codable {
        let ContentEncoding : String?
        let ContentType : String?
        let JsonRequestBehavior : Int?
        let MaxJsonLength : Int?
        let RecursionLimit : Int?

        let data : Data?

        public struct Data : Codable {
            let response : String?
            let status : String?

            let details : [T]?
        }
    }
0

Source: https://habr.com/ru/post/1683892/


All Articles