Convert Swift Array to NSData for NSUserDefaults.StandardUserDefaults persistent storage

I am trying to bow my head to Swift (after I was relatively competent with Obj-C) by creating a small application. I would like to use NSUserDefaults to keep a small amount of data permanently, but I'm having problems.

I initialize an empty tuple array as follows:

var costCategoryArray: [(name:String, defaultValue:Int, thisMonthsEstimate:Int, sumOfThisMonthsActuals:Int, riskFactor:Float, monthlyAverage:Float)]=[] 

When the array has an entry, I want to save the array in NSUserDefaults with standard Swift code, for example:

 NSUserDefaults.standardUserDefaults().setObject(costCategoryArray, forKey: "financialData") NSUserDefaults.standardUserDefaults().synchronize() 

I get a message that the tuple array does not match the AnyObject class. So I tried turning it into NSData:

 var myNSData: NSData = NSKeyedArchiver.archivedDataWithRootObject(costCategoryArray) var myUnarchivedData: Array = NSKeyedUnarchiver.unarchiveObjectWithData(myNSData) 

... but I get the same error when converting to NSData. The object held by my array does not match AnyObject. I also tried at each stage to make it immutable using:

 let immutableArray = costCategoryArray 

Ive also tried to create a class instead of using tuples, which, as I understand it, would force it to obey AnyObject:

 class costCategory : NSObject { var name : String var defaultValue : Int var thisMonthsEstimate : Int var sumOfThisMonthsActuals : Int var riskFactor : Float var monthlyAverage : Float init (name:String, defaultValue:Int, thisMonthsEstimate:Int, sumOfThisMonthsActuals:Int, riskFactor:Float, monthlyAverage:Float) { self.name = name self.defaultValue = defaultValue self.thisMonthsEstimate = thisMonthsEstimate self.sumOfThisMonthsActuals = sumOfThisMonthsActuals self.riskFactor = riskFactor self.monthlyAverage = monthlyAverage } } 

But a new error:

"The property list is not valid for format: 200 (property lists cannot contain objects of type" CFType ")"

What is the problem with an array of tuples? Why can't I store an array of class objects? I feel that I need expert advice, because so far everything that I am trying to do with Swift is largely incompatible ...

Thanks!

+1
source share
2 answers

Everything that you archive in NSData and back should implement the NSCoding protocol. I found that in addition, my Swift class had to extend NSObject. The following is a brief example of a Swift class that encodes and decodes:

 class B : NSObject, NSCoding { var str : String = "test" required init(coder aDecoder: NSCoder) { str = aDecoder.decodeObjectForKey("str") as String } override init() { } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(str, forKey: "str") } } // create an Object of Class B var b : B = B() // Archive it to NSData var data : NSData = NSKeyedArchiver.archivedDataWithRootObject(b) // Create a new object of Class B from the data var b2 : B = NSKeyedUnarchiver.unarchiveObjectWithData(data) as B 
+8
source

The value of "financialData" must be in quotation marks:

 NSUserDefaults.standardUserDefaults().setObject("costCategoryArray", forKey: "financialData") NSUserDefaults.standardUserDefaults().synchronize() 
-3
source

Source: https://habr.com/ru/post/1236315/


All Articles