@@ -64,47 +64,99 @@ class IterableKeychain {
64
64
}
65
65
66
66
func getLastPushPayload( currentDate: Date ) -> [ AnyHashable : Any ] ? {
67
- if isLastPushPayloadExpired ( currentDate: currentDate) {
68
- wrapper. removeValue ( forKey: Const . Keychain. Key. lastPushPayload)
69
- wrapper. removeValue ( forKey: Const . Keychain. Key. lastPushPayloadExpiration)
70
-
67
+ guard let payloadExpirationPair = getPayloadExpirationPairFromKeychain ( ) else {
71
68
return nil
72
69
}
73
70
74
- if let data = wrapper. data ( forKey: Const . Keychain. Key. lastPushPayload) {
75
- return ( try ? JSONSerialization . jsonObject ( with: data) ) as? [ AnyHashable : Any ]
71
+ if isLastPushPayloadExpired ( expiration: payloadExpirationPair. expiration, currentDate: currentDate) {
72
+ removePayloadExpirationPairFromKeychain ( )
73
+ return nil
76
74
}
77
75
78
- return nil
76
+ return decodeJsonPayload ( payloadExpirationPair . payload )
79
77
}
80
78
81
79
func setLastPushPayload( _ payload: [ AnyHashable : Any ] ? , withExpiration expiration: Date ? ) {
82
- // save expiration here
83
-
84
- guard let value = payload? . jsonValue, JSONSerialization . isValidJSONObject ( value) else {
85
- wrapper. removeValue ( forKey: Const . Keychain. Key. lastPushPayload)
80
+ guard let payload = payload, JSONSerialization . isValidJSONObject ( payload) else {
81
+ removePayloadExpirationPairFromKeychain ( )
86
82
return
87
83
}
88
84
89
- do {
90
- let data = try JSONSerialization . data ( withJSONObject: value, options: [ ] )
91
- wrapper. set ( data, forKey: Const . Keychain. Key. lastPushPayload)
92
- } catch {
93
- wrapper. removeValue ( forKey: Const . Keychain. Key. lastPushPayload)
94
- }
85
+ savePayloadExpirationPairToKeychain ( payload: payload, expiration: expiration)
95
86
}
96
87
97
88
// MARK: - PRIVATE/INTERNAL
98
89
99
90
private let wrapper : KeychainWrapper
100
91
101
- private func isLastPushPayloadExpired( currentDate: Date ) -> Bool {
102
- // get expiration here
92
+ private func getPayloadExpirationPairFromKeychain( ) -> ( payload: Data , expiration: Date ? ) ? {
93
+ // get the value from the keychain
94
+ guard let keychainValue = wrapper. data ( forKey: Const . Keychain. Key. lastPushPayloadAndExpiration) else {
95
+ return nil
96
+ }
97
+
98
+ // decode the payload/expiration pair
99
+ guard let payloadExpirationPair = try ? JSONDecoder ( ) . decode ( LastPushPayloadValue . self, from: keychainValue) else {
100
+ return nil
101
+ }
102
+
103
+ // cast the payload as a JSON object
104
+ guard let lastPushPayloadJSON = try ? JSONSerialization . jsonObject ( with: payloadExpirationPair. payload, options: [ ] ) as? [ AnyHashable : Any ] else {
105
+ return nil
106
+ }
107
+
108
+ return ( payload: lastPushPayloadJSON, expiration: payloadExpirationPair. expiration) as? ( payload: Data , expiration: Date ? )
109
+ }
110
+
111
+ private func savePayloadExpirationPairToKeychain( payload: [ AnyHashable : Any ] ? , expiration: Date ? ) {
112
+ guard let payload = payload else {
113
+ removePayloadExpirationPairFromKeychain ( )
114
+ return
115
+ }
116
+
117
+ guard let payloadAsData = encodeJsonPayload ( payload) else {
118
+ return
119
+ }
120
+
121
+ let payloadExpirationPair = LastPushPayloadValue ( payload: payloadAsData, expiration: expiration)
122
+
123
+ guard let encodedPair = try ? JSONEncoder ( ) . encode ( payloadExpirationPair) else {
124
+ return
125
+ }
126
+
127
+ wrapper. set ( encodedPair, forKey: Const . Keychain. Key. lastPushPayloadAndExpiration)
128
+ }
129
+
130
+ private func encodeJsonPayload( _ json: [ AnyHashable : Any ] ? ) -> Data ? {
131
+ guard let json = json, JSONSerialization . isValidJSONObject ( json) else {
132
+ return nil
133
+ }
134
+
135
+ return try ? JSONSerialization . data ( withJSONObject: json)
136
+ }
137
+
138
+ private func decodeJsonPayload( _ data: Data ? ) -> [ AnyHashable : Any ] ? {
139
+ guard let data = data else {
140
+ return nil
141
+ }
103
142
104
- guard let expiration = wrapper. data ( forKey: Const . Keychain. Key. lastPushPayloadExpiration) as? Date else {
143
+ return try ? JSONSerialization . jsonObject ( with: data) as? [ AnyHashable : Any ]
144
+ }
145
+
146
+ private func removePayloadExpirationPairFromKeychain( ) {
147
+ wrapper. removeValue ( forKey: Const . Keychain. Key. lastPushPayloadAndExpiration)
148
+ }
149
+
150
+ private func isLastPushPayloadExpired( expiration: Date ? , currentDate: Date ) -> Bool {
151
+ guard let expiration = expiration else {
105
152
return false
106
153
}
107
154
108
155
return !( expiration. timeIntervalSinceReferenceDate > currentDate. timeIntervalSinceReferenceDate)
109
156
}
157
+
158
+ private struct LastPushPayloadValue : Codable {
159
+ let payload : Data
160
+ let expiration : Date ?
161
+ }
110
162
}
0 commit comments