![](/img/trans.png)
[英]Store and update a Swift Dictionary in NSUserDefaults Xcode
[英]Store a Dictionary<String, CustomObject> in NSUserDefaults in Swift
我有一個創建的Dictionary
,其中的鍵是一個String
,值是一個稱為SectorCoordinate.
的自定義對象SectorCoordinate.
我只想將整個織補內容存儲在NSUserDefaults
,但是當我這樣做時,Xcode說:
The type [String, SectorCoordinate] does not conform to protocol AnyObject
我真的很困惑 我以為AnyObject
是Objective-C id
Swift版本,應該能夠容納任何對象。
我已經看到並嘗試實現了針對[String: String]
字典(例如JSON操作)的一系列解決方案,但是這些解決方案均無效,並且出現類似的錯誤。 我什至試圖破壞鍵值對,並且在嘗試甚至將一個SectorCoordinate
(它本身只是一個帶有一堆String
, Int
和日期的struct
存儲為一個時,也遇到了相同的錯誤。 AnyObject
。
有人對如何將半復雜對象和/或其字典存儲為AnyObject
有任何建議嗎? 看來這應該簡單得多。
Apple文檔說明了有關NSUserdefaults setObject:forKey:
方法的信息:
value參數只能是屬性列表對象: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 Struct。
您可以將任何對象存儲在NSUserDefs中,請參閱NSUserDefaults Apple文檔:
NSUserDefaults類提供了用於訪問常見類型(例如浮點數,雙精度數,整數,布爾值和URL)的便捷方法。 默認對象必須是屬性列表,即NSData,NSString,NSNumber,NSNumber,NSDate,NSArray或NSDictionary的一個實例(或用於集合的實例的組合)。 如果要存儲任何其他類型的對象,通常應將其歸檔以創建NSData實例。 有關更多詳細信息,請參見“首選項和設置編程指南”。
要擁有可以無縫轉換為NSData的對象,請確保您的類符合NSCoding協議(即,可以對其進行歸檔和取消歸檔)。 Swift有時也會希望您的類也符合NSSecureCoding。
我已經回答了如何在此頁上的其他地方使用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("//---------------------------------//")
這會將包含自制結構的字典保存到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)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.