How to solve deprecation of unarchiveObject(withFile:)

Diskprotek picture Diskprotek · Nov 1, 2018 · Viewed 7.8k times · Source

With iOS 12.1, unarchiveObject(withFile:) was deprecated.
How can you convert NSKeyedUnarchiver.unarchiveObject(withFile: String) to use a call to NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data: Data), or NSKeyedUnarchiver.unarchivedObject(ofClasses: [AnyClass], from: Data), or NSKeyedUnarchiver.unarchivedObject(ofClass: NSCoding.Protocol, from: Data)?

I'm guessing you have to have something like let fileData = try Data(contentsOf: URL) and then use one of those methods to unarchive the data. But, I cannot figure it out and the documentation accompanying the depreciation is not helpful (at least to me).

The archived data is rather simple -- just an array of strings (an array of class NameToBeSaved as defined by this code):

class NameToBeSaved: NSObject, NSCoding {
var name: String

init(userEnteredName: String) {
    self.name = userEnteredName
    super.init()
}

func encode(with aCoder: NSCoder) {
    aCoder.encode(name, forKey: "name")
}

required init?(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    super.init()
}

Here is the code calling unarchiveObject(withFile:) -

init() {
    if let archivedCategoryNames = NSKeyedUnarchiver.unarchiveObject(withFile: categoryNameArchiveURL.path) as? [NameToBeSaved] {
        allCategories += archivedCategoryNames
    } else {
        for category in starterCategories {
            let thisNewCategory = NameToBeSaved(userEnteredName: category)
            createNewCategory(thisNewCategory)
        }
        sortCategories()
    }
}

Answer

Diskprotek picture Diskprotek · Nov 1, 2018

I don't know if this is the best solution, but this solved the conversion for me (old code commented out for comparison):

    init() {

    do {
        let rawdata = try Data(contentsOf: categoryNameArchiveURL)
        if let archivedCategoryNames = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(rawdata) as! [NameToBeSaved]? {
            allCategories += archivedCategoryNames
        }
    } catch {
        print("Couldn't read file")
        for category in starterCategories {
            let thisNewCategory = NameToBeSaved(userEnteredName: category)
            createNewCategory(thisNewCategory)
        }
        sortCategories()
    }

/*        if let archivedCategoryNames = NSKeyedUnarchiver.unarchiveObject(withFile: categoryNameArchiveURL.path) as? [NameToBeSaved] {
            allCategories += archivedCategoryNames
        } else {
            for category in starterCategories {
                let thisNewCategory = NameToBeSaved(userEnteredName: category)
                createNewCategory(thisNewCategory)
            }
            sortCategories()
        }
 */
}