ios - NSKeyedUnarchiver returns nil - Could not cast value of type 'MyProj.Meal' (0x105373f68) to 'MyProj.Meal' (0x11f5ee928) -
i'm trying hang of archiving objects. i'm following apple's example project persistence here: https://developer.apple.com/library/content/referencelibrary/gettingstarted/developiosappsswift/persistdata.html
basically there's meal class conforms nscoding protocol. when run tests archive/unarchive meal object, following error:
could not cast value of type 'myproj.meal' (0x105373f68) 'myproj.meal' (0x11f5ee928)
here's code produces error; error on third line:
let meal = meal(name: "food", photo: nil, rating: 4)! let data = nskeyedarchiver.archiveddata(withrootobject: meal) let unarchivedmeal = nskeyedunarchiver.unarchiveobject(with: data) as! meal xctassertnotnil(unarchivedmeal)
and here's meal class apple:
// // meal.swift // foodtracker // // created jane appleseed on 11/10/16. // copyright © 2016 apple inc. rights reserved. // import uikit import os.log class meal: nsobject, nscoding { //mark: properties var name: string var photo: uiimage? var rating: int //mark: archiving paths static let documentsdirectory = filemanager().urls(for: .documentdirectory, in: .userdomainmask).first! static let archiveurl = documentsdirectory.appendingpathcomponent("meals") //mark: types struct propertykey { static let name = "name" static let photo = "photo" static let rating = "rating" } //mark: initialization init?(name: string, photo: uiimage?, rating: int) { // name must not empty guard !name.isempty else { return nil } // rating must between 0 , 5 inclusively guard (rating >= 0) && (rating <= 5) else { return nil } // initialization should fail if there no name or if rating negative. if name.isempty || rating < 0 { return nil } // initialize stored properties. self.name = name self.photo = photo self.rating = rating } //mark: nscoding func encode(with acoder: nscoder) { acoder.encode(name, forkey: propertykey.name) acoder.encode(photo, forkey: propertykey.photo) acoder.encode(rating, forkey: propertykey.rating) } required convenience init?(coder adecoder: nscoder) { // name required. if cannot decode name string, initializer should fail. guard let name = adecoder.decodeobject(forkey: propertykey.name) as? string else { debugprint("unable decode name meal object.") return nil } // because photo optional property of meal, use conditional cast. let photo = adecoder.decodeobject(forkey: propertykey.photo) as? uiimage let rating = adecoder.decodeinteger(forkey: propertykey.rating) // must call designated initializer. self.init(name: name, photo: photo, rating: rating) } }
any ideas? frustrating
Comments
Post a Comment