Last active
April 13, 2023 08:10
-
-
Save erezhod/d2dd370399fa0ed39c6402626667be78 to your computer and use it in GitHub Desktop.
Swift `UserDefaults` Persist Property Wrapper with `App Groups` support
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
| import Foundation | |
| enum UserDefaultsGroup: String { | |
| case standard | |
| case shared = "group.com.your.AppGroupName" // For sharing among App Groups | |
| } | |
| @propertyWrapper | |
| struct Persist<T: Codable> { | |
| struct Wrapper<T>: Codable where T: Codable { | |
| let wrapped: T | |
| } | |
| private let userDefaults: UserDefaults | |
| private let key: String | |
| private let group: UserDefaultsGroup | |
| private let defaultValue: T | |
| init(key: String, defaultValue: T, group: UserDefaultsGroup = .standard) { | |
| self.key = key | |
| self.defaultValue = defaultValue | |
| self.group = group | |
| switch group { | |
| case .standard: | |
| userDefaults = .standard | |
| case .shared: | |
| userDefaults = UserDefaults(suiteName: group.rawValue) ?? .standard | |
| } | |
| } | |
| var wrappedValue: T { | |
| get { | |
| guard let data = userDefaults.object(forKey: key) as? Data else { return defaultValue } | |
| let value = try? JSONDecoder().decode(Wrapper<T>.self, from: data) | |
| return value?.wrapped ?? defaultValue | |
| } | |
| set { | |
| do { | |
| let data = try JSONEncoder().encode(Wrapper(wrapped: newValue)) | |
| userDefaults.set(data, forKey: key) | |
| } catch { | |
| // TOOD: You should handle this error how you see fit. | |
| print(error) | |
| } | |
| } | |
| } | |
| } |
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
| import Foundation | |
| final class UserDefaultsStack { | |
| @Persist(key: "didFinishTutorial", defaultValue: false) | |
| var didFinishTutorial: Bool | |
| @Persist(key: "sharedSecretKey", defaultValue: nil, group: .shared) | |
| var sharedSecretKey: String | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment