I'm new to swift and was trying to teach myself data persistence using Apple's "App Development with Swift" iBook. I'm trying to create and store an array of students that I can then recall later on. The issue is, when I try to reload them, the array is empty. I really can't understand what's wrong since I get no errors, just an empty array. This is what I see when I run the code. Can someone please show me what I'm doing wrong? Any help is appreciated but it may need to be dumbed down for me. Cheers.
import Foundation
class Student: NSObject, NSCoding {
var idNumber: String
var forename: String
var surname: String
var homeAddress: String
var postcode: String
var homePhone: String
var gender: String
var tutorGroup: String
var schoolEmail: String
var dateOfBirth: String
// property key strings are used for en and de coding later
struct PropertyKey {
static let idNumber = "idNumber"
static let forename = "forename"
static let surname = "surname"
static let homeAddress = "homeAddress"
static let postcode = "postcode"
static let homePhone = "homePhone"
static let gender = "gender"
static let tutorGroup = "tutorGroup"
static let schoolEmail = "schoolEmail"
static let dateOfBirth = "dateOfBirth"
}
static let DocumentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("students")
init(idNumber: String, forename: String, surname: String,
homeAddress: String, postcode: String, homePhone: String,
gender: String, tutorGroup: String, schoolEmail: String,
dateOfBirth: String) {
self.idNumber = idNumber
self.forename = forename
self.surname = surname
self.homeAddress = homeAddress
self.postcode = postcode
self.homePhone = homePhone
self.gender = gender
self.tutorGroup = tutorGroup
self.schoolEmail = schoolEmail
self.dateOfBirth = dateOfBirth
}
static func loadFromFile() -> [Student] {
return NSKeyedUnarchiver.unarchiveObject(withFile: Student.ArchiveURL.path) as! [Student]
}
static func loadSampleStudents() -> [Student] {
return [
Student(idNumber: "13LDL", forename: "Dean", surname: "Lobo", homeAddress: "Neverland", postcode: "Far away", homePhone: "11111111", gender: "male", tutorGroup: "11L", schoolEmail: "[email protected]", dateOfBirth: "02/03/04"),
Student(idNumber: "14LSD", forename: "Harry", surname: "Harrison", homeAddress: "21 Bushey Mill Lane", postcode: "WD23 2DD", homePhone: "01923218324", gender: "male", tutorGroup: "11L", schoolEmail: "[email protected]", dateOfBirth: "02/03/05"),
Student(idNumber: "11LSA", forename: "Stefan", surname: "Stephens", homeAddress: "Somewhere near school", postcode: "SA12 2WP", homePhone: "01923123123", gender: "male", tutorGroup: "11L", schoolEmail: "[email protected]", dateOfBirth: "08/03/01"),
Student(idNumber: "11LPJ", forename: "Penny", surname: "Pennyworth", homeAddress: "12 Downing Street", postcode: "W1 12AP", homePhone: "0192311111", gender: "female", tutorGroup: "11L", schoolEmail: "[email protected]", dateOfBirth: "08/03/02"),
]
}
static func saveToFile(students: [Student]) {
NSKeyedArchiver.archiveRootObject(students, toFile: Student.ArchiveURL.path)
}
required convenience init?(coder aDecoder: NSCoder) {
guard let idNumber = aDecoder.decodeObject(forKey: PropertyKey.idNumber) as? String,
let forename = aDecoder.decodeObject(forKey: PropertyKey.forename) as? String,
let surname = aDecoder.decodeObject(forKey: PropertyKey.surname) as? String,
let homeAddress = aDecoder.decodeObject(forKey: PropertyKey.homeAddress) as? String,
let postcode = aDecoder.decodeObject(forKey: PropertyKey.postcode) as? String,
let homePhone = aDecoder.decodeObject(forKey: PropertyKey.homePhone) as? String,
let gender = aDecoder.decodeObject(forKey: PropertyKey.gender) as? String,
let tutorGroup = aDecoder.decodeObject(forKey: PropertyKey.tutorGroup) as? String,
let schoolEmail = aDecoder.decodeObject(forKey: PropertyKey.schoolEmail) as? String,
let dateOfBirth = aDecoder.decodeObject(forKey: PropertyKey.dateOfBirth) as? String
else {
return nil
}
self.init(idNumber: idNumber,
forename: forename,
surname: surname,
homeAddress: homeAddress,
postcode: postcode,
homePhone: homePhone,
gender: gender,
tutorGroup: tutorGroup,
schoolEmail: schoolEmail,
dateOfBirth: dateOfBirth
)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(idNumber, forKey: PropertyKey.idNumber)
aCoder.encode(forename, forKey: PropertyKey.forename)
aCoder.encode(surname, forKey: PropertyKey.surname)
aCoder.encode(homeAddress, forKey: PropertyKey.homeAddress)
aCoder.encode(postcode, forKey: PropertyKey.postcode)
aCoder.encode(homePhone, forKey: PropertyKey.homePhone)
aCoder.encode(gender, forKey: PropertyKey.gender)
aCoder.encode(tutorGroup, forKey: tutorGroup)
aCoder.encode(schoolEmail, forKey: PropertyKey.schoolEmail)
aCoder.encode(dateOfBirth, forKey: PropertyKey.dateOfBirth)
}
}
var students: [Student] = Student.loadSampleStudents()
print(students)
Student.saveToFile(students: students)
print("Student's were saved")
var reloadedStudents: [Student] = Student.loadFromFile()
print("student's were reloaded")
print(reloadedStudents)
A really simple error, with an easy fix. This line
aCoder.encode(tutorGroup, forKey: tutorGroup)
needs to be replaced with:So it should look like this:
I just discovered this by setting breakpoints (inside the
guard else
closure).