Skip to content

Commit 315db3c

Browse files
authored
Persist current SDK version for migrating between versions (#182)
* Persist current SDK version for migrating between versions * improve tests * Fix testcases * Add playground example * Update CHANGELOG.md
1 parent 5b03511 commit 315db3c

File tree

9 files changed

+386
-14
lines changed

9 files changed

+386
-14
lines changed

CHANGELOG.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
# Parse-Swift Changelog
22

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

7+
### 1.8.6
8+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.5...1.8.6)
9+
10+
__Improvements__
11+
- Added SwiftUI query combine example to playgrounds. Skip id when encoding ParseObjects ([#181](https://github.com/parse-community/Parse-Swift/pull/181)), thanks to [Corey Baker](https://github.com/cbaker6).
12+
- Persist current SDK version for migrating between versions ([#182](https://github.com/parse-community/Parse-Swift/pull/182)), thanks to [Corey Baker](https://github.com/cbaker6).
13+
714
### 1.8.5
815
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.4...1.8.5)
916

@@ -30,7 +37,7 @@ __Fixes__
3037
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.1...1.8.2)
3138

3239
__Improvements__
33-
- Ensure pipeline and fields are checked when comparing queries ([#163](https://github.com/parse-community/Parse-Swift/pull/163)), thanks to [Corey Baker](https://github.com/cbaker6).
40+
- Ensure pipeline and fields are checked when comparing queries ([#163](https://github.com/parse-community/Parse-Swift/pull/163)), thanks to [Corey Baker](https://github.com/cbaker6).
3441
- Allow custom error codes to be thrown from Cloud Functions ([#165](https://github.com/parse-community/Parse-Swift/pull/165)), thanks to [Daniel Blyth](https://github.com/dblythy).
3542

3643
### 1.8.1
@@ -85,7 +92,7 @@ __Improvements__
8592
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.5.1...1.6.0)
8693

8794
__Improvements__
88-
- Make AnyCodable internal. If developers want to use AnyCodable, AnyEncodable, or AnyDecodable for `explain` or `ParseCloud`, they should add the [AnyCodable](https://github.com/Flight-School/AnyCodable) package to their app. In addition developers can create their own type-erased wrappers or use whatever they desire ([#127](https://github.com/parse-community/Parse-Swift/pull/127)), thanks to [Corey Baker](https://github.com/cbaker6).
95+
- Make AnyCodable internal. If developers want to use AnyCodable, AnyEncodable, or AnyDecodable for `explain` or `ParseCloud`, they should add the [AnyCodable](https://github.com/Flight-School/AnyCodable) package to their app. In addition developers can create their own type-erased wrappers or use whatever they desire ([#127](https://github.com/parse-community/Parse-Swift/pull/127)), thanks to [Corey Baker](https://github.com/cbaker6).
8996

9097
### 1.5.1
9198
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.5.0...1.5.1)
@@ -120,7 +127,7 @@ __Improvements__
120127
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.2.6...1.3.0)
121128

122129
__Improvements__
123-
- (Breaking Change) No longer require dispatch to main queue when using ParseInstallation. The side effect of this is bade is no longer retrieved by the SDK. The developer should retrieve the badge count on their own and save it to `ParseInstallation` if they require badge ([#114](https://github.com/parse-community/Parse-Swift/pull/114)), thanks to [Corey Baker](https://github.com/cbaker6).
130+
- (Breaking Change) No longer require dispatch to main queue when using ParseInstallation. The side effect of this is badge is no longer retrieved by the SDK. The developer should retrieve the badge count on their own and save it to `ParseInstallation` if they require badge ([#114](https://github.com/parse-community/Parse-Swift/pull/114)), thanks to [Corey Baker](https://github.com/cbaker6).
124131

125132
__Fixes__
126133
- (Breaking Change) Correctly saves objectId of ParseInstallation to Keychain when saving to server. Also fixes issue when using deleteAll with current ParseUser and ParseInstallation. Old installations will automatically be migrated to the new one. If you end up having issues you can delete all of the installations in your ParseDashboard that were created with Parse-Swift < 1.30. If you are not able to do this, you can all log out of devices using Parse-Swift < 1.30 and then log back in ([#116](https://github.com/parse-community/Parse-Swift/pull/116)), thanks to [Corey Baker](https://github.com/cbaker6).

ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ npm start -- --appId applicationId --clientKey clientKey --masterKey masterKey -
1717

1818
initializeParse()
1919

20+
//: Get current SDK version
21+
if let version = ParseVersion.current {
22+
print("Current Swift SDK version is \"\(version)\"")
23+
}
24+
2025
//: Check the health of your Parse Server.
2126
do {
2227
print("Server health is: \(try ParseHealth.check())")

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,13 @@
387387
91678706259BC5D400BB5B4E /* ParseCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916786EF259BC59600BB5B4E /* ParseCloudTests.swift */; };
388388
91678710259BC5D600BB5B4E /* ParseCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916786EF259BC59600BB5B4E /* ParseCloudTests.swift */; };
389389
9167871A259BC5D600BB5B4E /* ParseCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916786EF259BC59600BB5B4E /* ParseCloudTests.swift */; };
390+
91679D64268E596300F71809 /* ParseVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D63268E596300F71809 /* ParseVersion.swift */; };
391+
91679D65268E596300F71809 /* ParseVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D63268E596300F71809 /* ParseVersion.swift */; };
392+
91679D66268E596300F71809 /* ParseVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D63268E596300F71809 /* ParseVersion.swift */; };
393+
91679D67268E596300F71809 /* ParseVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D63268E596300F71809 /* ParseVersion.swift */; };
394+
91679D6D268F261800F71809 /* ParseVersionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D68268F25EA00F71809 /* ParseVersionTests.swift */; };
395+
91679D6E268F261900F71809 /* ParseVersionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D68268F25EA00F71809 /* ParseVersionTests.swift */; };
396+
91679D6F268F261A00F71809 /* ParseVersionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91679D68268F25EA00F71809 /* ParseVersionTests.swift */; };
390397
918CED592684C74000CFDC83 /* ParseLiveQuery+combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 918CED582684C74000CFDC83 /* ParseLiveQuery+combine.swift */; };
391398
918CED5A2684C74000CFDC83 /* ParseLiveQuery+combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 918CED582684C74000CFDC83 /* ParseLiveQuery+combine.swift */; };
392399
918CED5B2684C74000CFDC83 /* ParseLiveQuery+combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 918CED582684C74000CFDC83 /* ParseLiveQuery+combine.swift */; };
@@ -718,6 +725,8 @@
718725
9158916A256A07DD0024BE9A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
719726
916786E1259B7DDA00BB5B4E /* ParseCloud.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloud.swift; sourceTree = "<group>"; };
720727
916786EF259BC59600BB5B4E /* ParseCloudTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloudTests.swift; sourceTree = "<group>"; };
728+
91679D63268E596300F71809 /* ParseVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseVersion.swift; sourceTree = "<group>"; };
729+
91679D68268F25EA00F71809 /* ParseVersionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseVersionTests.swift; sourceTree = "<group>"; };
721730
918CED582684C74000CFDC83 /* ParseLiveQuery+combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseLiveQuery+combine.swift"; sourceTree = "<group>"; };
722731
918CED5D268618C600CFDC83 /* ParseLiveQueryCombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseLiveQueryCombineTests.swift; sourceTree = "<group>"; };
723732
9194657724F16E330070296B /* ParseACLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseACLTests.swift; sourceTree = "<group>"; };
@@ -841,8 +850,8 @@
841850
4A5EE4601F49EA0600D3CAE3 /* Tests */ = {
842851
isa = PBXGroup;
843852
children = (
844-
4AA8076C1F794C1C008CD551 /* ParseSwiftTests */,
845853
4A1120BF1F49FC3300E32D94 /* LinuxMain.swift */,
854+
4AA8076C1F794C1C008CD551 /* ParseSwiftTests */,
846855
);
847856
path = Tests;
848857
sourceTree = "<group>";
@@ -921,6 +930,7 @@
921930
89899CDC2603CE73002E2043 /* ParseTwitterTests.swift */,
922931
7016ED3F25C4A25A00038648 /* ParseUserCombineTests.swift */,
923932
70C7DC1D24D20E530050419B /* ParseUserTests.swift */,
933+
91679D68268F25EA00F71809 /* ParseVersionTests.swift */,
924934
7FFF552A2217E729007C3B4E /* AnyCodableTests */,
925935
911DB12A24C3F7260027F3C7 /* NetworkMocking */,
926936
7037DAC726384E46005D7E62 /* ParseEncoderTests */,
@@ -1200,6 +1210,7 @@
12001210
70F79A182639CE6F00731C46 /* ParseHealth.swift */,
12011211
70F79A262639D84600731C46 /* ParseHealth+combine.swift */,
12021212
7004C21F25B63C7A005E0AD9 /* ParseRelation.swift */,
1213+
91679D63268E596300F71809 /* ParseVersion.swift */,
12031214
F97B45BE24D9C6F200F4A88B /* Pointer.swift */,
12041215
F97B45BB24D9C6F200F4A88B /* Query.swift */,
12051216
7044C1AC25C4FC080011F6E7 /* Query+combine.swift */,
@@ -1711,6 +1722,7 @@
17111722
70110D52250680140091CC1D /* ParseConstants.swift in Sources */,
17121723
70D1BDBA25BB17A600A42E7C /* ParseConfig.swift in Sources */,
17131724
F97B465224D9C78C00F4A88B /* AddUnique.swift in Sources */,
1725+
91679D64268E596300F71809 /* ParseVersion.swift in Sources */,
17141726
F97B45D624D9C6F200F4A88B /* ParseEncoder.swift in Sources */,
17151727
70F79A272639D84600731C46 /* ParseHealth+combine.swift in Sources */,
17161728
700395A325A119430052CB31 /* Operations.swift in Sources */,
@@ -1789,6 +1801,7 @@
17891801
buildActionMask = 2147483647;
17901802
files = (
17911803
918CED5E268618C600CFDC83 /* ParseLiveQueryCombineTests.swift in Sources */,
1804+
91679D6D268F261800F71809 /* ParseVersionTests.swift in Sources */,
17921805
911DB13624C4FC100027F3C7 /* ParseObjectTests.swift in Sources */,
17931806
70E09E1C262F0634002DD451 /* ParsePointerCombineTests.swift in Sources */,
17941807
89899D592603CF3E002E2043 /* ParseTwitterTests.swift in Sources */,
@@ -1868,6 +1881,7 @@
18681881
70110D53250680140091CC1D /* ParseConstants.swift in Sources */,
18691882
70D1BDBB25BB17A600A42E7C /* ParseConfig.swift in Sources */,
18701883
F97B465324D9C78C00F4A88B /* AddUnique.swift in Sources */,
1884+
91679D65268E596300F71809 /* ParseVersion.swift in Sources */,
18711885
F97B45D724D9C6F200F4A88B /* ParseEncoder.swift in Sources */,
18721886
70F79A282639D84600731C46 /* ParseHealth+combine.swift in Sources */,
18731887
700395A425A119430052CB31 /* Operations.swift in Sources */,
@@ -1955,6 +1969,7 @@
19551969
buildActionMask = 2147483647;
19561970
files = (
19571971
918CED60268618C600CFDC83 /* ParseLiveQueryCombineTests.swift in Sources */,
1972+
91679D6F268F261A00F71809 /* ParseVersionTests.swift in Sources */,
19581973
709B98512556ECAA00507778 /* ParseEncoderExtraTests.swift in Sources */,
19591974
70E09E1E262F0634002DD451 /* ParsePointerCombineTests.swift in Sources */,
19601975
89899D642603CF3F002E2043 /* ParseTwitterTests.swift in Sources */,
@@ -2019,6 +2034,7 @@
20192034
buildActionMask = 2147483647;
20202035
files = (
20212036
918CED5F268618C600CFDC83 /* ParseLiveQueryCombineTests.swift in Sources */,
2037+
91679D6E268F261900F71809 /* ParseVersionTests.swift in Sources */,
20222038
70F2E2B6254F283000B2EA5C /* ParseACLTests.swift in Sources */,
20232039
70E09E1D262F0634002DD451 /* ParsePointerCombineTests.swift in Sources */,
20242040
89899D632603CF3E002E2043 /* ParseTwitterTests.swift in Sources */,
@@ -2098,6 +2114,7 @@
20982114
F97B45E124D9C6F200F4A88B /* AnyCodable.swift in Sources */,
20992115
70D1BDBD25BB17A600A42E7C /* ParseConfig.swift in Sources */,
21002116
F97B45E524D9C6F200F4A88B /* AnyEncodable.swift in Sources */,
2117+
91679D67268E596300F71809 /* ParseVersion.swift in Sources */,
21012118
F97B465D24D9C78C00F4A88B /* Increment.swift in Sources */,
21022119
70F79A2A2639D84600731C46 /* ParseHealth+combine.swift in Sources */,
21032120
700395A625A119430052CB31 /* Operations.swift in Sources */,
@@ -2191,6 +2208,7 @@
21912208
F97B45E024D9C6F200F4A88B /* AnyCodable.swift in Sources */,
21922209
70D1BDBC25BB17A600A42E7C /* ParseConfig.swift in Sources */,
21932210
F97B45E424D9C6F200F4A88B /* AnyEncodable.swift in Sources */,
2211+
91679D66268E596300F71809 /* ParseVersion.swift in Sources */,
21942212
F97B465C24D9C78C00F4A88B /* Increment.swift in Sources */,
21952213
70F79A292639D84600731C46 /* ParseHealth+combine.swift in Sources */,
21962214
700395A525A119430052CB31 /* Operations.swift in Sources */,

Sources/ParseSwift/Parse.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,28 @@ public struct ParseSwift {
102102
Self.sessionDelegate = ParseURLSessionDelegate(callbackQueue: .main,
103103
authentication: configuration.authentication)
104104

105-
//Migrate old installations made with ParseSwift < 1.3.0
106-
if let currentInstallation = BaseParseInstallation.current {
107-
if currentInstallation.objectId == nil {
108-
BaseParseInstallation.deleteCurrentContainerFromKeychain()
109-
//Prepare installation
105+
do {
106+
let previousSDKVersion = try ParseVersion(ParseVersion.current)
107+
let currentSDKVersion = try ParseVersion(ParseConstants.version)
108+
109+
// All migrations from previous versions to current should occur here:
110+
111+
if currentSDKVersion > previousSDKVersion {
112+
ParseVersion.current = currentSDKVersion.string
113+
}
114+
} catch {
115+
// Migrate old installations made with ParseSwift < 1.3.0
116+
if let currentInstallation = BaseParseInstallation.current {
117+
if currentInstallation.objectId == nil {
118+
BaseParseInstallation.deleteCurrentContainerFromKeychain()
119+
// Prepare installation
120+
_ = BaseParseInstallation()
121+
}
122+
} else {
123+
// Prepare installation
110124
_ = BaseParseInstallation()
111125
}
112-
} else {
113-
//Prepare installation
114-
_ = BaseParseInstallation()
126+
ParseVersion.current = ParseConstants.version
115127
}
116128

117129
#if !os(Linux) && !os(Android)

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 = "1.8.5"
13+
static let version = "1.8.6"
1414
static let hashingKey = "parseSwift"
1515
static let fileManagementDirectory = "parse/"
1616
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"

Sources/ParseSwift/Storage/ParseStorage.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct ParseStorage {
2727
static let currentInstallation = "_currentInstallation"
2828
static let currentConfig = "_currentConfig"
2929
static let defaultACL = "_defaultACL"
30+
static let currentVersion = "_currentVersion"
3031
}
3132
}
3233

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// ParseVersion.swift
3+
// ParseSwift
4+
//
5+
// Created by Corey Baker on 7/1/21.
6+
// Copyright © 2021 Parse Community. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// `ParseVersion` is used to determine the version of the SDK.
12+
public struct ParseVersion {
13+
14+
var string: String
15+
16+
/// Current version of the SDK.
17+
public internal(set) static var current: String? {
18+
get {
19+
guard let versionInMemory: String =
20+
try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.currentVersion) else {
21+
#if !os(Linux) && !os(Android)
22+
guard let versionFromKeyChain: String =
23+
try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.currentVersion)
24+
else {
25+
return nil
26+
}
27+
return versionFromKeyChain
28+
#else
29+
return nil
30+
#endif
31+
}
32+
return versionInMemory
33+
}
34+
set {
35+
try? ParseStorage.shared.set(newValue, for: ParseStorage.Keys.currentVersion)
36+
#if !os(Linux) && !os(Android)
37+
try? KeychainStore.shared.set(newValue, for: ParseStorage.Keys.currentVersion)
38+
#endif
39+
}
40+
}
41+
42+
init(_ string: String?) throws {
43+
guard let newString = string else {
44+
throw ParseError(code: .unknownError,
45+
message: "Can't initialize with nil value.")
46+
}
47+
self.string = newString
48+
}
49+
}
50+
51+
func > (left: ParseVersion, right: ParseVersion) -> Bool {
52+
let left = left.string.split(separator: ".").compactMap { Int($0) }
53+
assert(left.count == 3, "Left version must have 3 values, \"1.1.1\".")
54+
let right = right.string.split(separator: ".").compactMap { Int($0) }
55+
assert(right.count == 3, "Right version must have 3 values, \"1.1.1\".")
56+
if left[0] > right[0] {
57+
return true
58+
} else if left[0] < right[0] {
59+
return false
60+
} else if left[1] > right[1] {
61+
return true
62+
} else if left[1] < right[1] {
63+
return false
64+
} else if left[2] > right[2] {
65+
return true
66+
} else {
67+
return false
68+
}
69+
}
70+
71+
func >= (left: ParseVersion, right: ParseVersion) -> Bool {
72+
if left == right || left > right {
73+
return true
74+
} else {
75+
return false
76+
}
77+
}
78+
79+
func < (left: ParseVersion, right: ParseVersion) -> Bool {
80+
let left = left.string.split(separator: ".").compactMap { Int($0) }
81+
assert(left.count == 3, "Left version must have 3 values, \"1.1.1\".")
82+
let right = right.string.split(separator: ".").compactMap { Int($0) }
83+
assert(right.count == 3, "Right version must have 3 values, \"1.1.1\".")
84+
if left[0] < right[0] {
85+
return true
86+
} else if left[0] > right[0] {
87+
return false
88+
} else if left[1] < right[1] {
89+
return true
90+
} else if left[1] > right[1] {
91+
return false
92+
} else if left[2] < right[2] {
93+
return true
94+
} else {
95+
return false
96+
}
97+
}
98+
99+
func <= (left: ParseVersion, right: ParseVersion) -> Bool {
100+
if left == right || left < right {
101+
return true
102+
} else {
103+
return false
104+
}
105+
}
106+
107+
func == (left: ParseVersion, right: ParseVersion) -> Bool {
108+
left.string == right.string
109+
}

0 commit comments

Comments
 (0)