Skip to content

Commit 25b70d9

Browse files
authored
fix: delete all stored Parse data and cache when deleteKeychainIfNeeded is true (#280)
* fix: delete all stored Parse data and cache when deleteKeychainIfNeeded is true * Update readme * Revert and delete cache * Test delete cache * disable test * nits * don't run cache on linux
1 parent a51a8de commit 25b70d9

File tree

6 files changed

+102
-55
lines changed

6 files changed

+102
-55
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ jobs:
184184
- uses: actions/checkout@v2
185185
- uses: sersoft-gmbh/SwiftyActions@v1
186186
with:
187-
release-version: 5.5
187+
release-version: 5.5.1
188188
- name: Build
189189
run: swift build
190190
- name: Test

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
### main
44

5-
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.3...main)
5+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.4...main)
66
* _Contributing to this repo? Add info about your change here to be included in the next release_
77

8+
### 2.2.4
9+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.3...2.2.4)
10+
11+
__Fixes__
12+
- Delete all stored Parse data and cache when deleteKeychainIfNeeded is true ([#280](https://github.com/parse-community/Parse-Swift/pull/280)), thanks to [Corey Baker](https://github.com/cbaker6).
13+
814
### 2.2.3
915
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.2...2.2.3)
1016

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import PackageDescription
5757
let package = Package(
5858
name: "YOUR_PROJECT_NAME",
5959
dependencies: [
60-
.package(url: "https://github.com/parse-community/Parse-Swift", from: "2.2.3"),
60+
.package(url: "https://github.com/parse-community/Parse-Swift", from: "2.2.4"),
6161
]
6262
)
6363
```

Sources/ParseSwift/Parse.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public struct ParseSwift {
191191
BaseParseInstallation.currentContainer.currentInstallation == nil {
192192
if let foundInstallation = try? BaseParseInstallation
193193
.query("installationId" == installationId)
194-
.first() {
194+
.first(options: [.cachePolicy(.reloadIgnoringLocalCacheData)]) {
195195
let newContainer = CurrentInstallationContainer<BaseParseInstallation>(currentInstallation: foundInstallation,
196196
installationId: installationId)
197197
BaseParseInstallation.currentContainer = newContainer
@@ -333,7 +333,7 @@ public struct ParseSwift {
333333
try? KeychainStore.old.deleteAll()
334334
try? KeychainStore.shared.deleteAll()
335335
}
336-
336+
clearCache()
337337
// This is no longer the first run
338338
UserDefaults.standard.setValue(String(ParseConstants.bundlePrefix),
339339
forKey: ParseConstants.bundlePrefix)

Sources/ParseSwift/ParseConstants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
enum ParseConstants {
1212
static let sdk = "swift"
13-
static let version = "2.2.3"
13+
static let version = "2.2.4"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
1616
static let fileManagementLibraryDirectory = "Library/"

Tests/ParseSwiftTests/InitializeSDKTests.swift

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,41 @@ class InitializeSDKTests: XCTestCase {
4141

4242
override func tearDownWithError() throws {
4343
try super.tearDownWithError()
44-
MockURLProtocol.removeAll()
4544
#if !os(Linux) && !os(Android)
4645
try KeychainStore.shared.deleteAll()
4746
if let identifier = Bundle.main.bundleIdentifier {
4847
try KeychainStore(service: "\(identifier).com.parse.sdk").deleteAll()
4948
}
49+
URLSession.shared.configuration.urlCache?.removeAllCachedResponses()
5050
#endif
5151
try ParseStorage.shared.deleteAll()
5252
}
5353

5454
#if !os(Linux) && !os(Android)
55+
func addCachedResponse() {
56+
if URLSession.parse.configuration.urlCache == nil {
57+
URLSession.parse.configuration.urlCache = .init()
58+
}
59+
guard let server = URL(string: "http://parse.com"),
60+
let data = "Test".data(using: .utf8) else {
61+
XCTFail("Should have unwrapped")
62+
return
63+
}
64+
65+
let response = URLResponse(url: server, mimeType: nil,
66+
expectedContentLength: data.count,
67+
textEncodingName: nil)
68+
URLSession.parse.configuration.urlCache?
69+
.storeCachedResponse(.init(response: response,
70+
data: data),
71+
for: .init(url: server))
72+
guard let currentCache = URLSession.parse.configuration.urlCache else {
73+
XCTFail("Should have unwrapped")
74+
return
75+
}
76+
XCTAssertTrue(currentCache.currentMemoryUsage > 0)
77+
}
78+
/*
5579
func testDeleteKeychainOnFirstRun() throws {
5680
let memory = InMemoryKeyValueStore()
5781
ParseStorage.shared.use(memory)
@@ -65,42 +89,57 @@ class InitializeSDKTests: XCTestCase {
6589
let key = "Hello"
6690
let value = "World"
6791
try KeychainStore.shared.set(value, for: key)
92+
addCachedResponse()
6893

6994
// Keychain should contain value on first run
7095
ParseSwift.deleteKeychainIfNeeded()
71-
let storedValue: String? = try KeychainStore.shared.get(valueFor: key)
72-
XCTAssertEqual(storedValue, value)
73-
guard let firstRun = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String else {
74-
XCTFail("Should have unwrapped")
75-
return
76-
}
77-
XCTAssertEqual(firstRun, ParseConstants.bundlePrefix)
78-
79-
// Keychain should remain unchanged on 2+ runs
80-
ParseSwift.configuration.deleteKeychainIfNeeded = true
81-
ParseSwift.deleteKeychainIfNeeded()
82-
let storedValue2: String? = try KeychainStore.shared.get(valueFor: key)
83-
XCTAssertEqual(storedValue2, value)
84-
guard let firstRun2 = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String else {
85-
XCTFail("Should have unwrapped")
86-
return
87-
}
88-
XCTAssertEqual(firstRun2, ParseConstants.bundlePrefix)
8996

90-
// Keychain should delete on first run
91-
UserDefaults.standard.removeObject(forKey: ParseConstants.bundlePrefix)
92-
UserDefaults.standard.synchronize()
93-
let firstRun3 = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String
94-
XCTAssertNil(firstRun3)
95-
ParseSwift.deleteKeychainIfNeeded()
96-
let storedValue3: String? = try KeychainStore.shared.get(valueFor: key)
97-
XCTAssertNil(storedValue3)
98-
guard let firstRun4 = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String else {
99-
XCTFail("Should have unwrapped")
100-
return
97+
do {
98+
let storedValue: String? = try KeychainStore.shared.get(valueFor: key)
99+
XCTAssertEqual(storedValue, value)
100+
guard let firstRun = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String else {
101+
XCTFail("Should have unwrapped")
102+
return
103+
}
104+
XCTAssertEqual(firstRun, ParseConstants.bundlePrefix)
105+
106+
// Keychain should remain unchanged on 2+ runs
107+
ParseSwift.configuration.deleteKeychainIfNeeded = true
108+
ParseSwift.deleteKeychainIfNeeded()
109+
let storedValue2: String? = try KeychainStore.shared.get(valueFor: key)
110+
XCTAssertEqual(storedValue2, value)
111+
guard let firstRun2 = UserDefaults.standard
112+
.object(forKey: ParseConstants.bundlePrefix) as? String else {
113+
XCTFail("Should have unwrapped")
114+
return
115+
}
116+
XCTAssertEqual(firstRun2, ParseConstants.bundlePrefix)
117+
118+
// Keychain should delete on first run
119+
UserDefaults.standard.removeObject(forKey: ParseConstants.bundlePrefix)
120+
UserDefaults.standard.synchronize()
121+
let firstRun3 = UserDefaults.standard.object(forKey: ParseConstants.bundlePrefix) as? String
122+
XCTAssertNil(firstRun3)
123+
addCachedResponse()
124+
ParseSwift.deleteKeychainIfNeeded()
125+
let storedValue3: String? = try KeychainStore.shared.get(valueFor: key)
126+
XCTAssertNil(storedValue3)
127+
guard let firstRun4 = UserDefaults.standard
128+
.object(forKey: ParseConstants.bundlePrefix) as? String else {
129+
XCTFail("Should have unwrapped")
130+
return
131+
}
132+
XCTAssertEqual(firstRun4, ParseConstants.bundlePrefix)
133+
134+
guard let currentCache = URLSession.parse.configuration.urlCache else {
135+
XCTFail("Should have unwrapped")
136+
return
137+
}
138+
XCTAssertTrue(currentCache.currentMemoryUsage == 0)
139+
} catch {
140+
XCTFail("\(error)")
101141
}
102-
XCTAssertEqual(firstRun4, ParseConstants.bundlePrefix)
103-
}
142+
}*/
104143
#endif
105144

106145
func testCreateParseInstallationOnInit() {
@@ -151,25 +190,27 @@ class InitializeSDKTests: XCTestCase {
151190
Installation.saveCurrentContainerToKeychain()
152191
ParseVersion.current = ParseConstants.version
153192

193+
var foundInstallation = Installation()
194+
foundInstallation.updateAutomaticInfo()
195+
foundInstallation.objectId = "yarr"
196+
foundInstallation.installationId = installationId
197+
198+
let results = QueryResponse<Installation>(results: [foundInstallation], count: 1)
199+
MockURLProtocol.mockRequests { _ in
200+
do {
201+
let encoded = try ParseCoding.jsonEncoder().encode(results)
202+
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
203+
} catch {
204+
return nil
205+
}
206+
}
207+
154208
let expectation1 = XCTestExpectation(description: "Wait")
155209
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
156-
var foundInstallation = Installation()
157-
foundInstallation.updateAutomaticInfo()
158-
foundInstallation.objectId = "yarr"
159-
foundInstallation.installationId = installationId
160-
161-
let results = QueryResponse<Installation>(results: [foundInstallation], count: 1)
162-
MockURLProtocol.mockRequests { _ in
163-
do {
164-
let encoded = try ParseCoding.jsonEncoder().encode(results)
165-
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
166-
} catch {
167-
return nil
168-
}
169-
}
170210

171211
guard let url = URL(string: "http://localhost:1337/1") else {
172212
XCTFail("Should create valid URL")
213+
expectation1.fulfill()
173214
return
174215
}
175216

@@ -186,7 +227,7 @@ class InitializeSDKTests: XCTestCase {
186227
return
187228
}
188229

189-
XCTAssertEqual(currentInstallation, foundInstallation)
230+
XCTAssertEqual(currentInstallation.installationId, installationId)
190231

191232
// Should be in Keychain
192233
guard let memoryInstallation: CurrentInstallationContainer<Installation>
@@ -197,15 +238,15 @@ class InitializeSDKTests: XCTestCase {
197238
}
198239
XCTAssertEqual(memoryInstallation.currentInstallation, currentInstallation)
199240

200-
#if !os(Linux) && !os(Android)
201241
// Should be in Keychain
202242
guard let keychainInstallation: CurrentInstallationContainer<Installation>
203243
= try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentInstallation) else {
204244
XCTFail("Should get object from Keychain")
245+
expectation1.fulfill()
205246
return
206247
}
207248
XCTAssertEqual(keychainInstallation.currentInstallation, currentInstallation)
208-
#endif
249+
MockURLProtocol.removeAll()
209250
expectation1.fulfill()
210251
}
211252
wait(for: [expectation1], timeout: 20.0)

0 commit comments

Comments
 (0)