Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSKeyedUnarchiver.unarchivedObject returning nil for dictionary

I am trying to update my code to iOS12. Below is my code:

class CurrentGameState: NSObject, NSSecureCoding {

static var supportsSecureCoding: Bool = true
var currentTest1 = Int()
var currentUnitPositionColumn = [String: Int]()
static var currentGameStatus = CurrentGameState(unit: "init", test: 1, column: -1)
var currentTest1 = Int()
var currentUnitPositionColumn = [String: Int]()

init(unit: String, test: Int, column: Int) {

    currentTest1 = test
    currentUnitPositionColumn[unit] = column
}
func encode(with aCoder: NSCoder) {

    aCoder.encode(currentTest1, forKey: test1)
    aCoder.encode(currentUnitPositionColumn, forKey: currentColumn)
}

required init(coder aDecoder: NSCoder) {

    self.currentTest1 = aDecoder.decodeInteger(forKey: test1)
    self.currentUnitPositionColumn = aDecoder.decodeObject(forKey: currentColumn) as! [String : Int]
}

extension PersistData {
func newSaveMatchInfo(saveType: GlobalConstants.saveType) {

    let gameDataFile = "GameData" + String(describing: saveType)
    if let url = getFileURLInAppDocumentDirectory(fileName: gameDataFile) {

        do{

            let archive = try NSKeyedArchiver.archivedData(withRootObject: CurrentGameState.currentGameStatus, requiringSecureCoding: true)
            try archive.write(to: url)

        }catch{
            print("!!!!!Error saving Game data == \(error)")
        }
    }
}

func newLoadMatchInfo(saveType: GlobalConstants.saveType) {

    let gameDataFile = "GameData" + String(describing: saveType)

    guard let gameData = try? Data(contentsOf: getFileURLInAppDocumentDirectory(fileName: gameDataFile)!),
        let gameInfo = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [CurrentGameState.self], from: gameData as Data ) else {

            print("!!!!!Error gameInfo = try? NSKeyedUnarchiver.unarchivedObject failed ")
            return
    }

    CurrentGameState.currentGameStatus = gameInfo as! 
}
}

When I run this code, the NSKeyedUnarchiver works for the Int currentTest1, but returns nil when it hits the dictionary currentUnitPositionColumn. The old code shown below for the NSKeyedUnarchiver works fine, but unarchiveObject(withFile: is deprecated in iOS12.

func loadMatchInfo(saveType: GlobalConstants.saveType) {
    let gameDataFile = "GameData" + String(describing: saveType)
    if let url = getFileURLInAppDocumentDirectory(fileName: gameDataFile) {
        if let gameData = NSKeyedUnarchiver.unarchiveObject(withFile: url.path) as? CurrentGameState {
            CurrentGameState.currentGameStatus = gameData
        }
    }
}

There is something about the Dictionary that will not work with my new code. Any help would be greatly appreciated.

like image 566
Delph2 Avatar asked Mar 05 '23 07:03

Delph2


1 Answers

Your code works fine if you replace:

let gameInfo = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [CurrentGameState.self], from: gameData as Data ) else {

with:

let gameInfo = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(gameData) else {

I suspect it fails using unarchivedObject(ofClasses: because you can't list Dictionary<String, Int>.

like image 147
rmaddy Avatar answered May 13 '23 00:05

rmaddy