Home > Enterprise >  Add multiple Structs to one UserDefaults entity
Add multiple Structs to one UserDefaults entity

Time:02-03

I have my UserDefaults like this

fileprivate enum userdefaultKeys: String {
    userSearchHistory = "userSearchHistory",
}

extension UserDefaults {
    static func getUserSearchHistory() -> SearchHistory? {
        let data = self.standard.data(forKey: userdefaultKeys.userSearchHistory.rawValue)
        return SearchHistory.decode(json: data)
    }
    
    static func setUserSearchHistory(userSearchHistory: SearchHistory?) {
        guard let json: Any = userSearchHistory?.json else { return }
        self.standard.set(json, forKey: userdefaultKeys.userSearchHistory.rawValue)
    }
}

And I'm saving this data to the UserDefaults


struct SearchHistory: Codable {
  let type: SearchHistoryEnum
  let name: String
  let corpNo: String
  let storeNo: String
  let long: Double
  let lat: Double
}

enum SearchHistoryEnum: Codable {
  case storeSearch
  case jsonSearch
}


let historySearch = SearchHistory(type: SearchHistoryEnum.storeSearch, name: store?.storename ?? "", corpNo: store?.corpno ?? "", storeNo: store?.storeno ?? "", long: longtitude, lat: latitude)
UserDefaults.setUserSearchHistory(userSearchHistory: historySearch)

This is okay, but it saves only one instance of SearchHistory in the time. I would like to have max 5. When 6th instance comes, I would like to delete the most old one

CodePudding user response:

First of all your enum doesn't compile, you probably mean

fileprivate enum UserdefaultKeys: String {
   case userSearchHistory
}

It's not necessary to specify the raw value.


Second of all I highly recommend not to fight the framework and to conform to the UserDefaults pattern to overload the getter and setter. I don't know your special methods for decoding and encoding, this is a simple implementation with standard JSONDecoder and JSONEncoder

extension UserDefaults {
    func searchHistory(forKey key: String = UserdefaultKeys.userSearchHistory.rawValue) -> SearchHistory? {
        guard let data = data(forKey: key) else { return nil }
        return try? JSONDecoder().decode(SearchHistory.self, from: data)
    }
    
    func searchHistory(forKey key: String = UserdefaultKeys.userSearchHistory.rawValue) -> [SearchHistory]? {
        guard let data = data(forKey: key) else { return nil }
        return try? JSONDecoder().decode([SearchHistory].self, from: data)
    }
    
    func set(_ value: SearchHistory, forKey key: String = UserdefaultKeys.userSearchHistory.rawValue) {
        guard let data = try? JSONEncoder().encode(value) else { return }
        set(data, forKey: key)
    }
    
    func set(_ value: [SearchHistory], forKey key: String = UserdefaultKeys.userSearchHistory.rawValue) {
        guard let data = try? JSONEncoder().encode(value) else { return }
        set(data, forKey: key)
    }
}  

The benefit is the syntax is always the same for a single item or for an array

let historySearch = SearchHistory(type: SearchHistoryEnum.storeSearch, name: store?.storename ?? "", corpNo: store?.corpno ?? "", storeNo: store?.storeno ?? "", long: longtitude, lat: latitude)
UserDefaults.standard.set(historySearch)

or

UserDefaults.standard.set([historySearch])

The code to delete the oldest put in the method to write the data.

  • Related