0

I have troubles understanding NSKeyedArchiver and NSKeyedUnarchiver in Swift.

This is some example code I have been given to get a picture of its use:

class Workout : NSObject, Coding {
    var name: String!
    var entries: Int = 0

    required convenience init(coder aDecoder: NSCoder) {
        self.init()
        name = aDecoder.decodeObject(forKey: "name") as! String
        entries = aDecoder.decodeInteger(forKey: "entries")
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encode(self.name, forKey: "name")
        aCoder.encode(self.entries, forKey: "entries")
    }
}

let libDir = FileManager.default.urls(for: .libraryDirectory,
                                   in: .userDomainMask)[0]
print(libDir)

let workout = Workout()
workout.entries = 14
workout.name = "Pull-ups"

let path = libDir.appendingPathComponent("workouts")

// Serialisere til disk
if let data = try? NSKeyedArchiver.archivedData(withRootObject: workout, requiringSecureCoding: true) {
    try? data.write(to: path)
}

// Deserialisere fra disk
if let archivedData = try? Data(contentsOf: path),
        let savedWorkout = (try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archivedData)) as? Workout {
    print("\(savedWorkout.name), entries: \(savedWorkout.entries)")
}

I somehow get how NSKeyedArchiver works, but the Workout class in NSKeyedUnarchiver is something i find difficult to understand. What is going on in the class? And when i try to paste the class in a new swift file, I get this error: "Cannot find type 'Coding' in scope".

davidmark
  • 13
  • 4
  • 2
    Sounds like you found this code somewhere online and the author made a typo? `Coding` should be `NSCoding`. What exactly do you not understand? – Sweeper Nov 30 '22 at 18:17
  • Seeing your struct, it might be simpler to use `Codable`. Also, don't use `try?` with a question mark. Prefers using a `do`/`catch` and print possible thrown errors – Larme Nov 30 '22 at 18:27
  • Agreed about avoiding `try?`. That fails silently and returns nil, so you don't know what went wrong. Much better to use try/catch and log any error returned. – Duncan C Nov 30 '22 at 19:11
  • I changed the code to NSCoding, and now the errors have stopped showing up. But nothing is printing in my console. I also want to use do/catch and print possible thrown errors, but I don't know where to add this in the code. I am very new to swift, so any suggestions would be much appreciated. – davidmark Nov 30 '22 at 20:50
  • https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html https://stackoverflow.com/questions/30720497/swift-do-try-catch-syntax etc. – Larme Dec 01 '22 at 09:43

0 Answers0