将Swift数组转换为NSData,用于NSUserDefaults.StandardUserDefaults持久存储

use*_*074 2 arrays tuples nsdata swift

我试图通过制作一个小应用程序来了解Swift(在与Obj-C相对胜任之后).我想使用NSUserDefaults持久保存少量数据,但我遇到了问题.

我初始化一个空数组的元组,如下所示:

var costCategoryArray: [(name:String, defaultValue:Int, thisMonthsEstimate:Int, sumOfThisMonthsActuals:Int, riskFactor:Float, monthlyAverage:Float)]=[]
Run Code Online (Sandbox Code Playgroud)

当数组有一个条目时,我想用标准的Swift代码将数组保存到NSUserDefaults,如下所示:

NSUserDefaults.standardUserDefaults().setObject(costCategoryArray, forKey: "financialData")
NSUserDefaults.standardUserDefaults().synchronize()
Run Code Online (Sandbox Code Playgroud)

我得到一个错误,说元组数组不符合AnyObject类.所以我试着把它变成NSData:

var myNSData: NSData = NSKeyedArchiver.archivedDataWithRootObject(costCategoryArray)
var myUnarchivedData: Array = NSKeyedUnarchiver.unarchiveObjectWithData(myNSData)
Run Code Online (Sandbox Code Playgroud)

...但是在转换为NSData期间我遇到了同样的错误.我的数组持有的对象不符合AnyObject.我还尝试在每个阶段使用以下内容使其不可变:

let immutableArray = costCategoryArray
Run Code Online (Sandbox Code Playgroud)

我也试过创建一个类而不是使用元组,我理解它会使它符合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
    }
}
Run Code Online (Sandbox Code Playgroud)

但新的错误是:

"属性列表格式无效:200(属性列表不能包含'CFType'类型的对象)"

一组元组有什么问题?为什么我不能存储类对象的数组?我觉得我需要一些专家建议,因为到目前为止我尝试用Swift做的一切都非常不相容......

谢谢!

slu*_*und 9

您归档到NSData并返回的任何内容都需要实现NSCoding协议.我发现另外,我的Swift类必须扩展NSObject.以下是编码和解码的Swift类的快速示例:

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
Run Code Online (Sandbox Code Playgroud)