Skip to content

Commit a746db0

Browse files
authored
fix: Prevent crash when the SDK has not been initialized (#95)
1 parent 1c4d8c3 commit a746db0

18 files changed

+150
-109
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
# Parse-Swift Changelog
33

44
### main
5-
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.1...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
5+
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.2...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
66
* _Contributing to this repo? Add info about your change here to be included in the next release_
77

8+
### 5.4.2
9+
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.1...5.4.2), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.4.2/documentation/parseswift)
10+
811
__Fixes__
12+
* Prevent crash when the developer makes query, fetch, etc. calls before the SDK is properly initialized ([#95](https://github.com/netreconlab/Parse-Swift/pull/95)), thanks to [Corey Baker](https://github.com/cbaker6).
913
* Add backwards compatability to Xcode 13.2. Building on Xcode <13.3 only works for SPM ([#92](https://github.com/netreconlab/Parse-Swift/pull/92)), thanks to [Corey Baker](https://github.com/cbaker6).
1014

1115
### 5.4.1

Sources/ParseSwift/API/API+Command.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,15 @@ internal extension API.Command {
409409
&& object.objectId == nil && !ignoringCustomObjectIdConfig {
410410
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
411411
}
412-
if object.isSaved {
412+
if try await object.isSaved() {
413413
// MARK: Should be switched to "update" when server supports PATCH.
414414
return try replace(object,
415415
original: data)
416416
}
417-
return await create(object)
417+
return try await create(object)
418418
}
419419

420-
static func create<T>(_ object: T) async -> API.Command<T, T> where T: ParseObject {
420+
static func create<T>(_ object: T) async throws -> API.Command<T, T> where T: ParseObject {
421421
var object = object
422422
if object.ACL == nil,
423423
let acl = try? await ParseACL.defaultACL() {
@@ -427,7 +427,7 @@ internal extension API.Command {
427427
try ParseCoding.jsonDecoder().decode(CreateResponse.self, from: data).apply(to: object)
428428
}
429429
return API.Command<T, T>(method: .POST,
430-
path: object.endpoint(.POST),
430+
path: try await object.endpoint(.POST),
431431
body: object,
432432
mapper: mapper)
433433
}

Sources/ParseSwift/API/API+NonParseBodyCommand.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ internal extension API.NonParseBodyCommand {
169169
objectsSavedBeforeThisOne: [String: PointerType]?,
170170
// swiftlint:disable:next line_length
171171
filesSavedBeforeThisOne: [String: ParseFile]?) async throws -> RESTBatchCommandTypeEncodablePointer<AnyCodable> {
172+
try await yieldIfNotInitialized()
172173
let defaultACL = try? await ParseACL.defaultACL()
173174
let batchCommands = try objects.compactMap { (object) -> API.BatchCommand<AnyCodable, PointerType>? in
174175
guard var objectable = object as? Objectable else {

Sources/ParseSwift/Objects/ParseInstallation+async.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ internal extension ParseInstallation {
341341
case .save:
342342
command = try await self.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
343343
case .create:
344-
command = await self.createCommand()
344+
command = try await self.createCommand()
345345
case .replace:
346346
command = try self.replaceCommand()
347347
case .update:
@@ -400,7 +400,7 @@ internal extension Sequence where Element: ParseInstallation {
400400
try await object.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
401401
)
402402
case .create:
403-
commands.append(await object.createCommand())
403+
commands.append(try await object.createCommand())
404404
case .replace:
405405
commands.append(try object.replaceCommand())
406406
case .update:

Sources/ParseSwift/Objects/ParseInstallation.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ public extension ParseInstallation {
172172
// MARK: Convenience
173173
extension ParseInstallation {
174174

175-
func endpoint(_ method: API.Method) -> API.Endpoint {
175+
func endpoint(_ method: API.Method) async throws -> API.Endpoint {
176+
try await yieldIfNotInitialized()
176177
if !Parse.configuration.isRequiringCustomObjectIds || method != .POST {
177178
return endpoint
178179
} else {
@@ -727,17 +728,19 @@ extension ParseInstallation {
727728
}
728729

729730
func saveCommand(ignoringCustomObjectIdConfig: Bool = false) async throws -> API.Command<Self, Self> {
731+
try await yieldIfNotInitialized()
730732
if Parse.configuration.isRequiringCustomObjectIds && objectId == nil && !ignoringCustomObjectIdConfig {
731733
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
732734
}
733-
if isSaved {
735+
if try await isSaved() {
734736
return try replaceCommand() // MARK: Should be switched to "updateCommand" when server supports PATCH.
735737
}
736-
return await createCommand()
738+
return try await createCommand()
737739
}
738740

739741
// MARK: Saving ParseObjects - private
740-
func createCommand() async -> API.Command<Self, Self> {
742+
func createCommand() async throws -> API.Command<Self, Self> {
743+
try await yieldIfNotInitialized()
741744
var object = self
742745
if object.ACL == nil,
743746
let acl = try? await ParseACL.defaultACL() {
@@ -747,7 +750,7 @@ extension ParseInstallation {
747750
try ParseCoding.jsonDecoder().decode(CreateResponse.self, from: data).apply(to: object)
748751
}
749752
return API.Command<Self, Self>(method: .POST,
750-
path: endpoint(.POST),
753+
path: try await endpoint(.POST),
751754
body: object,
752755
mapper: mapper)
753756
}
@@ -854,8 +857,8 @@ extension ParseInstallation {
854857
}
855858
}
856859

857-
func deleteCommand() throws -> API.NonParseBodyCommand<NoBody, NoBody> {
858-
guard isSaved else {
860+
func deleteCommand() async throws -> API.NonParseBodyCommand<NoBody, NoBody> {
861+
guard try await isSaved() else {
859862
throw ParseError(code: .otherCause, message: "Cannot Delete an object without id")
860863
}
861864

Sources/ParseSwift/Objects/ParseObject+async.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ or disable transactions for this call.
385385
case .save:
386386
command = try await self.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
387387
case .create:
388-
command = await self.createCommand()
388+
command = try await self.createCommand()
389389
case .replace:
390390
command = try self.replaceCommand()
391391
case .update:
@@ -442,7 +442,7 @@ internal extension Sequence where Element: ParseObject {
442442
try await object.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
443443
)
444444
case .create:
445-
commands.append(await object.createCommand())
445+
commands.append(try await object.createCommand())
446446
case .replace:
447447
commands.append(try object.replaceCommand())
448448
case .update:

Sources/ParseSwift/Objects/ParseObject.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,8 @@ extension ParseObject {
909909
ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
910910
}
911911

912-
internal func createCommand() async -> API.Command<Self, Self> {
913-
await API.Command<Self, Self>.create(self)
912+
internal func createCommand() async throws -> API.Command<Self, Self> {
913+
try await API.Command<Self, Self>.create(self)
914914
}
915915

916916
internal func replaceCommand() throws -> API.Command<Self, Self> {

Sources/ParseSwift/Objects/ParseUser+async.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ internal extension ParseUser {
572572
case .save:
573573
command = try await self.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
574574
case .create:
575-
command = await self.createCommand()
575+
command = try await self.createCommand()
576576
case .replace:
577577
command = try await self.replaceCommand()
578578
case .update:
@@ -631,7 +631,7 @@ internal extension Sequence where Element: ParseUser {
631631
try await object.saveCommand(ignoringCustomObjectIdConfig: ignoringCustomObjectIdConfig)
632632
)
633633
case .create:
634-
commands.append(await object.createCommand())
634+
commands.append(try await object.createCommand())
635635
case .replace:
636636
commands.append(try await object.replaceCommand())
637637
case .update:

Sources/ParseSwift/Objects/ParseUser.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ public extension ParseUser {
102102
// MARK: Convenience
103103
extension ParseUser {
104104

105-
func endpoint(_ method: API.Method) -> API.Endpoint {
105+
func endpoint(_ method: API.Method) async throws -> API.Endpoint {
106+
try await yieldIfNotInitialized()
106107
if !Parse.configuration.isRequiringCustomObjectIds || method != .POST {
107108
return endpoint
108109
} else {
@@ -1079,17 +1080,18 @@ extension ParseUser {
10791080
}
10801081

10811082
func saveCommand(ignoringCustomObjectIdConfig: Bool = false) async throws -> API.Command<Self, Self> {
1083+
try await yieldIfNotInitialized()
10821084
if Parse.configuration.isRequiringCustomObjectIds && objectId == nil && !ignoringCustomObjectIdConfig {
10831085
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
10841086
}
10851087
if isSaved {
10861088
return try await replaceCommand() // MARK: Should be switched to "updateCommand" when server supports PATCH.
10871089
}
1088-
return await createCommand()
1090+
return try await createCommand()
10891091
}
10901092

10911093
// MARK: Saving ParseObjects - private
1092-
func createCommand() async -> API.Command<Self, Self> {
1094+
func createCommand() async throws -> API.Command<Self, Self> {
10931095
var object = self
10941096
if object.ACL == nil,
10951097
let acl = try? await ParseACL.defaultACL() {
@@ -1099,7 +1101,7 @@ extension ParseUser {
10991101
try ParseCoding.jsonDecoder().decode(CreateResponse.self, from: data).apply(to: object)
11001102
}
11011103
return API.Command<Self, Self>(method: .POST,
1102-
path: endpoint(.POST),
1104+
path: try await endpoint(.POST),
11031105
body: object,
11041106
mapper: mapper)
11051107
}

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 = "5.4.1"
13+
static let version = "5.4.2"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
1616
static let fileManagementLibraryDirectory = "Library/"

0 commit comments

Comments
 (0)