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.