【发布时间】:2021-09-14 22:23:51
【问题描述】:
我有以下方法可以从 CloudKit 下载数据,并在完成后为其分配一个用户默认属性。
private static func download<T>(dataType: T, recordID: CKRecord.ID, completion: (@escaping () -> Void)?) {
database.fetch(withRecordID: recordID) { record, error in
if let record = record, error == nil {
print("\(recordID) downloaded from iCloud")
guard let data = record["file"] as? Data else { return }
guard let decoded = try? JSONDecoder().decode(dataType.self, from: data) else { return }
// Assign to UserDefaults here
completion()
} else {
print("Couldn't download \(recordID) \(error.debugDescription)")
}
}
}
问题是 UserDefaults 由另一个类处理,该类具有一些属性,具有自己的 getter 和 setter。是否仍然可以使用这种通用下载方法并具有用于告诉它应该将解码数据分配给 Storage 类的哪个属性的参数?如果不是,我想我可以有一个基于 dataType 的 switch 语句。提前致谢。
class Storage {
static var ud = UserDefaults.standard
class var zones: [Zone] {
get {
if let data = ud.object(forKey: "zones") as? Data {
do { return try JSONDecoder().decode([Zone].self, from: data) }
catch { return ZoneHandler.defaultZones }
} else { return ZoneHandler.defaultZones }
}
set {
guard let data = try? JSONEncoder().encode(newValue) else { return }
ud.set(data, forKey: "zones")
sharedStorage?.set(data, forKey: "zones")
}
}
class var preferences: Preferences {
get {
if let data = ud.object(forKey: "preferences") as? Data {
do { return try JSONDecoder().decode(Preferences.self, from: data) }
catch { return Preferences() }
} else { return Preferences() }
}
set {
guard let data = try? JSONEncoder().encode(newValue) else { return }
ud.set(data, forKey: "preferences")
sharedStorage?.set(data, forKey: "preferences")
}
}
// Several more properties like this exist in this class
}
【问题讨论】:
-
将解码后的 json 传递给您的完成处理程序,这就是它的用途。
-
谢谢@JoakimDanielson,这是个好主意。
-
将此作为答案发布,我会接受。另外,我可以再问一件事吗?我注意到下载方法实际上并没有用我在这里写的东西编译,它说不能将类型'T'的值转换为预期的参数类型'T.Type'。您知道如何将类型作为属性传递吗? @JoakimDanielson 再次感谢。
标签: swift function methods syntax