我已经创建了Dictionary
,其中密钥为String
且值为SectorCoordinate.
的自定义对象
我只想在NSUserDefaults
中存储完整的东西,但是当我这样做时,Xcode说:
The type [String, SectorCoordinate] does not conform to protocol AnyObject
我真的很困惑。我认为AnyObject
是Swift的Objective-C id
版本,应该能够容纳任何对象。
我已经看到并试图实施一系列针对[String: String]
词典(例如JSON操作)的解决方案,但这些解决方案没有效果,但有类似的错误。我甚至试图分解键值对,并且在尝试存储一个SectorCoordinate
(它本身只是一个struct
并且有一堆String
时,我也会遇到同样的错误} s,Int
和其中的日期)为AnyObject
。
有没有人对如何将半复杂对象和/或其词典存储为AnyObject
有任何建议?看起来这应该简单得多。
答案 0 :(得分:2)
关于NSUserdefaults setObject:forKey:
方法的Apple documentation州:
value参数只能是属性列表对象:NSData, NSString,NSNumber,NSDate,NSArray或NSDictionary。对于NSArray和 NSDictionary对象,其内容必须是属性列表对象。 请参阅“属性列表编程指南”中的“什么是属性列表?”。
因此,例如,您可以将Swift Dictionary [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 Struct。
答案 1 :(得分:2)
您可以在NSUserDefs中存储任何对象,请参阅NSUserDefaults Apple文档:
NSUserDefaults类提供了便于访问的方法 常见类型,例如浮点数,双精度数,整数,布尔值和URL。一个 默认对象必须是属性列表,即(或 对于集合的实例组合):NSData,NSString, NSNumber,NSDate,NSArray或NSDictionary。 如果你想存储任何 在其他类型的对象中,通常应将其存档以创建 NSData的实例。有关更多详细信息,请参阅首选项和设置 编程指南。
要拥有一个可以无缝转换为NSData的对象,请确保您的类符合NSCoding协议(即可以归档和取消归档)。 Swift有时也希望你的类符合NSSecureCoding。
答案 2 :(得分:1)
我已经回答了如何在本页的其他地方使用NSUserDefaults,但如果您有任何数据,请不要使用NSUserDefaults。此版本将包含您自己的自制结构的字典数组保存到FILE并恢复它们。这可以粘贴到游乐场进行测试。事实上,在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("//---------------------------------//")
答案 3 :(得分:1)
这会将包含自制结构的字典保存到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")
//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
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])
print("//______________printing checkEntryArrayOfDictionaries----//")
print(checkEntryArrayOfDictionaries)
//Save The values
NSUserDefaults().setObject(checkEntryArrayOfDictionaries, forKey: "aCheckbook")
//recovering the struct
//The dictionary to recover to PLAYGROUND
var myCheckBookEntry2:Dictionary = [String :CheckBookEntry ]()
//A SINGLE INSTANCE OF THE STRUCT TO SAVE EACH TO.
var anIndividualCheckBookEntry = CheckBookEntry()
//RECOVER THE SAVED ENTRY
if let checkEntry2 = NSUserDefaults().arrayForKey("aCheckbook") as? [[String:AnyObject]] {
for key in checkEntry2{
anIndividualCheckBookEntry.permanentTimeDateCode = key["permanentTimeDateCode"]! as! String
anIndividualCheckBookEntry.amountOfTransaction = key["amountOfTransaction"]! as! Double
anIndividualCheckBookEntry.category = key["catergory"]! as! String
anIndividualCheckBookEntry.payee = key["payee"]! as! String
anIndividualCheckBookEntry.memo = key["memo"]! as! String
anIndividualCheckBookEntry.checkNumber = key["checkNumber"]! as! String
//LOAD THIS SINGLE ENTRY INTO OUR NEW DICTIONARY
myCheckBookEntry2[ anIndividualCheckBookEntry.permanentTimeDateCode] = anIndividualCheckBookEntry
}
print("//---------------------------------//")
print(myCheckBookEntry2)
}