BLACK FRIDAY: Save 50% on all our 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
}

   

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.

   

Save 50% in my Black Friday sale.

SAVE 50% This Black Friday all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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.