简体   繁体   中英

iOS Swift: Downcasting AnyObject

I know a number of downcasting from Cocoa to Swift questions have been asked and there are some bugs, but I have tried a lot of the methods found here and I cannot get them to work, hoping someone can lend a hand.

I am new to programming. I am making a 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
    }

    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
    }

}

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]

        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 to load the file:

         else {            
            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 I have found listed here on StackOverflow and just cannot do so successfully. This is really frustrating.

Update with the final code:

func createPeoplePlist() {

    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"
        plistpath = pathToFile.stringByAppendingPathComponent(plistfile);

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

            self.createInitialPeople()

            println("Saving to Plist")

            [NSKeyedArchiver.archiveRootObject(peopleArray, toFile: plistpath)]

            println("writing to path \(plistpath)")


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

            peopleArray = NSKeyedUnarchiver.unarchiveObjectWithFile(plistpath) as [Person]



        }
    }


}

Your array still contains NSData when you read it back in (the data you created when archiving it in the first place). However, I would question why you are even putting the data in another array before writing to disk. peopleArray itself can be the root object; there is no need for an extra array wrapping it. Then you can simply use archiveRootObject(_:toFile:) and unarchiveObjectWithFile(_:) .

I would also recommend reading the Archives and Serializations Programming Guide and Property List Programming Guide , and the NSKeyedArchiver docs, for further information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM