I am doing a wrapper on top of the keychain. I would like to have a method to store dictionaries. I am using the Codable protocol to encode the objects into Data.
I actually don't really wan't the code to store any object in the dictionary, since the data could be read / written from several places in the code that may not know the same custom classes (the code is splitted into frameworks). Therefore accepting only raw types (String, Bool, Float, Double, Integer) and if possible arrays or dictionaries of those would be great.
So my question is: is it possible to specify a method that would accept only dictionaries like [String: Raw] where Raw would be (String| Bool | Float| Double | Integer | [Raw] | [String: Raw])?
I also tried to have a constraint on Codable (I would put the interdiction to use custom classes in the documentation), with the code:
func write<T: Codable>(param: [String: T]) {
print(param)
}
func read<T: Codable>(of valueType: T.Type, for key: String) -> T {
// read the data from the keychain
}
let param: [String: Int] = [
"key": 0
]
write(param: param)
let integer = read(of: Int.self, for: "key")
Is there a better way to implement this? Especially, here I can accept only values with the same type ([String: String], [String, Int] ...), not [String: (AnyObject & Codable)] to have structures with several levels, like:
let structure: [String: Codable] = [
"forename": "John",
"name": "Doe",
"location": [
"street": "Brooklyn av",
"city": "New York"
],
"phone": 0123456789
]
CodePudding user response:
Yes, there is a way to specify a method like that:
protocol Raw {}
extension String: Raw {}
extension Bool: Raw {}
extension Float: Raw {}
extension Double: Raw {}
extension Int: Raw {}
extension Array: Raw where Element: Raw {}
extension Dictionary: Raw where Key == String, Value: Raw {}
func write<T: Raw>(param: [String: T]) {
print(param)
}