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)