Converting Swift Array to NSData for NSUserDefaults.StandardUserDefaults persistent storage

北城以北 提交于 2019-11-30 19:52:40

问题


I'm trying to get my head around Swift (after being relatively competent with Obj-C) by making a small app. I would like to use NSUserDefaults to persistently save a small amount of data but I am having problems.

I initialise an empty array of tuples like this:

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 to NSUserDefaults with standard Swift code such as this:

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

I get an error saying that the tuple array doesn't conform to the AnyObject class. So I tried to turn it into NSData:

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

...but I get the same error during the conversion to NSData. The object being held by my array doesn't conform to AnyObject. I've also tried at each stage to make it immutable by using:

let immutableArray = costCategoryArray

Ive also tried creating a class instead of using tuples which I understood would make it comply with 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 the new error is:

"Property list invalid 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 like I need some expert advice as so far everything I try to do with Swift is pretty much incompatible...

Thanks!


回答1:


Anything you are archiving to NSData and back needs to implement the NSCoding protocol. I found that in addition, my Swift class had to extend NSObject. Here is a quick 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



回答2:


value of "financialData" should be in quotes:

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


来源:https://stackoverflow.com/questions/26224808/converting-swift-array-to-nsdata-for-nsuserdefaults-standarduserdefaults-persist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!