77//
88
99import Foundation
10+ import MullvadLogging
1011
1112@propertyWrapper
12- public struct AppStorage < Value: Codable > {
13+ public struct PrimitiveStorage < Value: UserDefaultsPrimitive > {
1314 let key : String
1415 let defaultValue : Value
1516 let container : UserDefaults
1617
1718 public var wrappedValue : Value {
1819 get {
19- guard
20- let data = container. data ( forKey: key) ,
21- let value = try ? JSONDecoder ( ) . decode ( Value . self, from: data)
20+ container. value ( forKey: key) as? Value ?? defaultValue
21+ }
22+ set {
23+ if let anyOptional = newValue as? AnyOptional ,
24+ anyOptional. isNil
25+ {
26+ container. removeObject ( forKey: key)
27+ } else {
28+ container. set ( newValue, forKey: key)
29+ }
30+ }
31+ }
32+
33+ public init ( wrappedValue: Value , key: String , container: UserDefaults ) {
34+ self . defaultValue = wrappedValue
35+ self . container = container
36+ self . key = key
37+ }
38+ }
39+
40+ @propertyWrapper
41+ public struct CompositeStorage < Value: Codable > {
42+ let logger = Logger ( label: " CompositeStorage " )
43+ private let key : String
44+ private let defaultValue : Value
45+ private let container : UserDefaults
46+
47+ public var wrappedValue : Value {
48+ get {
49+ guard let data = container. data ( forKey: key) ,
50+ let decoded = try ? JSONDecoder ( ) . decode ( Value . self, from: data)
2251 else {
2352 return container. value ( forKey: key) as? Value ?? defaultValue
2453 }
25- return value
54+ return decoded
2655 }
2756 set {
28- if let data = try ? JSONEncoder ( ) . encode ( newValue) {
57+ do {
58+ let data = try JSONEncoder ( ) . encode ( newValue)
2959 container. set ( data, forKey: key)
30- } else {
31- container . removeObject ( forKey : key )
60+ } catch {
61+ logger . error ( " Failed to encode \( Value . self ) " )
3262 }
3363 }
3464 }
@@ -47,3 +77,12 @@ protocol AnyOptional {
4777extension Optional : AnyOptional {
4878 var isNil : Bool { self == nil }
4979}
80+
81+ public protocol UserDefaultsPrimitive { }
82+ extension String : UserDefaultsPrimitive { }
83+ extension Int : UserDefaultsPrimitive { }
84+ extension Bool : UserDefaultsPrimitive { }
85+ extension Double : UserDefaultsPrimitive { }
86+ extension Data : UserDefaultsPrimitive { }
87+ extension Array : UserDefaultsPrimitive where Element: UserDefaultsPrimitive { }
88+ extension Dictionary : UserDefaultsPrimitive where Key == String , Value: UserDefaultsPrimitive { }
0 commit comments