NEW: Learn to build the incredible iOS 15 Weather app today! >>

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
}

   

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
    }

1      

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.

   

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS, you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Learn More

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

Reply to this topic…

You need to create an account or log in to reply.

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.