iOS版雨燕:保存自定义类的数组 [英] iOS Swift: saving an array of custom classes

查看:146
本文介绍了iOS版雨燕:保存自定义类的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来编程。我在做迅速一个小数据库程序适用于iOS。

我有一个Person类:

 类Person:NSObject的{
    VAR姓:字符串
    VAR名字:字符串    的init(姓:字符串,名字:字符串){
        self.firstName =名字
        self.lastName = lastName的
    }
}

我在视图控制器的顶部声明类的数组

  VAR peopleArray = [人]()

然后我通过声明一些样本用户填写的阵列,并追加到数组:

  VAR nateB =人(姓:内特,名字:Birkholz)
    VAR NATEC =人(姓:内特,名字:卡森)
    NAT的变种人=(姓:内特,名字:唐纳利)
    self.peopleArray.append(nateB)
    self.peopleArray.append(NATEC)
    self.peopleArray.append(经过NAT)

然后我尝试将数据保存到一个plist文件:

 让文件管理器=(NSFileManager.defaultManager())
        让directorys:[字符串]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask,真)作为? [串]        如果(directorys!=无){
            让目录:[字符串] = directorys !;
            让pathToFile =目录[0]; //文件目录
            让plistfile =PeopleArray.plist
            让plistpath = pathToFile.stringByAppendingPathComponent(plistfile);            如果!fileManager.fileExistsAtPath(plistpath){                的println(声明cocoaArray)
                VAR cocoaArray:NSArray的= peopleArray
                cocoaArray.writeToFile(plistpath,原子:真)
            的println(我写一个数组到该文件在\\ n \\ n \\(plistpath))
            }

不是创建plist文件,它静静地失败创建和功能完成,如果它了。有什么想法吗?

迅速的数据类型和数据结构与可可类的晦涩兼容性过程是令人沮丧的我。我只是想保存danged文件。我也是,如果我声明我数组作为一个NSArray不能使用追加功能,也不能I + =一个项目到数组...

更新

我增加了以下功能到我的Person类:

  FUNC EN codeWith codeR(A codeR:NS codeR!){
    一个coder.en codeObject的(名字,forKey:名字)
    一个coder.en codeObject的(姓氏,forKey:姓氏)
}的init(codeR ADE codeR:NS codeR!){
    self.firstName = ADE coder.de codeObjectForKey(名字)作为字符串
    self.lastName = ADE coder.de codeObjectForKey(lasName)作为字符串
}

保存文件现在是:

 让文件管理器=(NSFileManager.defaultManager())
        让directorys:[字符串]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask,真)作为? [串]        的println(directorys的值是\\(directorys))        如果(directorys!=无){
            让目录:[字符串] = directorys !;
            让pathToFile =目录[0]; //文件目录            让plistfile =PeopleArray.plist
            让plistpath = pathToFile.stringByAppendingPathComponent(plistfile);            如果!fileManager.fileExistsAtPath(plistpath){//写入plist文件                self.createInitialPeople()                的println(声明cocoaArray)
                VAR cocoaArray:NSArray的= [NSKeyedArchiver.archivedDataWithRootObject(peopleArray)
                的println(写入路径)
                cocoaArray.writeToFile(plistpath,原子:真)
                让Tellme公司= cocoaArray.writeToFile(plistpath,原子:真)
                的println(写的回报是\\(Tellme公司))
            }

与高深莫测的数据的plist文件被创建。

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

 其他{//读取plist文件
            的println(\\ n \\ nPlist在\\(plistpath找到文件))            让cocoaArray = NSMutableArray.arrayWithContentsOfFile(plistpath)            peopleArray = cocoaArray为阵
        }
    }

和我失败了,因为我不能垂头丧气AnyObject是不相同的'人'。我曾尝试通过多种方式向下转换它,只是不能这样做成功,这是很无奈。


解决方案

首先,根本原因是 [NSArray的将writeToFile:原子:] 仅支持某些数据类型。您可以查看文档<一个href=\"https://developer.apple.com/library/ios/documentation/cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html#jumpTo_70\">here.

如果您打印输出返回code cocoaArray.writeToFile(plistpath,原子:真),你会看到它设置为

要克服这个限制,需要

1)实现你的类连接code函数

  FUNC EN codeWith codeR(A codeR:NS codeR!){
    一个coder.en codeObject的(名字,forKey:名字)
    一个coder.en codeObject的(姓氏,forKey:姓氏)
}

2)转换您的数组中的元素融入到的NSData ,例如

  VAR cocoaArray:NSArray的= [NSKeyedArchiver.archivedDataWithRootObject(nateB)

最后,您还需要在类的去code功能,支持从plist文件中读取他们回来

I am new to programming. I am making a little database program for iOS in swift.

I have a person class:

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

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

I declare an array of the class at the top of my view controller:

    var peopleArray = [Person]()

I then fill the array by declaring some sample users and append it to the array:

    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)

I then try to save the data to a plist file:

        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)")
            }

The plist file isn't created, it silently fails to create and the function completes as if it had. Any thoughts?

The obscure compatibility processes of the swift data types and data structures with the cocoa classes is frustrating to me. I just want to save a danged file. I also can't use the "append" function if I declare my array as an NSArray, nor can I += an item into the array...

Update:

I added the following functions to my Person class:

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
}

Saving the file is now:

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)")
            } 

A Plist file with inscrutable data is created.

I close the app and start it again, i then try too load the file:

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

            let cocoaArray = NSMutableArray.arrayWithContentsOfFile(plistpath)

            peopleArray = cocoaArray as Array
        }
    }

And I fail because I cannot downcast "AnyObject is not identical to 'Person'. I have tried downcasting it in several ways and just cannot do so successfully. This is really frustrating.

解决方案

First of all, the root cause is [NSArray writeToFile:atomically:] only supports certain data types. You can check the documentation here.

If you print out the return code from cocoaArray.writeToFile(plistpath, atomically: true), you will see it is set to False.

To overcome this restriction, you need to

1) implement a encode function in your Person class

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

2) Convert the elements in your array into NSData, e.g.

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

At the end, you will also need a decode function in the Person class to support reading them back from a plist file

这篇关于iOS版雨燕:保存自定义类的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆