1

I have the following code. It's been deprecated and gives me that yellow warning. I want that to go away. Any thoughts on how to fix this?

var linearScore = 0
var spreadScore = 0


func saveScores () {
    print("SAVE START")
    let scores : [Int] = [linearScore, spreadScore]
    let encodedData = NSKeyedArchiver.archivedData(withRootObject: scores)
    UserDefaults.standard.set(encodedData, forKey: "scores")
}

func retrieveScores () {
    print("Scores being retrieved")

    //comment out the if/let below to reset goals in dev

    if let data = UserDefaults.standard.data(forKey: "scores"),
        let scoreList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Int] {

        self.linearScore = scoreList[0]
        self.spreadScore = scoreList[1]

        self.updateTopScores()

    } else {
        print("There is an issue")
        self.saveScores()
    }
}

The deprecated code with the error is the following 2 lines:

let encodedData = NSKeyedArchiver.archivedData(withRootObject: scores)

let scoreList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Int] {

Mason Ballowe
  • 1,847
  • 2
  • 12
  • 23

1 Answers1

4

You would need to te new archive and unarchive methods. First make your methods throw and use the following method for archiving:

class func archivedData(withRootObject object: Any, requiringSecureCoding requiresSecureCoding: Bool) throws -> Data

and this for unarchiving:

class func unarchiveTopLevelObjectWithData(_ data: Data) throws -> Any?

Try like this:

func saveScores() throws {
    print(#function)
    let scores = [linearScore, spreadScore]
    let encodedData = try NSKeyedArchiver.archivedData(withRootObject: scores, requiringSecureCoding: false)
    UserDefaults.standard.set(encodedData, forKey: "scores")
}

func retrieveScores() throws {
    print(#function)
    if let data = UserDefaults.standard.data(forKey: "scores"),
        let scoreList = try  NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Int] {
    } else {
        print("There is an issue")
        self.saveScores()
    }
}

Note that you could also just use Codable protocol to encode/decode your model data since Swift 4

var linearScore = 2
var spreadScore = 7

func saveScores() throws  {
    print(#function)
    let scores = [linearScore, spreadScore]
    let encodedData = try JSONEncoder().encode(scores)
    UserDefaults.standard.set(encodedData, forKey: "scores")
    print("scores saved")
}

func retrieveScored() throws {
    print(#function)
    if let data = UserDefaults.standard.data(forKey: "scores") {
        let scoreList = try JSONDecoder().decode([Int].self, from: data)
        print("scoreList:", scoreList)
    } else {
        print("No data found in user defaults for scores")
    }
}

And if you don't want to throw your errors just use the do try catch as needed:

func saveScores() {
    print(#function)
    let scores = [linearScore, spreadScore]
    do {
        try UserDefaults.standard.set(JSONEncoder().encode(scores), forKey: "scores")
        print("scores saved")
    } catch {
        print(error)
    }
}

func retrieveScores() {
    print(#function)
    if let data = UserDefaults.standard.data(forKey: "scores") {
         do {
            let scoreList = try JSONDecoder().decode([Int].self, from: data)
            print("scoreList:", scoreList)
        } catch {
            print(error)
        }

    } else {
        print("No data found in user defaults for scores")
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571