我的解决方案基于苹果如何进行序列化,我的解决方案是让你想要保存的每种类型都有不同的键枚举.
首先创建一个协议,任何可以保存(或恢复)的东西都必须采用该协议
protocol Saveable
{
associatedtype Key: CodingKey
}
您希望能够保存的任何类型都必须具有符合CodingKey
的Key
嵌套类型.后者只是为了让我有一种一致的方法从Key
个实例中提取一个字符串形式的密钥.
按如下方式更改您的协议
protocol LocalStorage
{
func save<T: Saveable>(value: T, for key: T.Key)
func get<T: Saveable>(type: T.Type, key: T.Key) -> T?
}
如果T.Key
是枚举,则无论何时保存T
类型的值,都会自动限制使用T.Key
中的枚举大小写.我把value
放在第一位的原因是,这意味着当您输入对函数的调用时,当您到达for:
时,Xcode编辑器已经计算出允许的键是什么,并将给您一个可供 Select 的完成列表.
下面是您可以如何实现User
struct User
{
var name: String
}
extension User: Saveable
{
enum Key: String, CodingKey
{
case user
case otherUser
}
}
在上面的情况下,有两个允许的密钥用于存储User
.
下面是LocalStorage
的存根实现
struct StorageImplementation: LocalStorage
{
func save<T: Saveable>(value: T, for key: T.Key)
{
print(key.stringValue)
}
func get<T: Saveable>(type: T.Type, key: T.Key) -> T?
{
print(key.stringValue)
return nil
}
}
这就是打电话给它的样子
let user = User(name: "jeremy")
StorageImplementation().save(value: user, for: .otherUser) // prints otherUser
StorageImplementation().get(type: User.self, key: .user) // prints user