iOS Swift:保存一组自定义类

Nat*_*olz 13 arrays serialization ios swift

我是编程新手.我在swift中为iOS制作了一个小数据库程序.

我有一个人课:

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

    init (firstName : String, lastName : String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}
Run Code Online (Sandbox Code Playgroud)

我在视图控制器的顶部声明了一个类的数组:

    var peopleArray = [Person]()
Run Code Online (Sandbox Code Playgroud)

然后我通过声明一些示例用户填充数组并将其附加到数组:

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

然后我尝试将数据保存到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)")
            }
Run Code Online (Sandbox Code Playgroud)

plist文件未创建,它默默地无法创建,并且函数完成就好了.有什么想法吗?

快速数据类型和数据结构与可可类的模糊兼容性过程令我感到沮丧.我只想保存一个危险文件.如果我将我的数组声明为NSArray,我也不能使用"append"函数,我也不能+ =数组中的项目...

更新:

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

现在保存文件:

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

创建具有不可知数据的Plist文件.

我关闭应用程序并再次启动它,然后尝试加载文件:

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

            let cocoaArray = NSMutableArray.arrayWithContentsOfFile(plistpath)

            peopleArray = cocoaArray as Array
        }
    }
Run Code Online (Sandbox Code Playgroud)

而且我失败了因为我不能贬低"AnyObject与'人'不相同.我曾尝试过以不同方式向下转发它,但却无法成功.这真是令人沮丧.

Kai*_* Xu 12

将以下函数添加到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
}
Run Code Online (Sandbox Code Playgroud)

你应该使用?NSKeyedArchiver?和?NSKeyedUnarchiver?存储和获取数组.

谢谢@Anthony Kong.

他的回答很有帮助,但我认为以下代码可以真正解决问题.

在STAR中存放阵列

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

找到阵列形式的列表

if let tempArr: [Person] = NSKeyedUnarchiver.unarchiveObjectWithFile(arrPath) as? [Person] {
    peopleArray = tempArr
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*ong 11

首先,根本原因[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")
}
Run Code Online (Sandbox Code Playgroud)

2)将数组中的元素转换为NSData例如

   var cocoaArray : NSArray = [NSKeyedArchiver.archivedDataWithRootObject(nateB)]
Run Code Online (Sandbox Code Playgroud)

最后,您还需要在Person类中使用解码函数来支持从plist文件中读取它们