Swift对象数组到plist文件

时间:2016-02-01 14:05:54

标签: swift

我正在尝试将对象的数组保存到I want to change background color of table row after selecting it. It works well for normal table. When i tried it to ng-table then only few styles are applied from ng-class not all styles are managed to apply including background color. My [enter link description here][1]. [1]: http://plnkr.co/edit/O6PzlHXEhOyheNS8BbAT?p=preview 但是我收到以下错误:

  

线程1:发出SIGABRT信号错误

我的对象类看起来像这样:

array.plist

在控制器中,我尝试使用Notes对象保存数组,如下所示:

class Note {
// MARK: Properties

var title: String
var photo: UIImage?
var text: String

// MARK: Initialization

init?(title: String, photo: UIImage?, text: String) {
    // Initialize stored properties.
    self.title = title
    self.photo = photo
    self.text = text

    // Initialization should fail if there is no name or if the rating is negative.
    if title.isEmpty{
        return nil
    }
}
func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(title, forKey:"title")
    aCoder.encodeObject(text, forKey:"text")
    aCoder.encodeObject(photo, forKey:"photo")
}

init (coder aDecoder: NSCoder!) {
    self.title = aDecoder.decodeObjectForKey("title") as! String
    self.text = aDecoder.decodeObjectForKey("text") as! String
    self.photo = aDecoder.decodeObjectForKey("photo") as! UIImage 
   }
}

2 个答案:

答案 0 :(得分:0)

并非所有类中的属性都不是可选的,但是当您从plist中检索它们时,您将解开所有这些属性。这可能会导致代码崩溃。

例如,如果照片是nil并且您保存了该对象,那么当您检索它时,您将展开它self.photo = aDecoder.decodeObjectForKey("photo") as! UIImage,如果您没有保存任何内容,它将会崩溃。

尝试删除展开并再次检查您的崩溃情况。即使这不是导致崩溃的原因,也会导致崩溃。

如果这不能解决您的问题,请粘贴完整的错误日志,以便更清楚地了解发生了什么。

答案 1 :(得分:0)

快速5。您可以将自定义类的数组保存到从NSObject和NSSecureCoding继承的.plist文件中。

如果我们创建一个名为Person的自定义类:

import Foundation

class Person: NSObject, NSSecureCoding {

    //Must conform to NSSecureCoding protocol
    public class var supportsSecureCoding: Bool { return true } //set to 'true'

    //just come generic things to describe a person
    private var name:String!
    private var gender:String!
    private var height:Double!

    //used to create a new instance of the class 'Person'
    init(name:String, gender:String, height:Double) {
        super.init()
        self.name = name
        self.gender = gender
        self.height = height
    }

    //used for NSSecureCoding:
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name") //encodes the name to a key of 'name'
        coder.encode(gender, forKey: "gender")
        coder.encode(height, forKey: "height")
    }

    //used for NSSecureCoding:
    required init?(coder: NSCoder) {
        super.init()
        self.name = (coder.decodeObject(forKey: "name") as! String)
        self.gender = (coder.decodeObject(forKey: "gender") as! String)
        self.height = (coder.decodeObject(forKey: "height") as! Double)
    }

    //created just to print the data from the class
    public override var description: String { return String(format: "name=%@,gender=%@,height%f", name, gender, height) }
}

现在,我们可以创建函数以从ViewController类中的.plist文件进行保存和加载:

我们需要从设备的目录系统中收集数据:

   func documentsDirectory()->String {
       let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
       let documentsDirectory = paths.first!
       return documentsDirectory
   }

   func dataFilePath ()->String{
       return self.documentsDirectory().appendingFormat("/your_file_name_here.plist")
   }

保存数组的功能:

func saveData(_ people:[Person]) {
       let archiver = NSKeyedArchiver(requiringSecureCoding: true)
       archiver.encode(skyBalls, forKey: "your_file_name_here")
       let data = archiver.encodedData
       try! data.write(to: URL(fileURLWithPath: dataFilePath()))
 }

加载数组的功能:

func loadData() -> [Person] {
        let path = self.dataFilePath()
        let defaultManager = FileManager()
        var arr = [Person]()
        if defaultManager.fileExists(atPath: path) {
            let url = URL(fileURLWithPath: path)
            let data = try! Data(contentsOf: url)
            let unarchiver = try! NSKeyedUnarchiver(forReadingFrom: data)

            //Ensure the unarchiver is required to use secure coding
            unarchiver.requiresSecureCoding = true

            //This is where it is important to specify classes that can be decoded:
            unarchiver.setClass(Person.classForCoder(), forClassName: "parentModule.Person")
            let allowedClasses =[NSArray.classForCoder(),Person.classForCoder()]

            //Finally decode the object as an array of your custom class
            arr = unarchiver.decodeObject(of: allowedClasses, forKey: "your_file_name_here") as! [Person]
            unarchiver.finishDecoding()
        }
        return arr
    }

在ViewController类中:

override func viewDidLoad() {
      super.viewDidLoad()

      let testPerson = Person(name: "Bill", gender: "Male", height: 65.5)
      let people:[Person] = [testPerson]

      //Save the array
      saveData(people)

      //Load and print the first index in the array 
      print(loadData()[0].description)
}

输出:

[name=Bill,gender=Male,height=65.5000000]