Search code examples
iosswiftpersistencenskeyedarchivernscoder

NSKeyedArchiver returning nil Swift 4.2


 let lessons = Lessons(definition: "testo", photo: url)
 SaveUtil.saveLessons(lessons: lessons!)
 let x = SaveUtil.loadLessons()

So everything compiles and runs but x is nil....I'm trying to make this ios12/swift 4.2 compliant but no idea what is missing. Thank you!

class SaveUtil {
    static func saveLessons(lessons: Lessons) {
        let data = try! NSKeyedArchiver.archivedData(withRootObject: lessons, requiringSecureCoding: false)
        UserDefaults.standard.set(data, forKey: "lessons")
    }

    static func loadLessons() -> [Lessons]?  {

        let data = UserDefaults.standard.data(forKey: "lessons")
        return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data!) as? [Lessons]
    }
}

Solution

  • the loadSession returns a array of Lesson. "as?" will check for type. As the unarchived object was not a array it will return nil. You are archiving it as Lesson Object and unarchiving it as Lesson Array Object.

    static func loadLessons() -> Lessons?  {
    
            let data = UserDefaults.standard.data(forKey: "lessons")
    
            return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data!) as? Lessons
        }
    

    Below is the code that works .

    class Lessons : NSObject,NSCoding {
    
        var definitionText:String
        var photoURL:String
    
        init(definition:String,photoURL:String) {
            self.definitionText = definition
            self.photoURL = photoURL
        }
    
        func encode(with aCoder: NSCoder) {
            aCoder.encode(self.definitionText, forKey: "definitionText")
            aCoder.encode(self.photoURL, forKey: "photoURL")
        }
    
        required convenience init?(coder aDecoder: NSCoder) {
            self.init(definition: "", photoURL: "")
            self.definitionText = aDecoder.decodeObject(forKey: "definitionText") as! String
            self.photoURL = aDecoder.decodeObject(forKey: "photoURL") as! String
        }
    }
    class SaveUtil {
        static func saveLessons(lessons: Lessons) {
    
            let data = NSKeyedArchiver.archivedData(withRootObject: lessons)
            UserDefaults.standard.set(data, forKey: "lessons")
        }
    
        static func loadLessons() -> Lessons?  {
            let data = UserDefaults.standard.data(forKey: "lessons")
            return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data!) as? Lessons
        }
    }
    

    After which you run your code it will return the object.

    let lessons = Lessons(definition: "testo", photoURL: "photo.jpg")
            SaveUtil.saveLessons(lessons: lessons)
            let x = SaveUtil.loadLessons()
            print("\(x?.photoURL)")