WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: Save [Int:Int] to UserDefaults

Forums > Swift

What is a best practices approach to saving a dictionary of Int:Int values to UserDefaults? There are various pieces of the parent that need updating conditionally and they are referenced by index and given a value. There are potentially multiple parent objects, so the mapping in UserDefaults needs to be keyed to the unique ID of the parent. Here is what I've come up with, but seems like there should be a more straight forward way to save/retrieve [Int:Int] from UserDefaults.

func saveIntDictionary(parentID: Int, intDictionary: [Int:Int]) {

   // create the UserDefaults key for this parent ID
   let parentItemKey: String = "\(parentID)_KEY"

   // Dictionary to store Int dictionary in UserDefaults
   var stringValuesToSave: [String:String] = [:]

   // populate [String:String] dictionary from [Int:Int] dictionary
   for key in intDictionary.keys {
      let valueToStore = intDictionary[key]!

      let keyStr: String = String(key)
      let valueStr: String = String(valueToStore)

      stringValuesToSave[keyStr] = valueStr
   }

   // save converted dictionary to UserDefaults
   UserDefaults.standard.setValue(stringValuesToSave, forKeyPath: parentItemKey)

}

func retrieveSavedIntDictionary(parentID: Int) -> [Int:Int] {

   // create the UserDefaults key for this parent ID
   let parentItemKey: String = "\(parentID)_KEY"

   // retrieve dictionary from UserDefaults
   let savedStringValues: [String:String] = UserDefaults.standard.object(forKey: parentItemKey) as? [String : String] ?? [String:String]()

   // Int dictionary to hold values to return
   var convertedIntDictionary:[Int:Int] = [:]

   // populate [Int:Int] dictionary from String:String dictionary
   for key in savedStringValues.keys {
      let keyInt: Int = Int(key)!
      let value: String = savedStringValues[key]!
      convertedIntDictionary[keyInt] = Int(value)
   }

   // return Int dictionary
   return convertedIntDictionary
}

1      

You can convert your [Int:Int] dictionary into a property list object and store it into UserDefaults.

    func saveIntDictionary(parentID: Int, intDictionary: [Int:Int]) {
        let parentItemKey = "\(parentID)_KEY"

        let encoder = PropertyListEncoder()

        guard let data = try? encoder.encode(intDictionary) else {
            return
        }

        UserDefaults.standard.set(data, forKey: parentItemKey)
    }

    func retrieveSavedIntDictionary(parentID: Int) -> [Int:Int] {
        let parentItemKey = "\(parentID)_KEY"

        let decoder = PropertyListDecoder()

        guard let data = UserDefaults.standard.data(forKey: parentItemKey),
              let intDictionary = try? decoder.decode([Int:Int].self, from: data) else {
            return [:]
        }

        return intDictionary
    }

2      

Thaks @roosterboy - that is exactly what I needed. Knew I could write my own object as Codable, but knew there had to be a more straight forward solution. Cheers and have a great weekend.

1      

Hacking with Swift is sponsored by Emerge

SPONSORED Optimize your app’s startup time, binary size, and overall performance using Emerge’s advanced app optimization and monitoring tools. Reliably measure app size, speed up your app's startup time with Emerge's Launch Booster, and much more. Emerge is actively used by many of the top mobile development teams in the world.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.