Dictionary 储存字典<;字符串,自定义对象>;在Swift中

Dictionary 储存字典<;字符串,自定义对象>;在Swift中,dictionary,struct,swift,nsuserdefaults,Dictionary,Struct,Swift,Nsuserdefaults,我已经创建了一个字典,其中键是一个字符串,值是一个名为扇区协调的自定义对象。 我只想将整个该死的东西存储在NSUserDefaults中,但当我这样做时,Xcode说: The type [String, SectorCoordinate] does not conform to protocol AnyObject 我真的很困惑。我认为AnyObject是Swift版本的Objective-C的id,应该能够容纳任何对象 我看到并试图实现一系列针对[String:String]字典(例如JS

我已经创建了一个
字典
,其中键是一个
字符串
,值是一个名为
扇区协调的自定义对象。

我只想将整个该死的东西存储在
NSUserDefaults
中,但当我这样做时,Xcode说:

The type [String, SectorCoordinate] does not conform to protocol AnyObject
我真的很困惑。我认为
AnyObject
是Swift版本的Objective-C的
id
,应该能够容纳任何对象

我看到并试图实现一系列针对
[String:String]
字典(例如JSON操作)的解决方案,但这些解决方案都不起作用,出现了类似的错误。我甚至尝试分解键值对,当我尝试将一个
扇区协调
(它本身只是一个
结构
,其中包含一堆
字符串
s、
Int
s和日期)存储为
任何对象时,都会出现相同的错误

有人对如何将半复杂对象和/或其字典存储为
AnyObject
有什么建议吗?这似乎应该简单得多。

有关NSUserdefaults的状态
setObject:forKey:
method:

值参数只能是属性列表对象:NSData, NSString、NSNumber、NSDate、NSArray或NSDictionary。对于NSArray和 NSDictionary对象,其内容必须是属性列表对象。 请参阅《属性列表编程指南》中的“什么是属性列表?”

因此,例如,您可以将Swift字典
[String:NSNumber]
强制转换为NSDictionary,并使用NSUserDefaults保存/检索它,如下所示:

let dictionary = ["myKey" : NSNumber(int: 12)] as NSDictionary
NSUserDefaults.standardUserDefaults().setObject(dictionary, forKey: "myDict") //[myKey : 12]
NSUserDefaults.standardUserDefaults().dictionaryForKey("myDict") //{[myKey : 12]}
但是这对于类型为
[String:SectorCoordinate]
的Swift字典是不可能的,其中
SectorCoordinate
是一个Swift结构。

有关NSUserdefaults的状态
setObject:forKey:
方法:

值参数只能是属性列表对象:NSData, NSString、NSNumber、NSDate、NSArray或NSDictionary。对于NSArray和 NSDictionary对象,其内容必须是属性列表对象。 请参阅《属性列表编程指南》中的“什么是属性列表?”

因此,例如,您可以将Swift字典
[String:NSNumber]
强制转换为NSDictionary,并使用NSUserDefaults保存/检索它,如下所示:

let dictionary = ["myKey" : NSNumber(int: 12)] as NSDictionary
NSUserDefaults.standardUserDefaults().setObject(dictionary, forKey: "myDict") //[myKey : 12]
NSUserDefaults.standardUserDefaults().dictionaryForKey("myDict") //{[myKey : 12]}

但是这对于类型为
[String:SectorCoordinate]
的Swift字典是不可能的,其中
SectorCoordinate
是一个Swift结构。

您可以在NSUserDefs中存储任何对象,请参阅NSUserDefaults Apple文档:

NSUserDefaults类为访问提供了方便的方法 常见类型,如浮点、双精度、整数、布尔和URL。A. 默认对象必须是属性列表,即(或)的实例 对于集合:NSData、NSString、, NSNumber、NSDate、NSArray或NSDictionary如果要存储任何 对于其他类型的对象,通常应将其存档以创建 NSData的实例。有关更多详细信息,请参阅首选项和设置 编程指南


要使对象能够无缝地转换为NSData,请确保您的类符合NSCoding协议(即,可以对其进行归档和取消归档)。Swift有时还希望您的类也符合NSSecureCodeding。

您可以将任何对象存储在NSUserDefs中,请参阅NSUserDefaults Apple文档:

NSUserDefaults类为访问提供了方便的方法 常见类型,如浮点、双精度、整数、布尔和URL。A. 默认对象必须是属性列表,即(或)的实例 对于集合:NSData、NSString、, NSNumber、NSDate、NSArray或NSDictionary如果要存储任何 对于其他类型的对象,通常应将其存档以创建 NSData的实例。有关更多详细信息,请参阅首选项和设置 编程指南


要使对象能够无缝地转换为NSData,请确保您的类符合NSCoding协议(即,可以对其进行归档和取消归档)。Swift有时还希望您的类也符合NSSecureCodeding。

我已经在本页的其他地方回答了如何使用NSUserDefaults,但是如果您有任何数据,请不要使用NSUserDefaults。此版本将一系列字典(包括您自己自制的结构)保存到文件中并进行恢复。这可以粘贴到操场上进行测试。事实上,在NSUserDefaults版本中,再增加两个支票簿条目将使保存在用户默认值中的操作崩溃

import Cocoa

//The key to the dictionary is in the struct here as permanentTimeDateCode

struct CheckBookEntry{

    var permanentTimeDateCode = String()  //value here is also the key for the dictorary it must be a string
    var amountOfTransaction = Double()
    var category = String()
    var payee = String()
    var memo = String()
    var checkNumber = String()

}

var checkBookEntryOne = CheckBookEntry(permanentTimeDateCode: "2015-02--06", amountOfTransaction: 20.00, category: "Properietor", payee: "Balance Forward", memo: "No memo", checkNumber: "00000")

var checkBookEntryTwo = CheckBookEntry(permanentTimeDateCode: "2015-02--05", amountOfTransaction: -15.00, category: "Reference", payee: "Bookstore", memo: "No memo", checkNumber: "00001")

var checkBookEntryThree = CheckBookEntry(permanentTimeDateCode: "2015-02--08", amountOfTransaction: -5.00, category: "Dinning", payee: "Moe's", memo: "Good Eats", checkNumber: "00003")

//A dictionary with the date as the key and a CheckBookEntry struct as the value.
var myCheckBookEntry:Dictionary = [String  :CheckBookEntry ]()

myCheckBookEntry["2015-02--06"] = checkBookEntryOne
myCheckBookEntry["2015-02--07"] = checkBookEntryTwo
myCheckBookEntry["2015-02--08"] = checkBookEntryThree
print(myCheckBookEntry)


//To save these set up an array of dictionaries
var checkEntryArrayOfDictionaries:[[String:AnyObject]] = []

//your struct is no an object that can be saved so it needs to be converted.
//use the variable names from our struct CheckBookEntry as the keys

checkEntryArrayOfDictionaries.append( ["permanentTimeDateCode" : checkBookEntryOne.permanentTimeDateCode,  "amountOfTransaction" : checkBookEntryOne.amountOfTransaction, "catergory" : checkBookEntryOne.category, "payee" : checkBookEntryOne.payee, "memo" :  checkBookEntryOne.memo, "checkNumber": checkBookEntryOne.checkNumber])

checkEntryArrayOfDictionaries.append( ["permanentTimeDateCode" : checkBookEntryTwo.permanentTimeDateCode,  "amountOfTransaction" : checkBookEntryTwo.amountOfTransaction, "catergory" : checkBookEntryTwo.category, "payee" : checkBookEntryTwo.payee, "memo" :  checkBookEntryTwo.memo, "checkNumber": checkBookEntryTwo.checkNumber])

checkEntryArrayOfDictionaries.append( ["permanentTimeDateCode" : checkBookEntryThree.permanentTimeDateCode,  "amountOfTransaction" : checkBookEntryThree.amountOfTransaction, "catergory" : checkBookEntryThree.category, "payee" : checkBookEntryThree.payee, "memo" :  checkBookEntryThree.memo, "checkNumber": checkBookEntryThree.checkNumber])


print("//______________printing checkEntryArrayOfDictionaries----//")
print(checkEntryArrayOfDictionaries)

//Save The values
NSUserDefaults().setObject(checkEntryArrayOfDictionaries, forKey: "aCheckbook")

let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let pathLocationString:String =  paths[0] as String

let checkbookFile:String = pathLocationString.stringByAppendingString("/aCheckbook")
print(checkbookFile)

if !NSFileManager.defaultManager().fileExistsAtPath(checkbookFile) {

    print("files exists or will exist")
    NSFileManager.defaultManager().createFileAtPath(checkbookFile, contents: nil, attributes: nil)
}

NSKeyedArchiver.archiveRootObject(checkEntryArrayOfDictionaries,
    toFile: checkbookFile)

//The dictionary to recover to PLAYGROUND
var myCheckBookEntry2:Dictionary = [String  :CheckBookEntry ]()

//A SINGLE INSTANCE OF THE STRUCT TO SAVE EACH TO.
var anIndividualCheckBookEntry = CheckBookEntry()


    let path2 = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    let myStringDictionaryArray:String =  path2[0] as String

   let arrayDictionaryFilePath:String = myStringDictionaryArray.stringByAppendingString("/aCheckbook")
    print(arrayDictionaryFilePath)


if NSFileManager.defaultManager().fileExistsAtPath(arrayDictionaryFilePath) {
    let dictionaryFileArray =
    NSKeyedUnarchiver.unarchiveObjectWithFile(arrayDictionaryFilePath)
        as! [Dictionary <String,AnyObject> ]

    var x = dictionaryFileArray[0]
    var y = dictionaryFileArray[1]
    var z = dictionaryFileArray[2]

    print("\(x) \(y) \(z)")

    var myDictionaryX = x as! [String : AnyObject]
    var myDictionaryY = y as! [String : AnyObject]
    var myDictionaryZ = z as! [String : AnyObject]
}


print("//---------------------------------//")
导入可可粉
//字典的键在这里的结构中作为permanentTimeDateCode
结构支票簿条目{
var permanentTimeDateCode=String()//这里的值也是口述的键,它必须是字符串
var amountOfTransaction=Double()
var category=String()
var paye=String()
var memo=String()
var checkNumber=String()
}
var checkBookEntryOne=支票账簿分录(永久时间日期代码:“2015-02--06”,交易金额:20.00,类别:“财产人”,收款人:“远期余额”,备注:“无备注”,支票编号:“00000”)
var checkBookEntryTwo=支票簿条目(永久时间日期代码:“2015-02--05”,交易金额:-15.00,类别:“参考”,收款人:“书店”,备注:“无备注”,支票编号:“00001”)
var checkBookEntryThree=支票簿条目(永久时间日期代码:“2015-02--08”,交易金额:-5.00,类别:“用餐”,收款人:“Moe”,备注:“好吃”,支票号码:“00003”)
//以日期为键,以CheckBookEntry结构为值的字典。
var myCheckBookEntry:Dictionary=[String:CheckBookEntry]()
myCheckBookEntry[“2015-02--06”]=checkBookEntryOne
myCheckBookEntry[“2015-02--07”]=checkBookEntryTwo
myCheckBookEntry[“2015-02--08”]=checkBookEntryThree
打印(myCheckBookEntry)
//要保存这些,请设置一组字典
var checkEntryArrayOfDictiona