使用Swift将类中的struct保存到NSUserDefaults

Tho*_*mas 8 nsuserdefaults nscoding uiimageview ios swift

我有一个类,类内部是一个(swift)数组,基于全局结构.我想将此类的数组保存到NSUserDefaults.这是我的代码:

struct mystruct {
    var start : NSDate = NSDate()
    var stop : NSDate = NSDate()
}

class MyClass : NSObject {

    var mystructs : [mystruct]

    init(mystructs : [mystruct]) {

        self.mystructs = mystructs 
        super.init()
    }

    func encodeWithCoder(encoder: NSCoder) {
        //let val = mystructs.map { $0 as NSObject } //this also doesn't work
        let objctvtmrec = NSMutableArray(mystructs)  //gives error
        encoder.encodeObject(objctvtmrec)
        //first approach:
        encoder.encodeObject(mystructs) //error: [mystructs] doesn't conform to protocol 'anyobject'
    }

}

var records : [MyClass] {
    get {
        var returnValue : [MyClass]? = NSUserDefaults.standardUserDefaults().objectForKey("records") as? [MyClass]
        if returnValue == nil
        {
            returnValue = []
        }
        return returnValue!
    }
    set (newValue) {
        let val = newValue.map { $0 as AnyObject }
        NSUserDefaults.standardUserDefaults().setObject(val, forKey: "records")
        NSUserDefaults.standardUserDefaults().synchronize()
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经子类化为NSObject,我知道我需要NSCoding.但我没有找到任何方法将struct数组转换为NSMuteableArray或类似的东西我可以存储.直到现在唯一的想法是遍历每个条目并将其直接复制到新数组或在整个项目中使用大量或客观的代码,因此我永远不需要从swift数组转换为objective-c数组.两者都是我不想做的事情.

aka*_*kyy 10

Swift结构不是类,因此它们不符合AnyObject协议.你必须重新思考你的方法.以下是一些建议:

  1. 将您structfinal class执行不变性

    final class MyStruct {
        let start : NSDate = NSDate()
        let stop : NSDate = NSDate()
    }
    
    encoder.encodeObject(mystructs)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将它们映射为类型的数组字典 [String: NSDate]

    let structDicts = mystructs.map { ["start": $0.start, "stop": $0.stop] }
    encoder.encodeObject(structDicts)
    
    Run Code Online (Sandbox Code Playgroud)


zap*_*aph 6

NSUserDefaults:在它能够处理类型是有限的NSData,NSString,NSNumber,NSDate,NSArray,NSDictionary,和Bool.因此,不能保存Swift对象或结构.必须将其他任何内容转换为NSData对象.

NSUserDefaults不起作用的方式不同NSArchiver.由于您已经添加NSCoder到类中,因此最好的选择可能是保存并恢复NSArchiver到目录中的Documents文件.

来自Apple NSUserDefaultsDocs:

默认对象必须是属性列表,即(或集合的实例组合)的实例:NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary.如果要存储任何其他类型的对象,通常应将其存档以创建NSData实例.