Home > Blockchain >  How to define the type of a dictionary to use as a store type in Swift
How to define the type of a dictionary to use as a store type in Swift

Time:01-24

I have a store model, and want to define all the data types used in the app in a single variable before storing it

final class Store: ObservableObject {
    @Published var projects: [Project] = []
    @Published var clients: [Client] = []
    @Published var userData: UserData? = nil
    private var storeData:[String: Any?] = [
        "projects": [],
        "clients": [],
        "userData":nil
    ]

    private func loadData(from storeFileData: Data) -> [String : [Any?]] {
        do {
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            return try decoder.decode([String : [Any?]].self, from: storeFileData)
        } catch {
            print(error)
            return []
        }
    }

I get this error:

Type 'Any' cannot conform to 'Decodable'

How to define the storeData type?

CodePudding user response:

In the loadData function, the return type of the function is defined as [String : [Any?]], but the type of the storeData variable is [String: Any?].

The issue is that the JSONDecoder can only decode to types that conform to the Decodable protocol, and Any does not conform to this protocol. Instead, you should define the storeData variable with specific types for each key, such as:

private var storeData: [String: [Project]?] = [
    "projects": [],
    "clients": [],
    "userData":nil
]

or you need to define your custom Decodable protocol to decode the data and use it in the loadData function. Also, you can use Codable protocol which is a combination of Encodable and Decodable protocols.

struct StoreData: Decodable {
    let projects: [Project]
    let clients: [Client]
    let userData: UserData?

    private enum CodingKeys: String, CodingKey {
        case projects
        case clients
        case userData
    }
}

private func loadData(from storeFileData: Data) -> StoreData {
    do {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        return try decoder.decode(StoreData.self, from: storeFileData)
    } catch {
        print(error)
        return StoreData(projects: [], clients: [], userData: nil)
    }
}

To update your storeData you can do storeData = loadData(from: storeFileData)

  • Related