I'm following the FoodTracker demo at developer apple. I'm on the last section: Persist data.
I'm running Xcode 8, and following the demo building on Swift 3.
If I download the code and convert to Swift 2.3, it doesn't work. If I convert to Swift 3.0 it doesn't work either. I have been trying to follow the demo on Swift 3.
The code requires some changes in order to compile and run on Swift 3, and I have been successful so far.
However, I'm now getting this at runtime:
FoodTracker[1597:720222] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSKeyedArchiver unarchiveObjectWithFile:]: unrecognized selector sent to class 0x1081497a8'
The changes I had do for this section were:
1) On the Meal class I added two static constants:
static let DocumentsDirectory =
FileManager().urls(for: .documentDirectory, in:
.userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.nameKey)
aCoder.encode(photo, forKey: PropertyKey.photoKey)
aCoder.encode(rating, forKey: PropertyKey.ratingKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: PropertyKey.nameKey) as! String
// Because photo is an optional property of Meal, use conditional cast
let photo = aDecoder.decodeObject(forKey: PropertyKey.photoKey) as? UIImage
let rating = aDecoder.decodeInteger(forKey: PropertyKey.ratingKey)
// Must call designated initializer
self.init(name: name, photo: photo, rating: rating)
}
func saveMeals() {
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile: Meal.ArchiveURL.path)
if !isSuccessfulSave {
print("Failed to save meals...")
}
}
func loadMeals() -> [Meal]? {
return NSKeyedArchiver.classForKeyedUnarchiver().unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
5 FoodTracker 0x0000000107ce9e44 _TFC11FoodTracker23MealTableViewController9loadMealsfT_GSqGSaCS_4Meal__ + 276
6 FoodTracker 0x0000000107ce701a _TFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 266
7 FoodTracker 0x0000000107ce7222 _TToFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 34
Use NSKeyedUnarchiver
:
func loadMeals() -> [Meal]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}