Last active
February 5, 2024 17:19
-
-
Save amrangry/6920e74fc50bad3e2f2c213a28403b5f to your computer and use it in GitHub Desktop.
UserDefaultsManager is a manager and wrapper class for UserDefaults
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UserDefaultsManager.swift | |
// Www.ADKATech.com | |
// | |
// Created by AmrAngry on 7/30/19. | |
// Modifyed by AmrAngry on 5/5/20. | |
// Copyright © 2019 Www.ADKATech.com. All rights reserved. | |
// Generic use original mestion by (FB)محمود زكى and hamada147(Github) | |
import Foundation | |
/* | |
//How to use | |
UserDefaultsManager.shared.set(true, forKey: .admin) | |
let isAdminEnable = UserDefaultsManager.shared.get(objectForkey: .admin, type: Bool.self) | |
print(isAdminEnable) | |
UserDefaultsManager.shared.purge() | |
print(UserDefaultsManager.shared.get(objectForkey: .admin, type: Bool.self)) | |
*/ | |
/// UserDefaultsManager is a manager and wrapper class for UserDefaults that use for persistance key-value store, optimized for storing user settings. | |
/// Key-Value Store: NSUserDefaults stores Property List objects (NSString, NSData, NSNumber, NSDate, NSArray, and NSDictionary) identified by NSString keys, similar to an NSMutableDictionary. | |
/// Optimized for storing user settings: NSUserDefaults is intended for relatively small amounts of data, queried very frequently, and modified occasionally. Using it in other ways may be slow or use more memory than solutions more suited to those uses. | |
class UserDefaultsManager: NSObject { | |
/// static shared instance Initializes of `self` with default strategies. | |
static let shared = UserDefaultsManager() | |
let userDefaults: UserDefaults? | |
/// Initializes private`self` with default strategies. | |
private override init() { | |
userDefaults = UserDefaults.standard | |
} | |
/// -removeObjectForKey: is equivalent to -[... setObject:nil forKey:defaultName] | |
func remove(for key: UserDefaultsKeys) { | |
userDefaults?.removeObject(forKey: key.value) | |
} | |
func purge() { | |
let keys = UserDefaultsKeys.allCases//UserDefaultsKeys.reteriveAllCases() | |
keys.forEach { | |
let excluded = UserDefaultsKeys.excludedCases.contains($0) | |
if excluded { | |
print("excluded case:\($0.value)") | |
} else { | |
remove(for: $0) | |
} | |
} | |
//KeyChainWrapper.share.deletePassword() | |
} | |
} | |
extension UserDefaultsManager { | |
/// set value:forKey: immediately stores a value (or removes the value if nil is passed as the value) for the provided key in the search list entry for the receiver's suite name in the current user and any host, then asynchronously stores the value persistently, where it is made available to other processes. | |
/// - Parameters: | |
/// - value: value of any Object confirm to Encodable Protocol | |
/// - key: String value assocaited with stored object | |
func set<T>(_ value: T?, forKey key: UserDefaultsKeys) where T: Encodable { | |
guard let tempValue = value else { | |
userDefaults?.set(nil, forKey: key.value) | |
return | |
} | |
let jsonEncoder = JSONEncoder() | |
guard let jsonData = try? jsonEncoder.encode(tempValue) else { | |
userDefaults?.set(nil, forKey: key.value) | |
return | |
} | |
let json = String(data: jsonData, encoding: .utf8) | |
userDefaults?.set(json, forKey: key.value) | |
} | |
/// Retrive Object assocaited with key | |
/// - Parameters: | |
/// - key: UserDefaultsKeys value that use to store value as reference | |
/// - type: Type of object that conform Decodable Protocol | |
func get<T: Decodable>(objectForkey key: UserDefaultsKeys, type: T.Type) -> T? { | |
let jsonString = getObject(key.value) as? String | |
let jsonData = jsonString?.data(using: .utf8) | |
let decoder = JSONDecoder() | |
return try? decoder.decode(type, from: jsonData ?? Data()) | |
} | |
/** | |
-set bool:forKey: immediately stores a value for the provided key in the search list entry for the receiver's suite name in the current user and any host, then asynchronously stores the value persistently, where it is made available to other processes. | |
*/ | |
func set(bool: Bool, for key: UserDefaultsKeys) { | |
userDefaults?.set(bool, forKey: key.value) | |
} | |
/// Retrive Bool assocaited with key | |
/// - Parameter key: UserDefaultsKeys enum | |
func get(for key: UserDefaultsKeys) -> Bool? { | |
let result = userDefaults?.bool(forKey: key.value) | |
return result | |
} | |
} | |
extension UserDefaultsManager { | |
/// Retrive Object assocaited with key | |
/// - Parameter key: UserDefaultsKeys value that use to store value as reference | |
private func getObject(_ key: String) -> Any? { | |
return userDefaults?.object(forKey: key) | |
} | |
} | |
enum UserDefaultsKeys: String, CaseIterable { | |
case currentLoggedinBranch = "currentLoggedinBranch" | |
case username = "login" | |
case locationCode = "location_code" | |
case companyName = "company name" | |
case companyID = "Current company id" | |
case lastLoginDate = "lastLoginDate" | |
case vat = "VAT" | |
case vatPercentage = "vatperc" | |
case admin | |
case serialNumber | |
case redeamEnabled | |
case issueEnabled | |
// no need to purge | |
case merchantID | |
case merchantName | |
case lastUpdateNotification | |
case theme = "Theme" | |
case ipAddress = "ip" | |
case voidKey = "void" | |
// Helper | |
static var excludedCases: [UserDefaultsKeys] = [ .voidKey, .ipAddress, .merchantID, .merchantName, .lastUpdateNotification, .theme] | |
var value : String { | |
return self.rawValue | |
} | |
} |
// Genaric is much easier to handle in code func set<T>(_ obj: T, for key: UserDefaultsKey) { self.userDefaults?.set(object, forKey: key.value) self.userDefaults?.synchronize() } // Genaric is much easier to handle in code func get<T>(for key: UserDefaultsKey) -> T? { let result = self.userDefaults?.object(forKey: key.value) as? T return result }
I agree with you, thanks for your suggestion, ima going to modify and posted here again
There may be a small typo that has been overlooked.
self.userDefaults?.set(object, forKey: key.value)
to
self.userDefaults?.set(obj, forKey: key.value)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm personally a huge fan of generic so I had to add it