IOS Swift: сохранение массива пользовательских классов

Я новичок в программировании. Я делаю небольшую программу базы данных для iOS в быстром режиме.

У меня есть класс человека:

class Person : NSObject {
    var firstName : String
    var lastName : String

    init (firstName : String, lastName : String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}

Я объявляю массив класса в верхней части моего контроллера представления:

    var peopleArray = [Person]()

Затем я заполняю массив, объявляя некоторых примерных пользователей и добавляя их в массив:

    var nateB = Person(firstName: "Nate", lastName: "Birkholz")
    var nateC = Person(firstName: "Nate", lastName: "Carson")
    var nateD = Person(firstName: "Nate", lastName: "Donnelly")
    self.peopleArray.append(nateB)
    self.peopleArray.append(nateC)
    self.peopleArray.append(nateD)

Затем я пытаюсь сохранить данные в файле plist:

        let fileManager = (NSFileManager.defaultManager())
        let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

        if (directorys != nil){
            let directories:[String] = directorys!;
            let pathToFile = directories[0]; //documents directory
            let plistfile = "PeopleArray.plist"
            let plistpath = pathToFile.stringByAppendingPathComponent(plistfile);

            if !fileManager.fileExistsAtPath(plistpath){ 

                println("Declaring cocoaArray")
                var cocoaArray : NSArray = peopleArray
                cocoaArray.writeToFile(plistpath, atomically: true)
            println("I wrote an array to the file at\n\n\(plistpath)")
            }

Файл plist не создается, он автоматически не создает и функция завершается так, как если бы она была. Есть предположения?

Неясные процессы совместимости быстрых типов данных и структур данных с классами cocoa расстраивают меня. Я просто хочу сохранить файл danged. Я также не могу использовать функцию "добавить", если я объявляю свой массив как NSArray, и я не могу + элемент в массиве...

Обновление

Я добавил следующие функции в класс Person:

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(firstName, forKey:"firstName")
    aCoder.encodeObject(lastName, forKey:"lastName")
}

init (coder aDecoder: NSCoder!) {
    self.firstName = aDecoder.decodeObjectForKey("firstName") as String
    self.lastName = aDecoder.decodeObjectForKey("lasName") as String
}

Сохранение файла:

let fileManager = (NSFileManager.defaultManager())
        let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

        println("value of directorys is \(directorys)")

        if (directorys != nil){
            let directories:[String] = directorys!;
            let pathToFile = directories[0]; //documents directory

            let plistfile = "PeopleArray.plist"
            let plistpath = pathToFile.stringByAppendingPathComponent(plistfile);

            if !fileManager.fileExistsAtPath(plistpath){  //writing Plist file

                self.createInitialPeople()

                println("Declaring cocoaArray")
                var cocoaArray : NSArray = [NSKeyedArchiver.archivedDataWithRootObject(peopleArray)]
                println("writing to path")
                cocoaArray.writeToFile(plistpath, atomically: true)
                let tellMe = cocoaArray.writeToFile(plistpath, atomically: true)
                println("Return of write is \(tellMe)")
            } 

Создается файл Plist с непостижимыми данными.

Я закрою приложение и запустил его снова, затем попробую загрузить файл:

         else {            //Reading Plist file
            println("\n\nPlist file found at \(plistpath)")

            let cocoaArray = NSMutableArray.arrayWithContentsOfFile(plistpath)

            peopleArray = cocoaArray as Array
        }
    }

И я терпеть неудачу, потому что я не могу упустить "AnyObject не идентичен" Person ". Я попытался уменьшить его несколькими способами и просто не могу сделать это успешно. Это действительно расстраивает.

Ответ 1

Прежде всего, основная причина [NSArray writeToFile:atomically:] поддерживает только определенные типы данных. Вы можете проверить документацию здесь.

Если вы распечатаете код возврата из cocoaArray.writeToFile(plistpath, atomically: true), вы увидите, что он установлен на False.

Чтобы преодолеть это ограничение, вам нужно

1) реализовать функцию кодирования в классе Person

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(firstName, forKey:"firstName")
    aCoder.encodeObject(lastName, forKey:"lastName")
}

2) Преобразуйте элементы в массив в NSData, например.

   var cocoaArray : NSArray = [NSKeyedArchiver.archivedDataWithRootObject(nateB)]

В конце вам также понадобится функция декодирования в классе Person для поддержки их чтения из файла plist

Ответ 2

После того, как вы добавили в свой класс Person следующие функции:

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(firstName, forKey:"firstName")
    aCoder.encodeObject(lastName, forKey:"lastName")
}


init (coder aDecoder: NSCoder!) {
    self.firstName = aDecoder.decodeObjectForKey("firstName") as String
    self.lastName = aDecoder.decodeObjectForKey("lasName") as String
}

Вы должны использовать 【NSKeyedArchiver】 и 【NSKeyedUnarchiver】 для хранения и выборки массива.

Спасибо @Энтони Конг.

Его ответ очень помогает, но я думаю, что следующие коды действительно могут решить проблему.

ЗАПУСК МАССЫ В ПЛИТЕ

let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true)
let path: AnyObject = paths[0]
let arrPath = path.stringByAppendingString("/array.plist")
NSKeyedArchiver.archiveRootObject(peopleArray, toFile: arrPath)

ДЛЯ ОБРАБОТКИ ПЛАТЫ МАССОВОЙ ФОРМЫ

if let tempArr: [Person] = NSKeyedUnarchiver.unarchiveObjectWithFile(arrPath) as? [Person] {
    peopleArray = tempArr
}