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.