在尝试保存我创建的新结构时,我无法保存到CoreData。
var allInformationByDate = [
"2016-08-13": DayData(sales: 0, doorsKnocked: 0, milesWalked: 0.00, hoursWorked: 0.00)
]
struct DayData {
let sales: Int
let doorsKnocked: Int
let milesWalked: Double
let hoursWorked: Double
}
我收到了错误:
无法将'[String:DayData]'类型的值转换为预期的参数类型'AnyObject?'
在这段代码上,特别是“allInformationByDate”......
var allInfoByDateDefault = NSUserDefaults.standardUserDefaults()
allInfoByDateDefault.setValue(allInformationByDate, forKey:"allInfoByDateRecord")
allInfoByDateDefault.synchronize()
有人知道如何修复这种语法吗?我已经尝试过改为
allInformationByDate as! AnyObject
但这只是让应用程序崩溃。
答案 0 :(得分:1)
问题是您无法在NSUserDefaults
但由于DayData
的所有属性都符合属性列表,因此您可以编写NSUserDefaults
的扩展名以将DayData
转换为字典,反之亦然。
此扩展程序可以编写单个DayData
对象以及字典[String:DayData]
。
extension NSUserDefaults {
// read a write a single 'DayData' object
func dayDataForKey(key: String) -> DayData? {
guard let data = self.objectForKey(key) as? [String:AnyObject] else { return nil }
return DayData(sales: data["sales"] as! Int, doorsKnocked: data["doorsKnocked"] as! Int, milesWalked: data["milesWalked"] as! Double, hoursWorked: data["hoursWorked"] as! Double)
}
func setDayData(dayData : DayData, forKey key: String) {
let propertyListRepresentation = ["sales": dayData.sales, "doorsKnocked" : dayData.doorsKnocked, "milesWalked": dayData.milesWalked, "hoursWorked": dayData.hoursWorked]
self.setObject(propertyListRepresentation, forKey: key)
}
// read a write a dictionary ('[String:DayData]') object
func dayDataDictionaryForKey(key: String) -> [String: DayData]? {
guard let dayData = self.objectForKey(key) as? [String : [String: AnyObject]] else { return nil }
var result = [String: DayData]()
for (key, value) in dayData {
result[key] = DayData(sales: value["sales"] as! Int, doorsKnocked: value["doorsKnocked"] as! Int, milesWalked: value["milesWalked"] as! Double, hoursWorked: value["hoursWorked"] as! Double)
}
return result
}
func setDayDataDictionary(dayData : [String: DayData], forKey key: String) {
var result = [String : [String: AnyObject]]()
for (key, value) in dayData {
result[key] = ["sales": value.sales, "doorsKnocked" : value.doorsKnocked, "milesWalked": value.milesWalked, "hoursWorked": value.hoursWorked]
}
self.setObject(result, forKey: key)
}
}
现在您可以轻松地将字典写入用户默认值:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setDayDataDictionary(allInformationByDate, forKey: "allInfoByDateRecord")
或阅读
let defaults = NSUserDefaults.standardUserDefaults()
if let infoByDateDefault = defaults.dayDataDictionaryForKey("allInfoByDateRecord") {
allInformationByDate = infoByDateDefault
}
答案 1 :(得分:0)
您不应使用setValue
方法。要设置字典,请调用setObject
方法。
文档:
在标准应用程序域中设置指定默认密钥的值。
value参数只能是属性列表对象:NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary。对于NSArray和NSDictionary对象......
此外,使用带有Objective-C API的Swift结构非常非常不方便。您需要使结构符合NSCoding
并将其转换为NSData
,然后再将其存储到NSUserDefaults。这基本上是一团糟。
您可以搜索向您展示如何符合NSCoding
的教程,但我不建议您使用它。
NSUserDefaults
通常用于保存简单的数据结构,如整数,浮点数,bool。这是因为,毕竟它是专为您设计的,以保存用户偏好和相关内容。
看到你有这样的结构,我建议你使用Core Data而不是NSUserDefaults
。您可以创建数据模型并基于struct:
NSManagedObject
子类
class DayData: NSManagedObject {
@NSManaged var sales: NSNumber?
@NSManaged var doorsKnocked: NSNumber?
@NSManaged var milesWalked: NSNumber?
@NSManaged var hoursWorked: NSNumber?
}
相信我,在这种情况下,核心数据更方便。
有关详细信息,请查看this tutorial。