Skip to content

Commit ddcf35f

Browse files
authored
fix: Installation not saving to keychain correctly, returning nil instead (#236)
* fix installation saving to keychain * nits: reduce duplication in container names * Update change log and minimum in readme * query if missing current installation * Fix failing test cases * More fixes to failing tests * Attempt to fix Linux test failure * Remove test from Linux * Update .codecov.yml
1 parent 1a30fb6 commit ddcf35f

16 files changed

+255
-94
lines changed

.codecov.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ coverage:
44
status:
55
patch:
66
default:
7-
target: 82
7+
target: auto
88
changes: false
99
project:
1010
default:

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# Parse-Swift Changelog
22

33
### main
4-
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.9...main)
4+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.10...main)
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

7+
### 1.9.10
8+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.9...1.9.10)
9+
__Fixes__
10+
- ParseInstallation can't be retreived from Keychain after the first fun ([#236](https://github.com/parse-community/Parse-Swift/pull/236)), thanks to [Corey Baker](https://github.com/cbaker6).
11+
712
### 1.9.9
813
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.8...1.9.9)
914

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import PackageDescription
4545
let package = Package(
4646
name: "YOUR_PROJECT_NAME",
4747
dependencies: [
48-
.package(url: "https://github.com/parse-community/Parse-Swift", from: "1.9.0"),
48+
.package(url: "https://github.com/parse-community/Parse-Swift", from: "1.9.10"),
4949
]
5050
)
5151
```

Sources/ParseSwift/API/API.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ public struct API {
176176
headers["X-Parse-Client-Key"] = clientKey
177177
}
178178

179-
if let token = BaseParseUser.currentUserContainer?.sessionToken {
179+
if let token = BaseParseUser.currentContainer?.sessionToken {
180180
headers["X-Parse-Session-Token"] = token
181181
}
182182

183-
if let installationId = BaseParseInstallation.currentInstallationContainer.installationId {
183+
if let installationId = BaseParseInstallation.currentContainer.installationId {
184184
headers["X-Parse-Installation-Id"] = installationId
185185
}
186186

Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ public extension ParseUser {
411411
throw ParseError(code: .unknownError, message: "Should have a current user.")
412412
}
413413
if let sessionToken = user.sessionToken {
414-
Self.currentUserContainer = .init(currentUser: current,
414+
Self.currentContainer = .init(currentUser: current,
415415
sessionToken: sessionToken)
416416
}
417417
Self.saveCurrentContainerToKeychain()
@@ -441,7 +441,7 @@ public extension ParseUser {
441441
throw ParseError(code: .unknownError, message: "Should have a current user.")
442442
}
443443
if let sessionToken = user.sessionToken {
444-
Self.currentUserContainer = .init(currentUser: current,
444+
Self.currentContainer = .init(currentUser: current,
445445
sessionToken: sessionToken)
446446
}
447447
Self.saveCurrentContainerToKeychain()

Sources/ParseSwift/Internal/BaseParseInstallation.swift

+10-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@ internal struct BaseParseInstallation: ParseInstallation {
2525
var updatedAt: Date?
2626
var ACL: ParseACL?
2727

28-
init() {
29-
//Force installation in keychain to be created if it hasn't already
30-
Self.current = self
28+
static func createNewInstallationIfNeeded() {
29+
guard let installationId = Self.currentContainer.installationId,
30+
Self.currentContainer.currentInstallation?.installationId == installationId else {
31+
try? ParseStorage.shared.delete(valueFor: ParseStorage.Keys.currentInstallation)
32+
#if !os(Linux) && !os(Android)
33+
try? KeychainStore.shared.delete(valueFor: ParseStorage.Keys.currentInstallation)
34+
#endif
35+
_ = Self.currentContainer
36+
return
37+
}
3138
}
3239
}

Sources/ParseSwift/LiveQuery/Messages.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ struct StandardMessage: LiveQueryable, Codable {
2424
self.applicationId = ParseSwift.configuration.applicationId
2525
self.masterKey = ParseSwift.configuration.masterKey
2626
self.clientKey = ParseSwift.configuration.clientKey
27-
self.sessionToken = BaseParseUser.currentUserContainer?.sessionToken
28-
self.installationId = BaseParseInstallation.currentInstallationContainer.installationId
27+
self.sessionToken = BaseParseUser.currentContainer?.sessionToken
28+
self.installationId = BaseParseInstallation.currentContainer.installationId
2929
}
3030
}
3131

@@ -59,7 +59,7 @@ struct SubscribeMessage<T: ParseObject>: LiveQueryable, Encodable {
5959
if let query = query {
6060
self.query = SubscribeQuery(className: query.className, where: query.where, fields: query.fields)
6161
}
62-
self.sessionToken = BaseParseUser.currentUserContainer?.sessionToken
62+
self.sessionToken = BaseParseUser.currentContainer?.sessionToken
6363
}
6464
}
6565

Sources/ParseSwift/LiveQuery/ParseLiveQuery.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ extension ParseLiveQuery: LiveQuerySocketDelegate {
427427
}
428428
}
429429

430-
if let installationId = BaseParseInstallation.currentInstallationContainer.installationId {
430+
if let installationId = BaseParseInstallation.currentContainer.installationId {
431431
if installationId != preliminaryMessage.installationId {
432432
let error = ParseError(code: .unknownError,
433433
// swiftlint:disable:next line_length

Sources/ParseSwift/Objects/ParseInstallation.swift

+48-28
Original file line numberDiff line numberDiff line change
@@ -124,32 +124,52 @@ struct CurrentInstallationContainer<T: ParseInstallation>: Codable {
124124

125125
// MARK: Current Installation Support
126126
extension ParseInstallation {
127-
static var currentInstallationContainer: CurrentInstallationContainer<Self> {
127+
static var currentContainer: CurrentInstallationContainer<Self> {
128128
get {
129129
guard let installationInMemory: CurrentInstallationContainer<Self> =
130-
try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) else {
130+
try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation) else {
131131
#if !os(Linux) && !os(Android)
132-
guard let installationFromKeyChain: CurrentInstallationContainer<Self> =
132+
guard let installationFromKeyChain: CurrentInstallationContainer<Self> =
133133
try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation)
134-
else {
135-
var newInstallation = CurrentInstallationContainer<Self>()
136-
let newInstallationId = UUID().uuidString.lowercased()
137-
newInstallation.installationId = newInstallationId
138-
newInstallation.currentInstallation?.createInstallationId(newId: newInstallationId)
139-
newInstallation.currentInstallation?.updateAutomaticInfo()
140-
try? KeychainStore.shared.set(newInstallation, for: ParseStorage.Keys.currentInstallation)
141-
try? ParseStorage.shared.set(newInstallation, for: ParseStorage.Keys.currentInstallation)
142-
return newInstallation
134+
else {
135+
let newInstallationId = UUID().uuidString.lowercased()
136+
var newInstallation = BaseParseInstallation()
137+
newInstallation.installationId = newInstallationId
138+
newInstallation.createInstallationId(newId: newInstallationId)
139+
newInstallation.updateAutomaticInfo()
140+
let newBaseInstallationContainer =
141+
CurrentInstallationContainer<BaseParseInstallation>(currentInstallation: newInstallation,
142+
installationId: newInstallationId)
143+
try? KeychainStore.shared.set(newBaseInstallationContainer,
144+
for: ParseStorage.Keys.currentInstallation)
145+
guard let installationFromKeyChain: CurrentInstallationContainer<Self> =
146+
try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation)
147+
else {
148+
// Couldn't create container correctly, return empty one.
149+
return CurrentInstallationContainer<Self>()
143150
}
151+
try? ParseStorage.shared.set(installationFromKeyChain, for: ParseStorage.Keys.currentInstallation)
144152
return installationFromKeyChain
153+
}
154+
return installationFromKeyChain
145155
#else
146-
var newInstallation = CurrentInstallationContainer<Self>()
147-
let newInstallationId = UUID().uuidString.lowercased()
148-
newInstallation.installationId = newInstallationId
149-
newInstallation.currentInstallation?.createInstallationId(newId: newInstallationId)
150-
newInstallation.currentInstallation?.updateAutomaticInfo()
151-
try? ParseStorage.shared.set(newInstallation, for: ParseStorage.Keys.currentInstallation)
152-
return newInstallation
156+
let newInstallationId = UUID().uuidString.lowercased()
157+
var newInstallation = BaseParseInstallation()
158+
newInstallation.installationId = newInstallationId
159+
newInstallation.createInstallationId(newId: newInstallationId)
160+
newInstallation.updateAutomaticInfo()
161+
let newBaseInstallationContainer =
162+
CurrentInstallationContainer<BaseParseInstallation>(currentInstallation: newInstallation,
163+
installationId: newInstallationId)
164+
try? ParseStorage.shared.set(newBaseInstallationContainer,
165+
for: ParseStorage.Keys.currentInstallation)
166+
guard let installationFromMemory: CurrentInstallationContainer<Self> =
167+
try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentInstallation)
168+
else {
169+
// Couldn't create container correctly, return empty one.
170+
return CurrentInstallationContainer<Self>()
171+
}
172+
return installationFromMemory
153173
#endif
154174
}
155175
return installationInMemory
@@ -160,19 +180,19 @@ extension ParseInstallation {
160180
}
161181

162182
internal static func updateInternalFieldsCorrectly() {
163-
if Self.currentInstallationContainer.currentInstallation?.installationId !=
164-
Self.currentInstallationContainer.installationId! {
183+
if Self.currentContainer.currentInstallation?.installationId !=
184+
Self.currentContainer.installationId! {
165185
//If the user made changes, set back to the original
166-
Self.currentInstallationContainer.currentInstallation?.installationId =
167-
Self.currentInstallationContainer.installationId!
186+
Self.currentContainer.currentInstallation?.installationId =
187+
Self.currentContainer.installationId!
168188
}
169189
//Always pull automatic info to ensure user made no changes to immutable values
170-
Self.currentInstallationContainer.currentInstallation?.updateAutomaticInfo()
190+
Self.currentContainer.currentInstallation?.updateAutomaticInfo()
171191
}
172192

173193
internal static func saveCurrentContainerToKeychain() {
174194
#if !os(Linux) && !os(Android)
175-
try? KeychainStore.shared.set(Self.currentInstallationContainer, for: ParseStorage.Keys.currentInstallation)
195+
try? KeychainStore.shared.set(Self.currentContainer, for: ParseStorage.Keys.currentInstallation)
176196
#endif
177197
}
178198

@@ -182,7 +202,7 @@ extension ParseInstallation {
182202
try? KeychainStore.shared.delete(valueFor: ParseStorage.Keys.currentInstallation)
183203
#endif
184204
//Prepare new installation
185-
_ = BaseParseInstallation()
205+
BaseParseInstallation.createNewInstallationIfNeeded()
186206
}
187207

188208
/**
@@ -192,10 +212,10 @@ extension ParseInstallation {
192212
*/
193213
public static var current: Self? {
194214
get {
195-
return Self.currentInstallationContainer.currentInstallation
215+
return Self.currentContainer.currentInstallation
196216
}
197217
set {
198-
Self.currentInstallationContainer.currentInstallation = newValue
218+
Self.currentContainer.currentInstallation = newValue
199219
Self.updateInternalFieldsCorrectly()
200220
}
201221
}

Sources/ParseSwift/Objects/ParseUser.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct CurrentUserContainer<T: ParseUser>: Codable {
9999

100100
// MARK: Current User Support
101101
extension ParseUser {
102-
static var currentUserContainer: CurrentUserContainer<Self>? {
102+
static var currentContainer: CurrentUserContainer<Self>? {
103103
get {
104104
guard let currentUserInMemory: CurrentUserContainer<Self>
105105
= try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentUser) else {
@@ -116,7 +116,7 @@ extension ParseUser {
116116

117117
internal static func saveCurrentContainerToKeychain() {
118118
#if !os(Linux) && !os(Android)
119-
try? KeychainStore.shared.set(Self.currentUserContainer, for: ParseStorage.Keys.currentUser)
119+
try? KeychainStore.shared.set(Self.currentContainer, for: ParseStorage.Keys.currentUser)
120120
#endif
121121
}
122122

@@ -128,7 +128,7 @@ extension ParseUser {
128128
}
129129
try? KeychainStore.shared.delete(valueFor: ParseStorage.Keys.currentUser)
130130
#endif
131-
BaseParseUser.currentUserContainer = nil
131+
BaseParseUser.currentContainer = nil
132132
}
133133

134134
/**
@@ -138,9 +138,9 @@ extension ParseUser {
138138
- warning: Only use `current` users on the main thread as as modifications to `current` have to be unique.
139139
*/
140140
public static var current: Self? {
141-
get { Self.currentUserContainer?.currentUser }
141+
get { Self.currentContainer?.currentUser }
142142
set {
143-
Self.currentUserContainer?.currentUser = newValue
143+
Self.currentContainer?.currentUser = newValue
144144
}
145145
}
146146

@@ -150,7 +150,7 @@ extension ParseUser {
150150
This is set by the server upon successful authentication.
151151
*/
152152
public var sessionToken: String? {
153-
Self.currentUserContainer?.sessionToken
153+
Self.currentContainer?.sessionToken
154154
}
155155
}
156156

@@ -217,7 +217,7 @@ extension ParseUser {
217217
var user = try ParseCoding.jsonDecoder().decode(Self.self, from: data)
218218
user.username = username
219219

220-
Self.currentUserContainer = .init(
220+
Self.currentContainer = .init(
221221
currentUser: user,
222222
sessionToken: sessionToken
223223
)
@@ -302,7 +302,7 @@ extension ParseUser {
302302
}
303303
}
304304

305-
Self.currentUserContainer = .init(
305+
Self.currentContainer = .init(
306306
currentUser: user,
307307
sessionToken: sessionToken
308308
)
@@ -656,7 +656,7 @@ extension ParseUser {
656656
user.authData = authData
657657
}
658658
}
659-
Self.currentUserContainer = .init(currentUser: user,
659+
Self.currentContainer = .init(currentUser: user,
660660
sessionToken: sessionToken)
661661
Self.saveCurrentContainerToKeychain()
662662
return user
@@ -672,7 +672,7 @@ extension ParseUser {
672672
let response = try ParseCoding.jsonDecoder()
673673
.decode(LoginSignupResponse.self, from: data)
674674
let user = response.applySignup(to: self)
675-
Self.currentUserContainer = .init(
675+
Self.currentContainer = .init(
676676
currentUser: user,
677677
sessionToken: response.sessionToken
678678
)

0 commit comments

Comments
 (0)