From 3c09b20f5606dd2de891926a9bbba94ab557bbc8 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 01:07:44 -0500 Subject: [PATCH 01/26] feat: allow for developer to specify updated keys --- Sources/ParseSwift/API/API+Command.swift | 2 +- .../Objects/ParseInstallation.swift | 117 ++++++++++++++++-- Sources/ParseSwift/Objects/ParseObject.swift | 32 +++++ Sources/ParseSwift/Objects/ParseUser.swift | 98 +++++++++++---- Sources/ParseSwift/Types/ParseConfig.swift | 2 +- Sources/ParseSwift/Types/ParseOperation.swift | 2 +- Tests/ParseSwiftTests/ParseObjectTests.swift | 44 ++++++- 7 files changed, 255 insertions(+), 42 deletions(-) diff --git a/Sources/ParseSwift/API/API+Command.swift b/Sources/ParseSwift/API/API+Command.swift index 6560d834a..ee90c06ee 100644 --- a/Sources/ParseSwift/API/API+Command.swift +++ b/Sources/ParseSwift/API/API+Command.swift @@ -391,7 +391,7 @@ internal extension API.Command { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } if object.isSaved { - return try replace(object) // Should be switched to "update" when server supports PATCH. + return try replace(object) // MARK: Should be switched to "update" when server supports PATCH. } return create(object) } diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 7efe18504..c2de57b8f 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -35,44 +35,67 @@ import Foundation public protocol ParseInstallation: ParseObject { /** - The device type for the `ParseInstallation`. + The device type for the `ParseInstallation`. */ var deviceType: String? { get set } /** - The installationId for the `ParseInstallation`. + The installationId for the `ParseInstallation`. */ var installationId: String? { get set } /** - The device token for the `ParseInstallation`. + The device token for the `ParseInstallation`. */ var deviceToken: String? { get set } /** - The badge for the `ParseInstallation`. + The badge for the `ParseInstallation`. */ var badge: Int? { get set } /** - The name of the time zone for the `ParseInstallation`. + The name of the time zone for the `ParseInstallation`. */ var timeZone: String? { get set } /** - The channels for the `ParseInstallation`. + The channels for the `ParseInstallation`. */ var channels: [String]? { get set } + /** + The application name for the `ParseInstallation`. + */ var appName: String? { get set } + /** + The application identifier for the `ParseInstallation`. + */ var appIdentifier: String? { get set } + /** + The application version for the `ParseInstallation`. + */ var appVersion: String? { get set } + /** + The sdk version for the `ParseInstallation`. + */ var parseVersion: String? { get set } + /** + The locale identifier for the `ParseInstallation`. + */ var localeIdentifier: String? { get set } + + /** + Updates a `ParseInstallation` with all keys that have been modified. + - parameter installation: The original installation. + - returns: The updated installation. + - throws: An error of type `ParseError`. + */ + func applyDefaultUpdate(_ installation: Self) throws -> Self } // MARK: Default Implementations @@ -80,6 +103,67 @@ public extension ParseInstallation { static var className: String { "_Installation" } + + func applyDefaultUpdate(_ installation: Self) throws -> Self { + guard hasSameObjectId(as: installation) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects don't match") + } + var updatedInstallation = self + if isRestoreOriginalKey(\.deviceType, + original: installation) { + updatedInstallation.deviceType = installation.deviceType + } + if isRestoreOriginalKey(\.deviceType, + original: installation) { + updatedInstallation.installationId = installation.installationId + } + if isRestoreOriginalKey(\.deviceType, + original: installation) { + updatedInstallation.deviceToken = installation.deviceToken + } + if isRestoreOriginalKey(\.badge, + original: installation) { + updatedInstallation.badge = installation.badge + } + if isRestoreOriginalKey(\.timeZone, + original: installation) { + updatedInstallation.timeZone = installation.timeZone + } + if isRestoreOriginalKey(\.channels, + original: installation) { + updatedInstallation.channels = installation.channels + } + if isRestoreOriginalKey(\.appName, + original: installation) { + updatedInstallation.appName = installation.appName + } + if isRestoreOriginalKey(\.appIdentifier, + original: installation) { + updatedInstallation.appIdentifier = installation.appIdentifier + } + if isRestoreOriginalKey(\.appVersion, + original: installation) { + updatedInstallation.appVersion = installation.appVersion + } + if isRestoreOriginalKey(\.parseVersion, + original: installation) { + updatedInstallation.parseVersion = installation.parseVersion + } + if isRestoreOriginalKey(\.localeIdentifier, + original: installation) { + updatedInstallation.localeIdentifier = installation.localeIdentifier + } + return updatedInstallation + } + + func applyUpdate(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects don't match") + } + return try applyDefaultUpdate(object) + } } // MARK: Convenience @@ -664,7 +748,7 @@ extension ParseInstallation { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } if isSaved { - return try replaceCommand() // Should be switched to "updateCommand" when server supports PATCH. + return try replaceCommand() // MARK: Should be switched to "updateCommand" when server supports PATCH. } return createCommand() } @@ -690,8 +774,14 @@ extension ParseInstallation { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } - let mapper = { (data) -> Self in - try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + let mapper = { (data: Data) -> Self in + let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + // MARK: The lines below should be removed when server supports PATCH. + guard let current = Self.current, + current.hasSameObjectId(as: object) == true else { + return object + } + return try object.applyUpdate(current) } return API.Command(method: .PUT, path: endpoint, @@ -704,8 +794,13 @@ extension ParseInstallation { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } - let mapper = { (data) -> Self in - try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + let mapper = { (data: Data) -> Self in + let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + guard let current = Self.current, + current.hasSameObjectId(as: object) == true else { + return object + } + return try object.applyUpdate(current) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index ee602757a..3b9a144ca 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -51,6 +51,23 @@ public protocol ParseObject: Objectable, The weight/rank of a `QueryConstraint.matchesText()`. */ var score: Double? { get } + + /** + Determines if a `KeyPath` of the current `ParseObject` should be restored + by comparing it to another `ParseObject`. + - parameter original: The original `ParseObject`. + - returns: Returns a `true` if the keyPath should be restored or `false` otherwise. + */ + func isRestoreOriginalKey(_ key: KeyPath, + original: Self) -> Bool where W: Equatable + + /** + Updates a `ParseObject` with all keys that have been modified. + - parameter object: The original object. + - returns: The updated object. + - throws: An error of type `ParseError`. + */ + func applyUpdate(_ object: Self) throws -> Self } // MARK: Default Implementations @@ -84,6 +101,21 @@ public extension ParseObject { func toPointer() throws -> Pointer { return try Pointer(self) } +/* + func isRestoreOriginalKey(_ key: KeyPath, + original: Self, + updated: Self) -> Bool where W: Equatable { + updated[keyPath: key] == nil && original[keyPath: key] != updated[keyPath: key] + }*/ + + func isRestoreOriginalKey(_ key: KeyPath, + original: Self) -> Bool where W: Equatable { + self[keyPath: key] == nil && original[keyPath: key] != self[keyPath: key] + } + + func applyUpdate(_ object: Self) throws -> Self { + return self + } } // MARK: Batch Support diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index f05d7c13b..98fca650d 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -35,27 +35,14 @@ public protocol ParseUser: ParseObject { or any authentication type that conforms to `ParseAuthentication`. */ var authData: [String: [String: String]?]? { get set } -} - -// MARK: SignupLoginBody -struct SignupLoginBody: ParseType { - var username: String? - var password: String? - var authData: [String: [String: String]?]? - init(username: String, password: String) { - self.username = username - self.password = password - } - - init(authData: [String: [String: String]?]) { - self.authData = authData - } -} - -// MARK: EmailBody -struct EmailBody: ParseType { - let email: String + /** + Updates a `ParseUser` with all keys that have been modified. + - parameter user: The original user. + - returns: The updated user. + - throws: An error of type `ParseError`. + */ + func applyDefaultUpdate(_ user: Self) throws -> Self } // MARK: Default Implementations @@ -63,6 +50,35 @@ public extension ParseUser { static var className: String { "_User" } + + func applyDefaultUpdate(_ user: Self) throws -> Self { + guard hasSameObjectId(as: user) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects do not match") + } + var updatedUser = self + if isRestoreOriginalKey(\.username, + original: user) { + updatedUser.username = user.username + } + if isRestoreOriginalKey(\.email, + original: user) { + updatedUser.email = user.email + } + if isRestoreOriginalKey(\.authData, + original: user) { + updatedUser.authData = user.authData + } + return updatedUser + } + + func applyUpdate(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects don't match") + } + return try applyDefaultUpdate(object) + } } // MARK: Convenience @@ -153,6 +169,27 @@ public extension ParseUser { } } +// MARK: SignupLoginBody +struct SignupLoginBody: ParseType { + var username: String? + var password: String? + var authData: [String: [String: String]?]? + + init(username: String, password: String) { + self.username = username + self.password = password + } + + init(authData: [String: [String: String]?]) { + self.authData = authData + } +} + +// MARK: EmailBody +struct EmailBody: ParseType { + let email: String +} + // MARK: Logging In extension ParseUser { @@ -1046,7 +1083,7 @@ extension ParseUser { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } if isSaved { - return try replaceCommand() // Should be switched to "updateCommand" when server supports PATCH. + return try replaceCommand() // MARK: Should be switched to "updateCommand" when server supports PATCH. } return createCommand() } @@ -1087,8 +1124,14 @@ extension ParseUser { } #endif } - let mapper = { (data) -> Self in - try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + let mapper = { (data: Data) -> Self in + let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + // MARK: The lines below should be removed when server supports PATCH. + guard let current = Self.current, + current.hasSameObjectId(as: object) == true else { + return object + } + return try object.applyUpdate(current) } return API.Command(method: .PUT, path: endpoint, @@ -1116,8 +1159,13 @@ extension ParseUser { } #endif } - let mapper = { (data) -> Self in - try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + let mapper = { (data: Data) -> Self in + let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + guard let current = Self.current, + current.hasSameObjectId(as: object) == true else { + return object + } + return try object.applyUpdate(current) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Sources/ParseSwift/Types/ParseConfig.swift b/Sources/ParseSwift/Types/ParseConfig.swift index 7a7e4116b..355b95ec8 100644 --- a/Sources/ParseSwift/Types/ParseConfig.swift +++ b/Sources/ParseSwift/Types/ParseConfig.swift @@ -105,7 +105,7 @@ extension ParseConfig { internal func updateCommand() -> API.Command, Bool> { let body = ConfigUpdateBody(params: self) - return API.Command(method: .PUT, // Should be switched to ".PATCH" when server supports PATCH. + return API.Command(method: .PUT, // MARK: Should be switched to ".PATCH" when server supports PATCH. path: .config, body: body) { (data) -> Bool in let updated = try ParseCoding.jsonDecoder().decode(ConfigUpdateResponse.self, from: data).result diff --git a/Sources/ParseSwift/Types/ParseOperation.swift b/Sources/ParseSwift/Types/ParseOperation.swift index ef732b706..f4a6af2ac 100644 --- a/Sources/ParseSwift/Types/ParseOperation.swift +++ b/Sources/ParseSwift/Types/ParseOperation.swift @@ -427,7 +427,7 @@ extension ParseOperation { } func saveCommand() throws -> API.NonParseBodyCommand, T> { - // Should be switched to ".PATCH" when server supports PATCH. + // MARK: Should be switched to ".PATCH" when server supports PATCH. API.NonParseBodyCommand(method: .PUT, path: target.endpoint, body: self) { try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: $0).apply(to: self.target) } diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index c0e236fb1..95b8d812d 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -44,7 +44,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var levels: [Level]? var nextLevel: Level? - //custom initializers + //: custom initializers init() {} init(objectId: String?) { @@ -58,6 +58,32 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length self.points = points self.player = name } + + //: Implement your own version of applyUpdate + func applyUpdate(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects don't match") + } + var updated = self + if isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if isRestoreOriginalKey(\.level, + original: object) { + updated.level = object.level + } + if isRestoreOriginalKey(\.levels, + original: object) { + updated.levels = object.levels + } + if isRestoreOriginalKey(\.nextLevel, + original: object) { + updated.nextLevel = object.nextLevel + } + return updated + } } struct Game: ParseObject { @@ -97,7 +123,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var profilePicture: ParseFile? } - class GameScoreClass: ParseObject { + final class GameScoreClass: ParseObject { //: These are required by ParseObject var objectId: String? @@ -156,7 +182,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length } } - class GameClass: ParseObject { + final class GameClass: ParseObject { //: These are required by ParseObject var objectId: String? @@ -330,6 +356,18 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length XCTAssertEqual(score.id, objectId) } + func testIsRestoreOriginalKey() throws { + let score1 = GameScore(points: 5) + var score2 = GameScore(points: 5, name: "world") + score2.levels = [Level()] + score2.nextLevel = Level() + XCTAssertFalse(score1.isRestoreOriginalKey(\.player, original: score2)) + XCTAssertTrue(score1.isRestoreOriginalKey(\.levels, original: score2)) + XCTAssertFalse(score1.isRestoreOriginalKey(\.points, original: score2)) + XCTAssertFalse(score1.isRestoreOriginalKey(\.level, original: score2)) + XCTAssertTrue(score1.isRestoreOriginalKey(\.nextLevel, original: score2)) + } + func testParseObjectMutable() throws { var score = GameScore(points: 19, name: "fire") score.objectId = "yolo" From 347bdfcc694db47c2e60c9581a3f8bb40ed30e45 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 13:13:12 -0500 Subject: [PATCH 02/26] add tests and Playgrounds --- .../Contents.swift | 24 ++++ .../Contents.swift | 12 +- .../Contents.swift | 20 ++- .../Contents.swift | 32 ++++- .../Contents.swift | 16 ++- .../Contents.swift | 12 +- .../Contents.swift | 24 +++- .../Contents.swift | 20 ++- .../Contents.swift | 18 +++ .../Contents.swift | 22 ++++ .../Contents.swift | 12 +- .../Contents.swift | 32 +++++ .../5 - ACL.xcplaygroundpage/Contents.swift | 10 +- .../Contents.swift | 15 ++- .../Contents.swift | 10 ++ .../Contents.swift | 33 ++++- .../9 - Files.xcplaygroundpage/Contents.swift | 18 +++ .../Objects/ParseInstallation.swift | 72 +++++------ Sources/ParseSwift/Objects/ParseObject.swift | 26 ++-- Sources/ParseSwift/Objects/ParseUser.swift | 36 ++---- .../ParseInstallationTests.swift | 121 +++++++++++++++++- Tests/ParseSwiftTests/ParseObjectTests.swift | 61 ++++++--- Tests/ParseSwiftTests/ParseUserTests.swift | 106 ++++++++++++++- 23 files changed, 644 insertions(+), 108 deletions(-) diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index a351d575f..5631eeba7 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -40,6 +40,16 @@ struct GameScore: ParseObject, ParseObjectMutable { //: Your own properties. var points: Int = 0 + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension @@ -68,6 +78,20 @@ struct GameData: ParseObject { //: `ParseBytes` needs to be a part of the original schema //: or else you will need your masterKey to force an upgrade. var bytes: ParseBytes? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if isRestoreOriginalKey(\.polygon, + original: object) { + updated.polygon = object.polygon + } + if isRestoreOriginalKey(\.points, + original: object) { + updated.bytes = object.bytes + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift index 856679440..a53d4b976 100644 --- a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift @@ -109,7 +109,17 @@ struct GameScore: ParseObject { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift index 3154d31aa..2273a393d 100644 --- a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift @@ -19,9 +19,27 @@ struct GameScore: ParseObject { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? var location: ParseGeoPoint? var name: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.location, + original: object) { + updated.location = object.location + } + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index d243cef54..ab22628b2 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -30,6 +30,16 @@ struct User: ParseUser { //: Your custom keys. var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } struct Role: ParseRole { @@ -44,6 +54,16 @@ struct Role: ParseRole { //: Provided by Role. var name: String + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } + init() { self.name = "" } @@ -59,7 +79,17 @@ struct GameScore: ParseObject, ParseObjectMutable { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift index 16689aed5..0cf83919a 100644 --- a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift @@ -22,8 +22,22 @@ struct GameScore: ParseObject { var score: Double? //: Your own properties. - var points: Int? = 0 + var points: Int? var name: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift index 23df3fd09..1263ae3bf 100644 --- a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift @@ -30,7 +30,17 @@ struct GameScore: ParseObject, ParseObjectMutable { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift index d5f2ffaa2..84930b038 100644 --- a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift @@ -28,10 +28,32 @@ struct GameScore: ParseObject { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? var location: ParseGeoPoint? var name: String? var myFiles: [ParseFile]? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + if updated.isRestoreOriginalKey(\.myFiles, + original: object) { + updated.myFiles = object.myFiles + } + if updated.isRestoreOriginalKey(\.location, + original: object) { + updated.location = object.location + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift index 97387ff9b..9ee4d7312 100644 --- a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift @@ -29,9 +29,27 @@ struct GameScore: ParseObject { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? var location: ParseGeoPoint? var name: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + if updated.isRestoreOriginalKey(\.location, + original: object) { + updated.location = object.location + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift index 09ba11f95..fb74c632f 100644 --- a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift @@ -30,6 +30,24 @@ struct GameScore: ParseObject { var points: Int = 0 var location: ParseGeoPoint? var name: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + if updated.isRestoreOriginalKey(\.location, + original: object) { + updated.location = object.location + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift index 60d89dd4b..d668a3bea 100644 --- a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift @@ -25,6 +25,28 @@ struct GameScore: ParseObject { var timeStamp: Date? = Date() var oldScore: Int? var isHighest: Bool? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.timeStamp, + original: object) { + updated.timeStamp = object.timeStamp + } + if updated.isRestoreOriginalKey(\.oldScore, + original: object) { + updated.oldScore = object.oldScore + } + if updated.isRestoreOriginalKey(\.isHighest, + original: object) { + updated.isHighest = object.isHighest + } + return updated + } } var score = GameScore() diff --git a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift index c912a6568..2a50dd642 100644 --- a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift @@ -13,7 +13,7 @@ PlaygroundPage.current.needsIndefiniteExecution = true import ParseSwift initializeParse() -struct User: ParseUser { +struct User: ParseUser, ParseObjectMutable { //: These are required by `ParseObject`. var objectId: String? var createdAt: Date? @@ -30,6 +30,16 @@ struct User: ParseUser { //: Your custom keys. var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } /*: Sign up user asynchronously - Performs work on background diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index a74b11cef..9afadd7ce 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -33,6 +33,28 @@ struct User: ParseUser, ParseObjectMutable { var gameScore: GameScore? var targetScore: GameScore? var allScores: [GameScore]? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + if updated.isRestoreOriginalKey(\.gameScore, + original: object) { + updated.gameScore = object.gameScore + } + if updated.isRestoreOriginalKey(\.targetScore, + original: object) { + updated.targetScore = object.targetScore + } + if updated.isRestoreOriginalKey(\.allScores, + original: object) { + updated.allScores = object.allScores + } + return updated + } } //: It's recommended to place custom initializers in an extension @@ -57,6 +79,16 @@ struct GameScore: ParseObject { //: Your own properties. var points: Int? = 0 + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift index 4ea392cb0..140ff0ac5 100644 --- a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift @@ -34,8 +34,14 @@ struct GameScore: ParseObject { //: Your own properties var points: Int - init() { - self.points = 0 + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated } } diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index a88656635..afc0ac072 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -13,7 +13,7 @@ import ParseSwift PlaygroundPage.current.needsIndefiniteExecution = true initializeParse() -struct Installation: ParseInstallation { +struct Installation: ParseInstallation, ParseObjectMutable { //: These are required by `ParseObject`. var objectId: String? var createdAt: Date? @@ -36,6 +36,16 @@ struct Installation: ParseInstallation { //: Your custom keys var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } /*: Save your first `customKey` value to your `ParseInstallation`. @@ -60,7 +70,8 @@ currentInstallation?.save { results in designated callbackQueue. If no callbackQueue is specified it returns to main queue. */ -var installationToUpdate = Installation.current +let originalInstallation = Installation.current +var installationToUpdate = originalInstallation?.mutable installationToUpdate?.customKey = "myCustomInstallationKey2" installationToUpdate?.save { results in diff --git a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift index c2ceb9753..24c608a95 100644 --- a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift @@ -25,6 +25,16 @@ struct GameScore: ParseObject { //: Your own properties var points: Int? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index 91fe04ca3..adeb32ee2 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -25,6 +25,16 @@ struct Book: ParseObject { //: Your own properties. var title: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.title, + original: object) { + updated.title = object.title + } + return updated + } } //: It's recommended to place custom initializers in an extension @@ -45,13 +55,26 @@ struct Author: ParseObject { var score: Double? //: Your own properties. - var name: String - var book: Book + var name: String? + var book: Book? var otherBooks: [Book]? - init() { - self.name = "hello" - self.book = Book() + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.name, + original: object) { + updated.name = object.name + } + if updated.isRestoreOriginalKey(\.book, + original: object) { + updated.book = object.book + } + if updated.isRestoreOriginalKey(\.otherBooks, + original: object) { + updated.otherBooks = object.otherBooks + } + return updated } } diff --git a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift index b0225d7ce..f1733e64f 100644 --- a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift @@ -26,6 +26,24 @@ struct GameScore: ParseObject { var points: Int = 0 var profilePicture: ParseFile? var myData: ParseFile? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + if updated.isRestoreOriginalKey(\.profilePicture, + original: object) { + updated.profilePicture = object.profilePicture + } + if updated.isRestoreOriginalKey(\.myData, + original: object) { + updated.myData = object.myData + } + return updated + } } //: It's recommended to place custom initializers in an extension diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index c2de57b8f..493b8721d 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -88,14 +88,6 @@ public protocol ParseInstallation: ParseObject { The locale identifier for the `ParseInstallation`. */ var localeIdentifier: String? { get set } - - /** - Updates a `ParseInstallation` with all keys that have been modified. - - parameter installation: The original installation. - - returns: The updated installation. - - throws: An error of type `ParseError`. - */ - func applyDefaultUpdate(_ installation: Self) throws -> Self } // MARK: Default Implementations @@ -104,65 +96,61 @@ public extension ParseInstallation { "_Installation" } - func applyDefaultUpdate(_ installation: Self) throws -> Self { - guard hasSameObjectId(as: installation) == true else { + func mergeParse(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { throw ParseError(code: .unknownError, message: "objectId's of objects don't match") } var updatedInstallation = self if isRestoreOriginalKey(\.deviceType, - original: installation) { - updatedInstallation.deviceType = installation.deviceType + original: object) { + updatedInstallation.deviceType = object.deviceType } - if isRestoreOriginalKey(\.deviceType, - original: installation) { - updatedInstallation.installationId = installation.installationId + if isRestoreOriginalKey(\.installationId, + original: object) { + updatedInstallation.installationId = object.installationId } - if isRestoreOriginalKey(\.deviceType, - original: installation) { - updatedInstallation.deviceToken = installation.deviceToken + if isRestoreOriginalKey(\.deviceToken, + original: object) { + updatedInstallation.deviceToken = object.deviceToken } if isRestoreOriginalKey(\.badge, - original: installation) { - updatedInstallation.badge = installation.badge + original: object) { + updatedInstallation.badge = object.badge } if isRestoreOriginalKey(\.timeZone, - original: installation) { - updatedInstallation.timeZone = installation.timeZone + original: object) { + updatedInstallation.timeZone = object.timeZone } if isRestoreOriginalKey(\.channels, - original: installation) { - updatedInstallation.channels = installation.channels + original: object) { + updatedInstallation.channels = object.channels } if isRestoreOriginalKey(\.appName, - original: installation) { - updatedInstallation.appName = installation.appName + original: object) { + updatedInstallation.appName = object.appName } if isRestoreOriginalKey(\.appIdentifier, - original: installation) { - updatedInstallation.appIdentifier = installation.appIdentifier + original: object) { + updatedInstallation.appIdentifier = object.appIdentifier } if isRestoreOriginalKey(\.appVersion, - original: installation) { - updatedInstallation.appVersion = installation.appVersion + original: object) { + updatedInstallation.appVersion = object.appVersion } if isRestoreOriginalKey(\.parseVersion, - original: installation) { - updatedInstallation.parseVersion = installation.parseVersion + original: object) { + updatedInstallation.parseVersion = object.parseVersion } if isRestoreOriginalKey(\.localeIdentifier, - original: installation) { - updatedInstallation.localeIdentifier = installation.localeIdentifier + original: object) { + updatedInstallation.localeIdentifier = object.localeIdentifier } return updatedInstallation } - func applyUpdate(_ object: Self) throws -> Self { - guard hasSameObjectId(as: object) == true else { - throw ParseError(code: .unknownError, - message: "objectId's of objects don't match") - } - return try applyDefaultUpdate(object) + func merge(_ object: Self) throws -> Self { + try mergeParse(object) } } @@ -781,7 +769,7 @@ extension ParseInstallation { current.hasSameObjectId(as: object) == true else { return object } - return try object.applyUpdate(current) + return try object.merge(current) } return API.Command(method: .PUT, path: endpoint, @@ -800,7 +788,7 @@ extension ParseInstallation { current.hasSameObjectId(as: object) == true else { return object } - return try object.applyUpdate(current) + return try object.merge(current) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 3b9a144ca..919588ddc 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -61,13 +61,21 @@ public protocol ParseObject: Objectable, func isRestoreOriginalKey(_ key: KeyPath, original: Self) -> Bool where W: Equatable + /** + Updates a `ParseObject` with all keys that have been modified. + - parameter object: The original installation. + - returns: The updated installation. + - throws: An error of type `ParseError`. + */ + func mergeParse(_ object: Self) throws -> Self + /** Updates a `ParseObject` with all keys that have been modified. - parameter object: The original object. - returns: The updated object. - throws: An error of type `ParseError`. */ - func applyUpdate(_ object: Self) throws -> Self + func merge(_ object: Self) throws -> Self } // MARK: Default Implementations @@ -101,21 +109,23 @@ public extension ParseObject { func toPointer() throws -> Pointer { return try Pointer(self) } -/* - func isRestoreOriginalKey(_ key: KeyPath, - original: Self, - updated: Self) -> Bool where W: Equatable { - updated[keyPath: key] == nil && original[keyPath: key] != updated[keyPath: key] - }*/ func isRestoreOriginalKey(_ key: KeyPath, original: Self) -> Bool where W: Equatable { self[keyPath: key] == nil && original[keyPath: key] != self[keyPath: key] } - func applyUpdate(_ object: Self) throws -> Self { + func mergeParse(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { + throw ParseError(code: .unknownError, + message: "objectId's of objects don't match") + } return self } + + func merge(_ object: Self) throws -> Self { + return try mergeParse(object) + } } // MARK: Batch Support diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index 98fca650d..6e823e877 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -35,14 +35,6 @@ public protocol ParseUser: ParseObject { or any authentication type that conforms to `ParseAuthentication`. */ var authData: [String: [String: String]?]? { get set } - - /** - Updates a `ParseUser` with all keys that have been modified. - - parameter user: The original user. - - returns: The updated user. - - throws: An error of type `ParseError`. - */ - func applyDefaultUpdate(_ user: Self) throws -> Self } // MARK: Default Implementations @@ -51,33 +43,29 @@ public extension ParseUser { "_User" } - func applyDefaultUpdate(_ user: Self) throws -> Self { - guard hasSameObjectId(as: user) == true else { + func mergeParse(_ object: Self) throws -> Self { + guard hasSameObjectId(as: object) == true else { throw ParseError(code: .unknownError, message: "objectId's of objects do not match") } var updatedUser = self if isRestoreOriginalKey(\.username, - original: user) { - updatedUser.username = user.username + original: object) { + updatedUser.username = object.username } if isRestoreOriginalKey(\.email, - original: user) { - updatedUser.email = user.email + original: object) { + updatedUser.email = object.email } if isRestoreOriginalKey(\.authData, - original: user) { - updatedUser.authData = user.authData + original: object) { + updatedUser.authData = object.authData } return updatedUser } - func applyUpdate(_ object: Self) throws -> Self { - guard hasSameObjectId(as: object) == true else { - throw ParseError(code: .unknownError, - message: "objectId's of objects don't match") - } - return try applyDefaultUpdate(object) + func merge(_ object: Self) throws -> Self { + try mergeParse(object) } } @@ -1131,7 +1119,7 @@ extension ParseUser { current.hasSameObjectId(as: object) == true else { return object } - return try object.applyUpdate(current) + return try object.merge(current) } return API.Command(method: .PUT, path: endpoint, @@ -1165,7 +1153,7 @@ extension ParseUser { current.hasSameObjectId(as: object) == true else { return object } - return try object.applyUpdate(current) + return try object.merge(current) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index 81f30d2e3..c17f73cfe 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -64,7 +64,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l } } - struct Installation: ParseInstallation { + struct Installation: ParseInstallation, ParseObjectMutable { var installationId: String? var deviceType: String? var deviceToken: String? @@ -82,6 +82,16 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var ACL: ParseACL? var score: Double? var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } let testInstallationObjectId = "yarr" @@ -255,6 +265,38 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l } #endif + func testMerge() throws { + guard var original = Installation.current else { + XCTFail("Should have unwrapped") + return + } + original.objectId = "yolo" + original.createdAt = Date() + original.updatedAt = Date() + original.badge = 10 + + var updated = original.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.badge = 1 + updated.deviceToken = "12345" + updated.customKey = "newKey" + let merged = try updated.merge(original) + XCTAssertEqual(merged.customKey, updated.customKey) + XCTAssertEqual(merged.badge, updated.badge) + XCTAssertEqual(merged.deviceType, original.deviceType) + XCTAssertEqual(merged.deviceToken, updated.deviceToken) + XCTAssertEqual(merged.channels, original.channels) + XCTAssertEqual(merged.installationId, original.installationId) + XCTAssertEqual(merged.timeZone, original.timeZone) + XCTAssertEqual(merged.appName, original.appName) + XCTAssertEqual(merged.appVersion, original.appVersion) + XCTAssertEqual(merged.appIdentifier, original.appIdentifier) + XCTAssertEqual(merged.parseVersion, original.parseVersion) + XCTAssertEqual(merged.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(merged.createdAt, original.createdAt) + XCTAssertEqual(merged.updatedAt, updated.updatedAt) + } + func testUpdate() { var installation = Installation() installation.objectId = testInstallationObjectId @@ -387,6 +429,83 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l } } + func testSaveMutableMergeCurrentInstallation() throws { + // Save current Installation + try testSaveCurrentInstallation() + MockURLProtocol.removeAll() + + guard let original = Installation.current else { + XCTFail("Should unwrap") + return + } + var response = original.mutable + response.createdAt = nil + response.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try response.getEncoder().encode(response, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + response = try response.getDecoder().decode(Installation.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + var updated = original.mutable + updated.customKey = "hello" + updated.deviceToken = "1234" + + do { + let saved = try updated.save() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentInstallation = Installation.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameInstallationId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.customKey, updated.customKey) + XCTAssertEqual(saved.badge, original.badge) + XCTAssertEqual(saved.deviceType, original.deviceType) + XCTAssertEqual(saved.deviceToken, updated.deviceToken) + XCTAssertEqual(saved.channels, original.channels) + XCTAssertEqual(saved.installationId, original.installationId) + XCTAssertEqual(saved.timeZone, original.timeZone) + XCTAssertEqual(saved.appName, original.appName) + XCTAssertEqual(saved.appVersion, original.appVersion) + XCTAssertEqual(saved.appIdentifier, original.appIdentifier) + XCTAssertEqual(saved.parseVersion, original.parseVersion) + XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.customKey, newCurrentInstallation.customKey) + XCTAssertEqual(saved.badge, newCurrentInstallation.badge) + XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) + XCTAssertEqual(saved.deviceToken, newCurrentInstallation.deviceToken) + XCTAssertEqual(saved.channels, newCurrentInstallation.channels) + XCTAssertEqual(saved.installationId, newCurrentInstallation.installationId) + XCTAssertEqual(saved.timeZone, newCurrentInstallation.timeZone) + XCTAssertEqual(saved.appName, newCurrentInstallation.appName) + XCTAssertEqual(saved.appVersion, newCurrentInstallation.appVersion) + XCTAssertEqual(saved.appIdentifier, newCurrentInstallation.appIdentifier) + XCTAssertEqual(saved.parseVersion, newCurrentInstallation.parseVersion) + XCTAssertEqual(saved.localeIdentifier, newCurrentInstallation.localeIdentifier) + XCTAssertEqual(saved.createdAt, newCurrentInstallation.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentInstallation.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + func testSaveCurrentInstallationWithDefaultACL() throws { try userLogin() guard let userObjectId = User.current?.objectId else { diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index 95b8d812d..5f3453c47 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -59,27 +59,23 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length self.player = name } - //: Implement your own version of applyUpdate - func applyUpdate(_ object: Self) throws -> Self { - guard hasSameObjectId(as: object) == true else { - throw ParseError(code: .unknownError, - message: "objectId's of objects don't match") - } - var updated = self - if isRestoreOriginalKey(\.points, - original: object) { + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { updated.points = object.points } - if isRestoreOriginalKey(\.level, - original: object) { + if updated.isRestoreOriginalKey(\.level, + original: object) { updated.level = object.level } - if isRestoreOriginalKey(\.levels, - original: object) { + if updated.isRestoreOriginalKey(\.levels, + original: object) { updated.levels = object.levels } - if isRestoreOriginalKey(\.nextLevel, - original: object) { + if updated.isRestoreOriginalKey(\.nextLevel, + original: object) { updated.nextLevel = object.nextLevel } return updated @@ -377,6 +373,41 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length XCTAssertEqual(score.createdAt, empty.createdAt) } + func testMerge() throws { + var score = GameScore(points: 19, name: "fire") + score.objectId = "yolo" + score.createdAt = Date() + score.updatedAt = Date() + var level = Level() + level.objectId = "hello" + var level2 = Level() + level2.objectId = "world" + score.level = level + score.levels = [level] + score.nextLevel = level2 + var updated = score.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.points = 30 + updated.player = "moreFire" + updated.levels = [level, level2] + let merged = try updated.merge(score) + XCTAssertEqual(merged.points, updated.points) + XCTAssertEqual(merged.player, updated.player) + XCTAssertEqual(merged.level, score.level) + XCTAssertEqual(merged.levels, updated.levels) + XCTAssertEqual(merged.nextLevel, score.nextLevel) + XCTAssertEqual(merged.createdAt, score.createdAt) + XCTAssertEqual(merged.updatedAt, updated.updatedAt) + } + + func testMergeDifferentObjectId() throws { + var score = GameScore(points: 19, name: "fire") + score.objectId = "yolo" + var score2 = score + score2.objectId = "nolo" + XCTAssertThrowsError(try score2.merge(score)) + } + func testFetchCommand() { var score = GameScore(points: 10) let className = score.className diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index bccaded4c..2a641db51 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -12,7 +12,7 @@ import XCTest class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length - struct User: ParseUser { + struct User: ParseUser, ParseObjectMutable { //: These are required by ParseObject var objectId: String? @@ -30,6 +30,16 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length // Your custom keys var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } struct LoginSignupResponse: ParseUser { @@ -100,6 +110,35 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length try ParseStorage.shared.deleteAll() } + func testMerge() throws { + // Signup current User + XCTAssertNil(User.current?.objectId) + try userSignUp() + XCTAssertNotNil(User.current?.objectId) + + guard var original = User.current else { + XCTFail("Should have unwrapped") + return + } + original.objectId = "yolo" + original.createdAt = Date() + original.updatedAt = Date() + + var updated = original.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.email = "swift@parse.com" + updated.username = "12345" + updated.customKey = "newKey" + let merged = try updated.merge(original) + XCTAssertEqual(merged.customKey, updated.customKey) + XCTAssertEqual(merged.email, updated.email) + XCTAssertEqual(merged.emailVerified, original.emailVerified) + XCTAssertEqual(merged.username, updated.username) + XCTAssertEqual(merged.authData, original.authData) + XCTAssertEqual(merged.createdAt, original.createdAt) + XCTAssertEqual(merged.updatedAt, updated.updatedAt) + } + func testFetchCommand() { var user = User() XCTAssertThrowsError(try user.fetchCommand(include: nil)) @@ -745,6 +784,71 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length } } + func testSaveMutableMergeCurrentUser() throws { + // Signup current User + XCTAssertNil(User.current?.objectId) + try userSignUp() + XCTAssertNotNil(User.current?.objectId) + + guard let original = User.current else { + XCTFail("Should unwrap") + return + } + var response = original.mutable + response.createdAt = nil + response.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try response.getEncoder().encode(response, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + response = try response.getDecoder().decode(User.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + var updated = original.mutable + updated.customKey = "beast" + updated.username = "mode" + + do { + let saved = try updated.save() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentUser = User.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentUser)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.customKey, updated.customKey) + XCTAssertEqual(saved.email, original.email) + XCTAssertEqual(saved.username, updated.username) + XCTAssertEqual(saved.emailVerified, original.emailVerified) + XCTAssertEqual(saved.password, original.password) + XCTAssertEqual(saved.authData, original.authData) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.customKey, newCurrentUser.customKey) + XCTAssertEqual(saved.email, newCurrentUser.email) + XCTAssertEqual(saved.username, newCurrentUser.username) + XCTAssertEqual(saved.emailVerified, newCurrentUser.emailVerified) + XCTAssertEqual(saved.password, newCurrentUser.password) + XCTAssertEqual(saved.authData, newCurrentUser.authData) + XCTAssertEqual(saved.createdAt, newCurrentUser.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentUser.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + func testSaveAsyncAndUpdateCurrentUser() throws { // swiftlint:disable:this function_body_length XCTAssertNil(User.current?.objectId) try userSignUp() From 4fb838e8ade454bc268cf5d1961be4d97fa797db Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 13:33:27 -0500 Subject: [PATCH 03/26] nit --- .../Pages/6 - Installation.xcplaygroundpage/Contents.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index afc0ac072..f262e9b9c 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -70,8 +70,7 @@ currentInstallation?.save { results in designated callbackQueue. If no callbackQueue is specified it returns to main queue. */ -let originalInstallation = Installation.current -var installationToUpdate = originalInstallation?.mutable +var installationToUpdate = Installation.current?.mutable installationToUpdate?.customKey = "myCustomInstallationKey2" installationToUpdate?.save { results in From df836f0d8202630d43466e0f2bb1d376d1522d07 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 20:02:28 -0500 Subject: [PATCH 04/26] add ACL to default implementation --- .../Objects/ParseInstallation.swift | 4 ++ Sources/ParseSwift/Objects/ParseObject.swift | 7 ++- Sources/ParseSwift/Objects/ParseUser.swift | 4 ++ .../ParseInstallationTests.swift | 48 +++++++++++++++++++ Tests/ParseSwiftTests/ParseObjectTests.swift | 21 +++++++- Tests/ParseSwiftTests/ParseUserTests.swift | 44 +++++++++++++++++ 6 files changed, 126 insertions(+), 2 deletions(-) diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 493b8721d..4d3106a45 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -102,6 +102,10 @@ public extension ParseInstallation { message: "objectId's of objects don't match") } var updatedInstallation = self + if isRestoreOriginalKey(\.ACL, + original: object) { + updatedInstallation.ACL = object.ACL + } if isRestoreOriginalKey(\.deviceType, original: object) { updatedInstallation.deviceType = object.deviceType diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 919588ddc..2430d4ea2 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -120,7 +120,12 @@ public extension ParseObject { throw ParseError(code: .unknownError, message: "objectId's of objects don't match") } - return self + var updated = self + if isRestoreOriginalKey(\.ACL, + original: object) { + updated.ACL = object.ACL + } + return updated } func merge(_ object: Self) throws -> Self { diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index 6e823e877..54fcc0740 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -49,6 +49,10 @@ public extension ParseUser { message: "objectId's of objects do not match") } var updatedUser = self + if isRestoreOriginalKey(\.ACL, + original: object) { + updatedUser.ACL = object.ACL + } if isRestoreOriginalKey(\.username, original: object) { updatedUser.username = object.username diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index c17f73cfe..bc6645c45 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -274,6 +274,9 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l original.createdAt = Date() original.updatedAt = Date() original.badge = 10 + var acl = ParseACL() + acl.publicRead = true + original.ACL = acl var updated = original.mutable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -293,10 +296,55 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l XCTAssertEqual(merged.appIdentifier, original.appIdentifier) XCTAssertEqual(merged.parseVersion, original.parseVersion) XCTAssertEqual(merged.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(merged.ACL, original.ACL) XCTAssertEqual(merged.createdAt, original.createdAt) XCTAssertEqual(merged.updatedAt, updated.updatedAt) } + func testMerge2() throws { + guard var original = Installation.current else { + XCTFail("Should have unwrapped") + return + } + original.objectId = "yolo" + original.createdAt = Date() + original.updatedAt = Date() + original.badge = 10 + original.deviceToken = "bruh" + original.channels = ["halo"] + var acl = ParseACL() + acl.publicRead = true + original.ACL = acl + + var updated = original.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.customKey = "newKey" + let merged = try updated.merge(original) + XCTAssertEqual(merged.customKey, updated.customKey) + XCTAssertEqual(merged.badge, original.badge) + XCTAssertEqual(merged.deviceType, original.deviceType) + XCTAssertEqual(merged.deviceToken, original.deviceToken) + XCTAssertEqual(merged.channels, original.channels) + XCTAssertEqual(merged.installationId, original.installationId) + XCTAssertEqual(merged.timeZone, original.timeZone) + XCTAssertEqual(merged.appName, original.appName) + XCTAssertEqual(merged.appVersion, original.appVersion) + XCTAssertEqual(merged.appIdentifier, original.appIdentifier) + XCTAssertEqual(merged.parseVersion, original.parseVersion) + XCTAssertEqual(merged.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(merged.ACL, original.ACL) + XCTAssertEqual(merged.createdAt, original.createdAt) + XCTAssertEqual(merged.updatedAt, updated.updatedAt) + } + + func testMergeDifferentObjectId() throws { + var installation = Installation() + installation.objectId = "yolo" + var installation2 = installation + installation2.objectId = "nolo" + XCTAssertThrowsError(try installation2.merge(installation)) + } + func testUpdate() { var installation = Installation() installation.objectId = testInstallationObjectId diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index 5f3453c47..a0d17407f 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -82,7 +82,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length } } - struct Game: ParseObject { + struct Game: ParseObject, ParseObjectMutable { //: These are required by ParseObject var objectId: String? var createdAt: Date? @@ -378,6 +378,9 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length score.objectId = "yolo" score.createdAt = Date() score.updatedAt = Date() + var acl = ParseACL() + acl.publicRead = true + score.ACL = acl var level = Level() level.objectId = "hello" var level2 = Level() @@ -396,10 +399,26 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length XCTAssertEqual(merged.level, score.level) XCTAssertEqual(merged.levels, updated.levels) XCTAssertEqual(merged.nextLevel, score.nextLevel) + XCTAssertEqual(merged.ACL, score.ACL) XCTAssertEqual(merged.createdAt, score.createdAt) XCTAssertEqual(merged.updatedAt, updated.updatedAt) } + func testMergeDefaultImplementation() throws { + var score = Game() + score.objectId = "yolo" + score.createdAt = Date() + score.updatedAt = Date() + var updated = score.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.name = "moreFire" + let merged = try updated.merge(score) + XCTAssertEqual(merged.name, updated.name) + XCTAssertEqual(merged.gameScore, score.gameScore) + XCTAssertEqual(merged.gameScores, score.gameScores) + XCTAssertEqual(merged.profilePicture, updated.profilePicture) + } + func testMergeDifferentObjectId() throws { var score = GameScore(points: 19, name: "fire") score.objectId = "yolo" diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index 2a641db51..b8f9e5428 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -123,6 +123,10 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length original.objectId = "yolo" original.createdAt = Date() original.updatedAt = Date() + original.authData = ["hello": ["world": "yolo"]] + var acl = ParseACL() + acl.publicRead = true + original.ACL = acl var updated = original.mutable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -135,10 +139,50 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length XCTAssertEqual(merged.emailVerified, original.emailVerified) XCTAssertEqual(merged.username, updated.username) XCTAssertEqual(merged.authData, original.authData) + XCTAssertEqual(merged.ACL, original.ACL) XCTAssertEqual(merged.createdAt, original.createdAt) XCTAssertEqual(merged.updatedAt, updated.updatedAt) } + func testMerge2() throws { + // Signup current User + XCTAssertNil(User.current?.objectId) + try userSignUp() + XCTAssertNotNil(User.current?.objectId) + + guard var original = User.current else { + XCTFail("Should have unwrapped") + return + } + original.objectId = "yolo" + original.createdAt = Date() + original.updatedAt = Date() + var acl = ParseACL() + acl.publicRead = true + original.ACL = acl + + var updated = original.mutable + updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + updated.customKey = "newKey" + let merged = try updated.merge(original) + XCTAssertEqual(merged.customKey, updated.customKey) + XCTAssertEqual(merged.email, original.email) + XCTAssertEqual(merged.emailVerified, original.emailVerified) + XCTAssertEqual(merged.username, original.username) + XCTAssertEqual(merged.authData, original.authData) + XCTAssertEqual(merged.ACL, original.ACL) + XCTAssertEqual(merged.createdAt, original.createdAt) + XCTAssertEqual(merged.updatedAt, updated.updatedAt) + } + + func testMergeDifferentObjectId() throws { + var user = User() + user.objectId = "yolo" + var user2 = user + user2.objectId = "nolo" + XCTAssertThrowsError(try user2.merge(user)) + } + func testFetchCommand() { var user = User() XCTAssertThrowsError(try user.fetchCommand(include: nil)) From 68d5a93feeaaf55379fef5b93f09f68944ad63ca Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 20:43:24 -0500 Subject: [PATCH 05/26] test Patch merge --- .../ParseInstallationAsyncTests.swift | 91 ++++++++++++++++++- .../ParseSwiftTests/ParseUserAsyncTests.swift | 79 +++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 0b9d73cad..11923efbd 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -65,7 +65,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b } } - struct Installation: ParseInstallation { + struct Installation: ParseInstallation, ParseObjectMutable { var installationId: String? var deviceType: String? var deviceToken: String? @@ -83,6 +83,16 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var ACL: ParseACL? var score: Double? var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } let testInstallationObjectId = "yarr" @@ -386,6 +396,85 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b XCTAssertEqual(saved.updatedAt, serverResponse.updatedAt) } + func testUpdateMutableMergeCurrentInstallation() async throws { + // Save current Installation + try saveCurrentInstallation() + MockURLProtocol.removeAll() + + guard let original = Installation.current else { + XCTFail("Should unwrap") + return + } + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(Installation.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdate = original.mutable + originalUpdate.customKey = "hello" + originalUpdate.deviceToken = "1234" + let updated = originalUpdate + + do { + let saved = try await updated.update() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentInstallation = Installation.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameInstallationId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.customKey, updated.customKey) + XCTAssertEqual(saved.badge, original.badge) + XCTAssertEqual(saved.deviceType, original.deviceType) + XCTAssertEqual(saved.deviceToken, updated.deviceToken) + XCTAssertEqual(saved.channels, original.channels) + XCTAssertEqual(saved.installationId, original.installationId) + XCTAssertEqual(saved.timeZone, original.timeZone) + XCTAssertEqual(saved.appName, original.appName) + XCTAssertEqual(saved.appVersion, original.appVersion) + XCTAssertEqual(saved.appIdentifier, original.appIdentifier) + XCTAssertEqual(saved.parseVersion, original.parseVersion) + XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.customKey, newCurrentInstallation.customKey) + XCTAssertEqual(saved.badge, newCurrentInstallation.badge) + XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) + XCTAssertEqual(saved.deviceToken, newCurrentInstallation.deviceToken) + XCTAssertEqual(saved.channels, newCurrentInstallation.channels) + XCTAssertEqual(saved.installationId, newCurrentInstallation.installationId) + XCTAssertEqual(saved.timeZone, newCurrentInstallation.timeZone) + XCTAssertEqual(saved.appName, newCurrentInstallation.appName) + XCTAssertEqual(saved.appVersion, newCurrentInstallation.appVersion) + XCTAssertEqual(saved.appIdentifier, newCurrentInstallation.appIdentifier) + XCTAssertEqual(saved.parseVersion, newCurrentInstallation.parseVersion) + XCTAssertEqual(saved.localeIdentifier, newCurrentInstallation.localeIdentifier) + XCTAssertEqual(saved.createdAt, newCurrentInstallation.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentInstallation.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testUpdateClientMissingObjectId() async throws { var installation = Installation() diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index c7dd12467..98e5efb1f 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -13,7 +13,7 @@ import XCTest class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_length - struct User: ParseUser { + struct User: ParseUser, ParseObjectMutable { //: These are required by ParseObject var objectId: String? @@ -31,6 +31,16 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng // Your custom keys var customKey: String? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.customKey, + original: object) { + updated.customKey = object.customKey + } + return updated + } } struct LoginSignupResponse: ParseUser { @@ -706,6 +716,73 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng } } + func testUpdateMutableMergeCurrentUser() async throws { + // Signup current User + login() + MockURLProtocol.removeAll() + XCTAssertNotNil(User.current?.objectId) + + guard let original = User.current else { + XCTFail("Should unwrap") + return + } + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(User.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdated = original.mutable + originalUpdated.customKey = "beast" + originalUpdated.username = "mode" + let updated = originalUpdated + + do { + let saved = try await updated.update() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentUser = User.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentUser)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.customKey, updated.customKey) + XCTAssertEqual(saved.email, original.email) + XCTAssertEqual(saved.username, updated.username) + XCTAssertEqual(saved.emailVerified, original.emailVerified) + XCTAssertEqual(saved.password, original.password) + XCTAssertEqual(saved.authData, original.authData) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.customKey, newCurrentUser.customKey) + XCTAssertEqual(saved.email, newCurrentUser.email) + XCTAssertEqual(saved.username, newCurrentUser.username) + XCTAssertEqual(saved.emailVerified, newCurrentUser.emailVerified) + XCTAssertEqual(saved.password, newCurrentUser.password) + XCTAssertEqual(saved.authData, newCurrentUser.authData) + XCTAssertEqual(saved.createdAt, newCurrentUser.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentUser.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testDelete() async throws { login() From b3bca7475e02c5268c7b0c0a3b7214dad4435164 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 10 Jan 2022 21:10:10 -0500 Subject: [PATCH 06/26] update documentation --- .../Contents.swift | 2 +- Sources/ParseSwift/Objects/ParseObject.swift | 41 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 5631eeba7..0caee262b 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -39,7 +39,7 @@ struct GameScore: ParseObject, ParseObjectMutable { var score: Double? //: Your own properties. - var points: Int = 0 + var points: Int? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 2430d4ea2..f8557808f 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -62,18 +62,53 @@ public protocol ParseObject: Objectable, original: Self) -> Bool where W: Equatable /** - Updates a `ParseObject` with all keys that have been modified. + Merges two `ParseObject`'s resulting in modified and unchanged Parse keys. - parameter object: The original installation. - returns: The updated installation. - throws: An error of type `ParseError`. + - note: Use this in combination with `ParseMutable` to only send updated + keys to the server and then merge those changes with the original object. + - warning: You should only call this method and shouldn't implement it directly + as it's already implemented for developers to use. */ func mergeParse(_ object: Self) throws -> Self /** - Updates a `ParseObject` with all keys that have been modified. + Merges two `ParseObject`'s resulting in modified and unchanged keys. + + //: Create your own value typed `ParseObject`. + struct GameScore: ParseObject, ParseObjectMutable { + //: These are required by ParseObject + var objectId: String? + var createdAt: Date? + var updatedAt: Date? + var ACL: ParseACL? + var score: Double? + + //: Your own properties. + var points: Int? + + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.isRestoreOriginalKey(\.points, + original: object) { + updated.points = object.points + } + return updated + } + } + - parameter object: The original object. - - returns: The updated object. + - returns: The merged object. - throws: An error of type `ParseError`. + - note: Use this in combination with `ParseMutable` to only send updated + keys to the server and then merge those changes with the original object. + - important: It is recommend you provide an implementation of this method + for all of your `ParseObject`'s as the developer has access to all keys of a + `ParseObject`. You should always call `mergeParse` + in the beginning of your implementation to handle all default Parse keys. In addition, + use `isRestoreOriginalKey` to compare key modifications between objects. */ func merge(_ object: Self) throws -> Self } From e125b54e7f8e75ce59a5a8e090f84d0aaf758499 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Fri, 14 Jan 2022 12:34:17 -0500 Subject: [PATCH 07/26] merge ParseObjects automatically --- .../Contents.swift | 12 ++-- .../Contents.swift | 4 +- .../Contents.swift | 12 ++-- .../Contents.swift | 12 ++-- .../Contents.swift | 8 +-- .../Contents.swift | 4 +- .../Contents.swift | 16 ++--- .../Contents.swift | 12 ++-- .../Contents.swift | 12 ++-- .../Contents.swift | 16 ++--- .../Contents.swift | 4 +- .../Contents.swift | 18 ++--- .../5 - ACL.xcplaygroundpage/Contents.swift | 4 +- .../Contents.swift | 4 +- .../Contents.swift | 4 +- .../Contents.swift | 16 ++--- .../9 - Files.xcplaygroundpage/Contents.swift | 12 ++-- Sources/ParseSwift/API/API+Command.swift | 30 ++++++-- Sources/ParseSwift/Coding/ParseEncoder.swift | 14 +++- .../BaseParseInstallation.swift | 1 + .../InternalObjects/BaseParseUser.swift | 1 + .../Objects/ParseInstallation.swift | 70 ++++++++++--------- Sources/ParseSwift/Objects/ParseObject.swift | 30 +++++--- Sources/ParseSwift/Objects/ParseUser.swift | 40 ++++++----- .../Protocols/ParseObjectMutable.swift | 3 + Sources/ParseSwift/Types/ParseRelation.swift | 9 +++ Tests/ParseSwiftTests/APICommandTests.swift | 6 +- Tests/ParseSwiftTests/IOS13Tests.swift | 3 + .../ParseSwiftTests/InitializeSDKTests.swift | 1 + Tests/ParseSwiftTests/ParseACLTests.swift | 3 + .../ParseAnonymousAsyncTests.swift | 2 + .../ParseAnonymousCombineTests.swift | 2 + .../ParseSwiftTests/ParseAnonymousTests.swift | 2 + .../ParseAppleAsyncTests.swift | 2 + .../ParseAppleCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseAppleTests.swift | 2 + .../ParseAuthenticationAsyncTests.swift | 2 + .../ParseAuthenticationCombineTests.swift | 2 + .../ParseAuthenticationTests.swift | 2 + .../ParseConfigAsyncTests.swift | 2 + .../ParseConfigCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseConfigTests.swift | 2 + .../ParseEncoderExtraTests.swift | 1 + .../ParseFacebookAsyncTests.swift | 2 + .../ParseFacebookCombineTests.swift | 2 + .../ParseSwiftTests/ParseFacebookTests.swift | 2 + .../ParseGitHubCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseGitHubTests.swift | 2 + .../ParseGoogleCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseGoogleTests.swift | 2 + .../ParseInstallationAsyncTests.swift | 7 +- .../ParseInstallationCombineTests.swift | 3 + .../ParseInstallationTests.swift | 7 +- .../ParseSwiftTests/ParseLDAPAsyncTests.swift | 2 + .../ParseLDAPCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseLDAPTests.swift | 2 + .../ParseLinkedInCombineTests.swift | 2 + .../ParseSwiftTests/ParseLinkedInTests.swift | 2 + .../ParseSwiftTests/ParseLiveQueryTests.swift | 1 + .../ParseObjectAsyncTests.swift | 1 + .../ParseObjectBatchTests.swift | 2 + .../ParseObjectCombineTests.swift | 1 + .../ParseObjectCustomObjectIdTests.swift | 6 ++ Tests/ParseSwiftTests/ParseObjectTests.swift | 35 ++++++---- .../ParseOperationAsyncTests.swift | 1 + .../ParseOperationCombineTests.swift | 1 + .../ParseSwiftTests/ParseOperationTests.swift | 2 + .../ParsePointerAsyncTests.swift | 1 + .../ParsePointerCombineTests.swift | 1 + Tests/ParseSwiftTests/ParsePointerTests.swift | 1 + .../ParseQueryAsyncTests.swift | 1 + .../ParseQueryCombineTests.swift | 1 + Tests/ParseSwiftTests/ParseQueryTests.swift | 2 + .../ParseQueryViewModelTests.swift | 1 + .../ParseSwiftTests/ParseRelationTests.swift | 2 + Tests/ParseSwiftTests/ParseRoleTests.swift | 4 ++ Tests/ParseSwiftTests/ParseSessionTests.swift | 2 + .../ParseTwitterAsyncTests.swift | 2 + .../ParseTwitterCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseTwitterTests.swift | 2 + .../ParseSwiftTests/ParseUserAsyncTests.swift | 6 +- .../ParseUserCombineTests.swift | 2 + Tests/ParseSwiftTests/ParseUserTests.swift | 6 +- 83 files changed, 356 insertions(+), 177 deletions(-) diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 0caee262b..039c31a2f 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -44,8 +44,8 @@ struct GameScore: ParseObject, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated @@ -82,12 +82,12 @@ struct GameData: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if isRestoreOriginalKey(\.polygon, - original: object) { + if shouldRestoreKey(\.polygon, + original: object) { updated.polygon = object.polygon } - if isRestoreOriginalKey(\.points, - original: object) { + if shouldRestoreKey(\.points, + original: object) { updated.bytes = object.bytes } return updated diff --git a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift index a53d4b976..cac94a25a 100644 --- a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift @@ -114,8 +114,8 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated diff --git a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift index 2273a393d..8ce37b81c 100644 --- a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift @@ -26,16 +26,16 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.location, - original: object) { + if updated.shouldRestoreKey(\.location, + original: object) { updated.location = object.location } - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } return updated diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index ab22628b2..3ab339cfc 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -34,8 +34,8 @@ struct User: ParseUser { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated @@ -57,8 +57,8 @@ struct Role: ParseRole { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated @@ -84,8 +84,8 @@ struct GameScore: ParseObject, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated diff --git a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift index 0cf83919a..e6102431c 100644 --- a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift @@ -28,12 +28,12 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } return updated diff --git a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift index 1263ae3bf..7e3dd03bf 100644 --- a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift @@ -35,8 +35,8 @@ struct GameScore: ParseObject, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated diff --git a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift index 84930b038..77a1be4d8 100644 --- a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift @@ -36,20 +36,20 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } - if updated.isRestoreOriginalKey(\.myFiles, - original: object) { + if updated.shouldRestoreKey(\.myFiles, + original: object) { updated.myFiles = object.myFiles } - if updated.isRestoreOriginalKey(\.location, - original: object) { + if updated.shouldRestoreKey(\.location, + original: object) { updated.location = object.location } return updated diff --git a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift index 9ee4d7312..42b3ae0dc 100644 --- a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift @@ -36,16 +36,16 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } - if updated.isRestoreOriginalKey(\.location, - original: object) { + if updated.shouldRestoreKey(\.location, + original: object) { updated.location = object.location } return updated diff --git a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift index fb74c632f..6ef85ac83 100644 --- a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift @@ -34,16 +34,16 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } - if updated.isRestoreOriginalKey(\.location, - original: object) { + if updated.shouldRestoreKey(\.location, + original: object) { updated.location = object.location } return updated diff --git a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift index d668a3bea..dbdcf775d 100644 --- a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift @@ -29,20 +29,20 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.timeStamp, - original: object) { + if updated.shouldRestoreKey(\.timeStamp, + original: object) { updated.timeStamp = object.timeStamp } - if updated.isRestoreOriginalKey(\.oldScore, - original: object) { + if updated.shouldRestoreKey(\.oldScore, + original: object) { updated.oldScore = object.oldScore } - if updated.isRestoreOriginalKey(\.isHighest, - original: object) { + if updated.shouldRestoreKey(\.isHighest, + original: object) { updated.isHighest = object.isHighest } return updated diff --git a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift index 2a50dd642..95b7c45d9 100644 --- a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift @@ -34,8 +34,8 @@ struct User: ParseUser, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index 9afadd7ce..0cac9b222 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -37,20 +37,20 @@ struct User: ParseUser, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } - if updated.isRestoreOriginalKey(\.gameScore, - original: object) { + if updated.shouldRestoreKey(\.gameScore, + original: object) { updated.gameScore = object.gameScore } - if updated.isRestoreOriginalKey(\.targetScore, - original: object) { + if updated.shouldRestoreKey(\.targetScore, + original: object) { updated.targetScore = object.targetScore } - if updated.isRestoreOriginalKey(\.allScores, - original: object) { + if updated.shouldRestoreKey(\.allScores, + original: object) { updated.allScores = object.allScores } return updated @@ -83,7 +83,7 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, + if updated.shouldRestoreKey(\.points, original: object) { updated.points = object.points } diff --git a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift index 140ff0ac5..8a885408a 100644 --- a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift @@ -37,8 +37,8 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index f262e9b9c..87edea150 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -40,8 +40,8 @@ struct Installation: ParseInstallation, ParseObjectMutable { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated diff --git a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift index 24c608a95..e622504d7 100644 --- a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift @@ -29,8 +29,8 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } return updated diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index adeb32ee2..00ed66fa3 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -29,8 +29,8 @@ struct Book: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.title, - original: object) { + if updated.shouldRestoreKey(\.title, + original: object) { updated.title = object.title } return updated @@ -62,16 +62,16 @@ struct Author: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.name, - original: object) { + if updated.shouldRestoreKey(\.name, + original: object) { updated.name = object.name } - if updated.isRestoreOriginalKey(\.book, - original: object) { + if updated.shouldRestoreKey(\.book, + original: object) { updated.book = object.book } - if updated.isRestoreOriginalKey(\.otherBooks, - original: object) { + if updated.shouldRestoreKey(\.otherBooks, + original: object) { updated.otherBooks = object.otherBooks } return updated diff --git a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift index f1733e64f..18aaa3645 100644 --- a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift @@ -30,16 +30,16 @@ struct GameScore: ParseObject { //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.profilePicture, - original: object) { + if updated.shouldRestoreKey(\.profilePicture, + original: object) { updated.profilePicture = object.profilePicture } - if updated.isRestoreOriginalKey(\.myData, - original: object) { + if updated.shouldRestoreKey(\.myData, + original: object) { updated.myData = object.myData } return updated diff --git a/Sources/ParseSwift/API/API+Command.swift b/Sources/ParseSwift/API/API+Command.swift index ee90c06ee..0759728dc 100644 --- a/Sources/ParseSwift/API/API+Command.swift +++ b/Sources/ParseSwift/API/API+Command.swift @@ -385,13 +385,15 @@ internal extension API.Command { // MARK: Saving ParseObjects static func save(_ object: T, + original data: Data?, isIgnoreCustomObjectIdConfig: Bool) throws -> API.Command where T: ParseObject { if ParseSwift.configuration.isAllowingCustomObjectIds && object.objectId == nil && !isIgnoreCustomObjectIdConfig { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } if object.isSaved { - return try replace(object) // MARK: Should be switched to "update" when server supports PATCH. + // MARK: Should be switched to "update" when server supports PATCH. + return try replace(object, original: data) } return create(object) } @@ -411,13 +413,20 @@ internal extension API.Command { mapper: mapper) } - static func replace(_ object: T) throws -> API.Command where T: ParseObject { + static func replace(_ object: T, original data: Data?) throws -> API.Command where T: ParseObject { guard object.objectId != nil else { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } - let mapper = { (data) -> T in - try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: object) + let mapper = { (mapperData: Data) -> T in + let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: mapperData).apply(to: object) + guard let originalData = data, + let original = try? ParseCoding.jsonDecoder().decode(T.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PUT, path: object.endpoint, @@ -425,13 +434,20 @@ internal extension API.Command { mapper: mapper) } - static func update(_ object: T) throws -> API.Command where T: ParseObject { + static func update(_ object: T, original data: Data?) throws -> API.Command where T: ParseObject { guard object.objectId != nil else { throw ParseError(code: .missingObjectId, message: "objectId must not be nil") } - let mapper = { (data) -> T in - try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: object) + let mapper = { (mapperData: Data) -> T in + let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: mapperData).apply(to: object) + guard let originalData = data, + let original = try? ParseCoding.jsonDecoder().decode(T.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PATCH, path: object.endpoint, diff --git a/Sources/ParseSwift/Coding/ParseEncoder.swift b/Sources/ParseSwift/Coding/ParseEncoder.swift index 5f07a8c07..68d7df92e 100644 --- a/Sources/ParseSwift/Coding/ParseEncoder.swift +++ b/Sources/ParseSwift/Coding/ParseEncoder.swift @@ -69,12 +69,22 @@ public struct ParseEncoder { case custom(Set) func keys() -> Set { + let defaultObjectKeys = Set(["createdAt", + "updatedAt", + "objectId", + "className", + "emailVerified", + "id", + "score", + "originalData"]) switch self { case .object: - return Set(["createdAt", "updatedAt", "objectId", "className", "emailVerified", "id", "score"]) + return defaultObjectKeys case .customObjectId: - return Set(["createdAt", "updatedAt", "className", "emailVerified", "id", "score"]) + var mutableKeys = defaultObjectKeys + _ = mutableKeys.remove("objectId") + return mutableKeys case .cloud: return Set(["functionJobName"]) case .none: diff --git a/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift b/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift index 506dfefce..f35218789 100644 --- a/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift +++ b/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift @@ -25,6 +25,7 @@ internal struct BaseParseInstallation: ParseInstallation { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? static func createNewInstallationIfNeeded() { guard let installationId = Self.currentContainer.installationId, diff --git a/Sources/ParseSwift/InternalObjects/BaseParseUser.swift b/Sources/ParseSwift/InternalObjects/BaseParseUser.swift index 8fcabf095..878b0ff64 100644 --- a/Sources/ParseSwift/InternalObjects/BaseParseUser.swift +++ b/Sources/ParseSwift/InternalObjects/BaseParseUser.swift @@ -19,4 +19,5 @@ internal struct BaseParseUser: ParseUser { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? } diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 4d3106a45..14b8d82a4 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -102,52 +102,52 @@ public extension ParseInstallation { message: "objectId's of objects don't match") } var updatedInstallation = self - if isRestoreOriginalKey(\.ACL, - original: object) { + if shouldRestoreKey(\.ACL, + original: object) { updatedInstallation.ACL = object.ACL } - if isRestoreOriginalKey(\.deviceType, - original: object) { + if shouldRestoreKey(\.deviceType, + original: object) { updatedInstallation.deviceType = object.deviceType } - if isRestoreOriginalKey(\.installationId, - original: object) { + if shouldRestoreKey(\.installationId, + original: object) { updatedInstallation.installationId = object.installationId } - if isRestoreOriginalKey(\.deviceToken, + if shouldRestoreKey(\.deviceToken, original: object) { updatedInstallation.deviceToken = object.deviceToken } - if isRestoreOriginalKey(\.badge, - original: object) { + if shouldRestoreKey(\.badge, + original: object) { updatedInstallation.badge = object.badge } - if isRestoreOriginalKey(\.timeZone, - original: object) { + if shouldRestoreKey(\.timeZone, + original: object) { updatedInstallation.timeZone = object.timeZone } - if isRestoreOriginalKey(\.channels, - original: object) { + if shouldRestoreKey(\.channels, + original: object) { updatedInstallation.channels = object.channels } - if isRestoreOriginalKey(\.appName, - original: object) { + if shouldRestoreKey(\.appName, + original: object) { updatedInstallation.appName = object.appName } - if isRestoreOriginalKey(\.appIdentifier, - original: object) { + if shouldRestoreKey(\.appIdentifier, + original: object) { updatedInstallation.appIdentifier = object.appIdentifier } - if isRestoreOriginalKey(\.appVersion, - original: object) { + if shouldRestoreKey(\.appVersion, + original: object) { updatedInstallation.appVersion = object.appVersion } - if isRestoreOriginalKey(\.parseVersion, - original: object) { + if shouldRestoreKey(\.parseVersion, + original: object) { updatedInstallation.parseVersion = object.parseVersion } - if isRestoreOriginalKey(\.localeIdentifier, - original: object) { + if shouldRestoreKey(\.localeIdentifier, + original: object) { updatedInstallation.localeIdentifier = object.localeIdentifier } return updatedInstallation @@ -769,11 +769,13 @@ extension ParseInstallation { let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) // MARK: The lines below should be removed when server supports PATCH. - guard let current = Self.current, - current.hasSameObjectId(as: object) == true else { - return object - } - return try object.merge(current) + guard let originalData = originalData, + let original = try? ParseCoding.jsonDecoder().decode(Self.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PUT, path: endpoint, @@ -788,11 +790,13 @@ extension ParseInstallation { } let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) - guard let current = Self.current, - current.hasSameObjectId(as: object) == true else { - return object - } - return try object.merge(current) + guard let originalData = originalData, + let original = try? ParseCoding.jsonDecoder().decode(Self.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index f8557808f..19f01f975 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -52,14 +52,20 @@ public protocol ParseObject: Objectable, */ var score: Double? { get } + /** + This `ParseObject` before `ParseObject.mutable` was called. + - warning: This property should not be set or modified by the developer. + */ + var originalData: Data? { get set } + /** Determines if a `KeyPath` of the current `ParseObject` should be restored by comparing it to another `ParseObject`. - parameter original: The original `ParseObject`. - returns: Returns a `true` if the keyPath should be restored or `false` otherwise. */ - func isRestoreOriginalKey(_ key: KeyPath, - original: Self) -> Bool where W: Equatable + func shouldRestoreKey(_ key: KeyPath, + original: Self) -> Bool where W: Equatable /** Merges two `ParseObject`'s resulting in modified and unchanged Parse keys. @@ -91,7 +97,7 @@ public protocol ParseObject: Objectable, //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, + if updated.shouldRestoreKey(\.points, original: object) { updated.points = object.points } @@ -108,7 +114,7 @@ public protocol ParseObject: Objectable, for all of your `ParseObject`'s as the developer has access to all keys of a `ParseObject`. You should always call `mergeParse` in the beginning of your implementation to handle all default Parse keys. In addition, - use `isRestoreOriginalKey` to compare key modifications between objects. + use `shouldRestoreKey` to compare key modifications between objects. */ func merge(_ object: Self) throws -> Self } @@ -145,8 +151,8 @@ public extension ParseObject { return try Pointer(self) } - func isRestoreOriginalKey(_ key: KeyPath, - original: Self) -> Bool where W: Equatable { + func shouldRestoreKey(_ key: KeyPath, + original: Self) -> Bool where W: Equatable { self[keyPath: key] == nil && original[keyPath: key] != self[keyPath: key] } @@ -156,7 +162,7 @@ public extension ParseObject { message: "objectId's of objects don't match") } var updated = self - if isRestoreOriginalKey(\.ACL, + if shouldRestoreKey(\.ACL, original: object) { updated.ACL = object.ACL } @@ -1037,7 +1043,9 @@ extension ParseObject { } internal func saveCommand(isIgnoreCustomObjectIdConfig: Bool = false) throws -> API.Command { - try API.Command.save(self, isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig) + try API.Command.save(self, + original: originalData, + isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig) } internal func createCommand() -> API.Command { @@ -1045,11 +1053,13 @@ extension ParseObject { } internal func replaceCommand() throws -> API.Command { - try API.Command.replace(self) + try API.Command.replace(self, + original: originalData) } internal func updateCommand() throws -> API.Command { - try API.Command.update(self) + try API.Command.update(self, + original: originalData) } // swiftlint:disable:next function_body_length diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index 54fcc0740..d082c661b 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -49,20 +49,20 @@ public extension ParseUser { message: "objectId's of objects do not match") } var updatedUser = self - if isRestoreOriginalKey(\.ACL, - original: object) { + if shouldRestoreKey(\.ACL, + original: object) { updatedUser.ACL = object.ACL } - if isRestoreOriginalKey(\.username, - original: object) { + if shouldRestoreKey(\.username, + original: object) { updatedUser.username = object.username } - if isRestoreOriginalKey(\.email, - original: object) { + if shouldRestoreKey(\.email, + original: object) { updatedUser.email = object.email } - if isRestoreOriginalKey(\.authData, - original: object) { + if shouldRestoreKey(\.authData, + original: object) { updatedUser.authData = object.authData } return updatedUser @@ -1119,11 +1119,13 @@ extension ParseUser { let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) // MARK: The lines below should be removed when server supports PATCH. - guard let current = Self.current, - current.hasSameObjectId(as: object) == true else { - return object - } - return try object.merge(current) + guard let originalData = originalData, + let original = try? ParseCoding.jsonDecoder().decode(Self.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PUT, path: endpoint, @@ -1153,11 +1155,13 @@ extension ParseUser { } let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) - guard let current = Self.current, - current.hasSameObjectId(as: object) == true else { - return object - } - return try object.merge(current) + guard let originalData = originalData, + let original = try? ParseCoding.jsonDecoder().decode(Self.self, + from: originalData), + original.hasSameObjectId(as: object) else { + return object + } + return try object.merge(original) } return API.Command(method: .PATCH, path: endpoint, diff --git a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift b/Sources/ParseSwift/Protocols/ParseObjectMutable.swift index 297239083..67c49773f 100644 --- a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift +++ b/Sources/ParseSwift/Protocols/ParseObjectMutable.swift @@ -25,6 +25,7 @@ import Foundation var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: These are required by `ParseUser`. var username: String? @@ -59,6 +60,7 @@ import Foundation var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int = 0 @@ -109,6 +111,7 @@ public extension ParseObjectMutable { var object = Self() object.objectId = objectId object.createdAt = createdAt + object.originalData = try? ParseCoding.jsonEncoder().encode(self) return object } } diff --git a/Sources/ParseSwift/Types/ParseRelation.swift b/Sources/ParseSwift/Types/ParseRelation.swift index 315fd8239..870f50e39 100644 --- a/Sources/ParseSwift/Types/ParseRelation.swift +++ b/Sources/ParseSwift/Types/ParseRelation.swift @@ -344,3 +344,12 @@ extension ParseRelation: CustomStringConvertible { debugDescription } } + +struct StoredParseRelation: Decodable { + var className: String + var key: String + + func createParseRelation(_ parent: T) -> ParseRelation { + ParseRelation(parent: parent, key: key, className: className) + } +} diff --git a/Tests/ParseSwiftTests/APICommandTests.swift b/Tests/ParseSwiftTests/APICommandTests.swift index 872663d1a..7194c770b 100644 --- a/Tests/ParseSwiftTests/APICommandTests.swift +++ b/Tests/ParseSwiftTests/APICommandTests.swift @@ -24,6 +24,8 @@ class APICommandTests: XCTestCase { var name = "First" var score: Double? + + var originalData: Data? } override func setUpWithError() throws { @@ -55,6 +57,8 @@ class APICommandTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? + var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -65,7 +69,6 @@ class APICommandTests: XCTestCase { // Your custom keys var customKey: String? - var score: Double? } struct LoginSignupResponse: ParseUser { @@ -76,6 +79,7 @@ class APICommandTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/IOS13Tests.swift b/Tests/ParseSwiftTests/IOS13Tests.swift index b716862f7..12e5f3368 100644 --- a/Tests/ParseSwiftTests/IOS13Tests.swift +++ b/Tests/ParseSwiftTests/IOS13Tests.swift @@ -22,6 +22,8 @@ class IOS13Tests: XCTestCase { // swiftlint:disable:this type_body_length var score: Double? + var originalData: Data? + var name = "First" } @@ -33,6 +35,7 @@ class IOS13Tests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/InitializeSDKTests.swift b/Tests/ParseSwiftTests/InitializeSDKTests.swift index 459dd26e0..61a551e4e 100644 --- a/Tests/ParseSwiftTests/InitializeSDKTests.swift +++ b/Tests/ParseSwiftTests/InitializeSDKTests.swift @@ -28,6 +28,7 @@ class InitializeSDKTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseACLTests.swift b/Tests/ParseSwiftTests/ParseACLTests.swift index 94a78dc28..57f221bc5 100644 --- a/Tests/ParseSwiftTests/ParseACLTests.swift +++ b/Tests/ParseSwiftTests/ParseACLTests.swift @@ -41,6 +41,7 @@ class ParseACLTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -61,6 +62,7 @@ class ParseACLTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -93,6 +95,7 @@ class ParseACLTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // provided by Role var name: String diff --git a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift index fd34428d7..20b5c3d9d 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift @@ -20,6 +20,7 @@ class ParseAnonymousAsyncTests: XCTestCase { // swiftlint:disable:this type_body var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseAnonymousAsyncTests: XCTestCase { // swiftlint:disable:this type_body var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift b/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift index 07cd02bdb..7a2569270 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift @@ -23,6 +23,7 @@ class ParseAnonymousCombineTests: XCTestCase { // swiftlint:disable:this type_bo var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseAnonymousCombineTests: XCTestCase { // swiftlint:disable:this type_bo var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAnonymousTests.swift b/Tests/ParseSwiftTests/ParseAnonymousTests.swift index d9d7e5f2c..84e88718b 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousTests.swift @@ -20,6 +20,7 @@ class ParseAnonymousTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseAnonymousTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift index ddf8cd7cf..09a146714 100644 --- a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift @@ -20,6 +20,7 @@ class ParseAppleAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseAppleAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleCombineTests.swift b/Tests/ParseSwiftTests/ParseAppleCombineTests.swift index 411a29d11..12d954f91 100644 --- a/Tests/ParseSwiftTests/ParseAppleCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleCombineTests.swift @@ -23,6 +23,7 @@ class ParseAppleCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseAppleCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleTests.swift b/Tests/ParseSwiftTests/ParseAppleTests.swift index 7d7144d19..f24ce7cc0 100644 --- a/Tests/ParseSwiftTests/ParseAppleTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleTests.swift @@ -19,6 +19,7 @@ class ParseAppleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseAppleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift index 64e5459ea..709725d7f 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift @@ -21,6 +21,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -38,6 +39,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift index 79b8b9740..a7e70b945 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift @@ -23,6 +23,7 @@ class ParseAuthenticationCombineTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseAuthenticationCombineTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift index 0b4c48273..740cb22b8 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift @@ -23,6 +23,7 @@ class ParseAuthenticationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseAuthenticationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift index 9ebd29f07..e323065e2 100644 --- a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift @@ -25,6 +25,7 @@ class ParseConfigAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -45,6 +46,7 @@ class ParseConfigAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigCombineTests.swift b/Tests/ParseSwiftTests/ParseConfigCombineTests.swift index 66bdba31e..b01dedc13 100644 --- a/Tests/ParseSwiftTests/ParseConfigCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigCombineTests.swift @@ -28,6 +28,7 @@ class ParseConfigCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -48,6 +49,7 @@ class ParseConfigCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigTests.swift b/Tests/ParseSwiftTests/ParseConfigTests.swift index 6696ff617..54d49f343 100644 --- a/Tests/ParseSwiftTests/ParseConfigTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigTests.swift @@ -25,6 +25,7 @@ class ParseConfigTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -45,6 +46,7 @@ class ParseConfigTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseEncoderTests/ParseEncoderExtraTests.swift b/Tests/ParseSwiftTests/ParseEncoderTests/ParseEncoderExtraTests.swift index 01068c2dd..0bb7f264b 100644 --- a/Tests/ParseSwiftTests/ParseEncoderTests/ParseEncoderExtraTests.swift +++ b/Tests/ParseSwiftTests/ParseEncoderTests/ParseEncoderExtraTests.swift @@ -17,6 +17,7 @@ class ParseEncoderTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: ParseUser property var emailVerified: Bool? diff --git a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift index c6ecdb4e9..e8e4903b2 100644 --- a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift @@ -20,6 +20,7 @@ class ParseFacebookAsyncTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseFacebookAsyncTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift b/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift index 5474f4c15..c1687f1fb 100644 --- a/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift @@ -23,6 +23,7 @@ class ParseFacebookCombineTests: XCTestCase { // swiftlint:disable:this type_bod var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseFacebookCombineTests: XCTestCase { // swiftlint:disable:this type_bod var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseFacebookTests.swift b/Tests/ParseSwiftTests/ParseFacebookTests.swift index 83f2b6890..890dc1d04 100644 --- a/Tests/ParseSwiftTests/ParseFacebookTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookTests.swift @@ -19,6 +19,7 @@ class ParseFacebookTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseFacebookTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift b/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift index 163585175..8e600ded8 100644 --- a/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift @@ -23,6 +23,7 @@ class ParseGitHubCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseGitHubCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGitHubTests.swift b/Tests/ParseSwiftTests/ParseGitHubTests.swift index bda3b59fc..8aad6706e 100644 --- a/Tests/ParseSwiftTests/ParseGitHubTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubTests.swift @@ -19,6 +19,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift b/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift index 2e5745e15..a81d18782 100644 --- a/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift @@ -23,6 +23,7 @@ class ParseGoogleCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseGoogleCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGoogleTests.swift b/Tests/ParseSwiftTests/ParseGoogleTests.swift index 8c3cc7608..6e45505e0 100644 --- a/Tests/ParseSwiftTests/ParseGoogleTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleTests.swift @@ -19,6 +19,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 11923efbd..b1c71c358 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -21,6 +21,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -41,6 +42,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -82,13 +84,14 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var customKey: String? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated diff --git a/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift b/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift index 94ff6f391..dd786e07c 100644 --- a/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift @@ -23,6 +23,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -43,6 +44,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -84,6 +86,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index bc6645c45..d4344b45c 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -20,6 +20,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -81,13 +83,14 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var customKey: String? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated diff --git a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift index 954dd737e..a3a7a91a9 100644 --- a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift @@ -20,6 +20,7 @@ class ParseLDAPAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseLDAPAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift b/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift index 0c82cbd32..2ba1d261c 100644 --- a/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift @@ -23,6 +23,7 @@ class ParseLDAPCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseLDAPCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLDAPTests.swift b/Tests/ParseSwiftTests/ParseLDAPTests.swift index b53107d9f..2f2a5e6e9 100644 --- a/Tests/ParseSwiftTests/ParseLDAPTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPTests.swift @@ -19,6 +19,7 @@ class ParseLDAPTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseLDAPTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift b/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift index 373eec23b..281c5937c 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift @@ -23,6 +23,7 @@ class ParseLinkedInCombineTests: XCTestCase { // swiftlint:disable:this type_bod var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseLinkedInCombineTests: XCTestCase { // swiftlint:disable:this type_bod var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLinkedInTests.swift b/Tests/ParseSwiftTests/ParseLinkedInTests.swift index 715d8ceef..90624fb07 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInTests.swift @@ -19,6 +19,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLiveQueryTests.swift b/Tests/ParseSwiftTests/ParseLiveQueryTests.swift index 6e786fbff..b30dce562 100644 --- a/Tests/ParseSwiftTests/ParseLiveQueryTests.swift +++ b/Tests/ParseSwiftTests/ParseLiveQueryTests.swift @@ -18,6 +18,7 @@ class ParseLiveQueryTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int = 0 diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index ce7e28529..31da4cd48 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -21,6 +21,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseObjectBatchTests.swift b/Tests/ParseSwiftTests/ParseObjectBatchTests.swift index 7277b4384..5f67844a8 100644 --- a/Tests/ParseSwiftTests/ParseObjectBatchTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectBatchTests.swift @@ -19,6 +19,7 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // Custom properties var points: Int = 0 @@ -44,6 +45,7 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var name = "Hello" diff --git a/Tests/ParseSwiftTests/ParseObjectCombineTests.swift b/Tests/ParseSwiftTests/ParseObjectCombineTests.swift index ac70ebc25..f8eee8f50 100644 --- a/Tests/ParseSwiftTests/ParseObjectCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectCombineTests.swift @@ -22,6 +22,7 @@ class ParseObjectCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift b/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift index 3fa509288..0e034e36d 100644 --- a/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift @@ -22,6 +22,8 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var score: Double? + var originalData: Data? + var name = "First" } @@ -32,6 +34,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? @@ -61,6 +64,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var gameScore: GameScore @@ -85,6 +89,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -114,6 +119,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index a0d17407f..03c8fb3cd 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -24,6 +24,8 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var score: Double? + var originalData: Data? + init() { name = "First" } @@ -36,6 +38,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? @@ -62,20 +65,20 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.points, - original: object) { + if updated.shouldRestoreKey(\.points, + original: object) { updated.points = object.points } - if updated.isRestoreOriginalKey(\.level, - original: object) { + if updated.shouldRestoreKey(\.level, + original: object) { updated.level = object.level } - if updated.isRestoreOriginalKey(\.levels, - original: object) { + if updated.shouldRestoreKey(\.levels, + original: object) { updated.levels = object.levels } - if updated.isRestoreOriginalKey(\.nextLevel, - original: object) { + if updated.shouldRestoreKey(\.nextLevel, + original: object) { updated.nextLevel = object.nextLevel } return updated @@ -89,6 +92,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var gameScore: GameScore @@ -113,6 +117,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var name = "Hello" @@ -127,6 +132,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int @@ -186,6 +192,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var gameScore: GameScoreClass @@ -242,6 +249,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -262,6 +270,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -357,11 +366,11 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var score2 = GameScore(points: 5, name: "world") score2.levels = [Level()] score2.nextLevel = Level() - XCTAssertFalse(score1.isRestoreOriginalKey(\.player, original: score2)) - XCTAssertTrue(score1.isRestoreOriginalKey(\.levels, original: score2)) - XCTAssertFalse(score1.isRestoreOriginalKey(\.points, original: score2)) - XCTAssertFalse(score1.isRestoreOriginalKey(\.level, original: score2)) - XCTAssertTrue(score1.isRestoreOriginalKey(\.nextLevel, original: score2)) + XCTAssertFalse(score1.shouldRestoreKey(\.player, original: score2)) + XCTAssertTrue(score1.shouldRestoreKey(\.levels, original: score2)) + XCTAssertFalse(score1.shouldRestoreKey(\.points, original: score2)) + XCTAssertFalse(score1.shouldRestoreKey(\.level, original: score2)) + XCTAssertTrue(score1.shouldRestoreKey(\.nextLevel, original: score2)) } func testParseObjectMutable() throws { diff --git a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift index dd86fb787..449b76119 100644 --- a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift @@ -19,6 +19,7 @@ class ParseOperationAsyncTests: XCTestCase { // swiftlint:disable:this type_body var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseOperationCombineTests.swift b/Tests/ParseSwiftTests/ParseOperationCombineTests.swift index cf722c48d..22c8275a6 100644 --- a/Tests/ParseSwiftTests/ParseOperationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationCombineTests.swift @@ -22,6 +22,7 @@ class ParseOperationCombineTests: XCTestCase { // swiftlint:disable:this type_bo var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseOperationTests.swift b/Tests/ParseSwiftTests/ParseOperationTests.swift index 80bf61246..16b59cbfb 100644 --- a/Tests/ParseSwiftTests/ParseOperationTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationTests.swift @@ -18,6 +18,7 @@ class ParseOperationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? @@ -45,6 +46,7 @@ class ParseOperationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift index 8013ccc85..2141d97ad 100644 --- a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift @@ -20,6 +20,7 @@ class ParsePointerAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParsePointerCombineTests.swift b/Tests/ParseSwiftTests/ParsePointerCombineTests.swift index a05542a6b..d484c1206 100644 --- a/Tests/ParseSwiftTests/ParsePointerCombineTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerCombineTests.swift @@ -22,6 +22,7 @@ class ParsePointerCombineTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParsePointerTests.swift b/Tests/ParseSwiftTests/ParsePointerTests.swift index bae7c3ba0..585676e15 100644 --- a/Tests/ParseSwiftTests/ParsePointerTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerTests.swift @@ -19,6 +19,7 @@ class ParsePointerTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift index 1766e3e75..d251fa093 100644 --- a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift @@ -19,6 +19,7 @@ class ParseQueryAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseQueryCombineTests.swift b/Tests/ParseSwiftTests/ParseQueryCombineTests.swift index 9a943fe44..bbaf17131 100644 --- a/Tests/ParseSwiftTests/ParseQueryCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryCombineTests.swift @@ -22,6 +22,7 @@ class ParseQueryCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseQueryTests.swift b/Tests/ParseSwiftTests/ParseQueryTests.swift index 51bfe2b8e..bde4e26d3 100644 --- a/Tests/ParseSwiftTests/ParseQueryTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryTests.swift @@ -19,6 +19,7 @@ class ParseQueryTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int @@ -40,6 +41,7 @@ class ParseQueryTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? var points: Int? } diff --git a/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift b/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift index bb0128940..f3b4e0432 100644 --- a/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift @@ -19,6 +19,7 @@ class ParseQueryViewModelTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int = 0 diff --git a/Tests/ParseSwiftTests/ParseRelationTests.swift b/Tests/ParseSwiftTests/ParseRelationTests.swift index 78320bcbf..74f331908 100644 --- a/Tests/ParseSwiftTests/ParseRelationTests.swift +++ b/Tests/ParseSwiftTests/ParseRelationTests.swift @@ -19,6 +19,7 @@ class ParseRelationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int @@ -41,6 +42,7 @@ class ParseRelationTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParseRoleTests.swift b/Tests/ParseSwiftTests/ParseRoleTests.swift index 8e6e5b50e..3694ba813 100644 --- a/Tests/ParseSwiftTests/ParseRoleTests.swift +++ b/Tests/ParseSwiftTests/ParseRoleTests.swift @@ -18,6 +18,7 @@ class ParseRoleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var points: Int @@ -42,6 +43,7 @@ class ParseRoleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -62,6 +64,7 @@ class ParseRoleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // provided by Role var name: String @@ -78,6 +81,7 @@ class ParseRoleTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParseSessionTests.swift b/Tests/ParseSwiftTests/ParseSessionTests.swift index 8f3b013f2..889eec7a0 100644 --- a/Tests/ParseSwiftTests/ParseSessionTests.swift +++ b/Tests/ParseSwiftTests/ParseSessionTests.swift @@ -21,6 +21,7 @@ class ParseSessionTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -38,6 +39,7 @@ class ParseSessionTests: XCTestCase { var createdWith: [String: String] var installationId: String var expiresAt: Date + var originalData: Data? var objectId: String? var createdAt: Date? diff --git a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift index 775a71239..99c52bcb9 100644 --- a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift @@ -20,6 +20,7 @@ class ParseTwitterAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -37,6 +38,7 @@ class ParseTwitterAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift b/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift index 6dfad8741..ed0e784a8 100644 --- a/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift @@ -23,6 +23,7 @@ class ParseTwitterCombineTests: XCTestCase { // swiftlint:disable:this type_body var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -40,6 +41,7 @@ class ParseTwitterCombineTests: XCTestCase { // swiftlint:disable:this type_body var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseTwitterTests.swift b/Tests/ParseSwiftTests/ParseTwitterTests.swift index 463ee8d0b..e9a34e0fe 100644 --- a/Tests/ParseSwiftTests/ParseTwitterTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterTests.swift @@ -19,6 +19,7 @@ class ParseTwitterTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -36,6 +37,7 @@ class ParseTwitterTests: XCTestCase { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 98e5efb1f..fd89fd21b 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -21,6 +21,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -35,8 +36,8 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated @@ -51,6 +52,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserCombineTests.swift b/Tests/ParseSwiftTests/ParseUserCombineTests.swift index f2ef434e2..39f044614 100644 --- a/Tests/ParseSwiftTests/ParseUserCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseUserCombineTests.swift @@ -23,6 +23,7 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -43,6 +44,7 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index b8f9e5428..ba1c093b2 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -20,6 +20,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? @@ -34,8 +35,8 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.isRestoreOriginalKey(\.customKey, - original: object) { + if updated.shouldRestoreKey(\.customKey, + original: object) { updated.customKey = object.customKey } return updated @@ -50,6 +51,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? // These are required by ParseUser var username: String? From 29a96f17ca27bd0c9faefb912ece27bd12edff99 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Fri, 14 Jan 2022 15:19:28 -0500 Subject: [PATCH 08/26] fix build on Swift 5.2 --- Sources/ParseSwift/Objects/ParseInstallation.swift | 4 ++-- Sources/ParseSwift/Objects/ParseUser.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 14b8d82a4..6245c8994 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -769,7 +769,7 @@ extension ParseInstallation { let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) // MARK: The lines below should be removed when server supports PATCH. - guard let originalData = originalData, + guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), original.hasSameObjectId(as: object) else { @@ -790,7 +790,7 @@ extension ParseInstallation { } let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) - guard let originalData = originalData, + guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), original.hasSameObjectId(as: object) else { diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index d082c661b..dc853129a 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -1119,7 +1119,7 @@ extension ParseUser { let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) // MARK: The lines below should be removed when server supports PATCH. - guard let originalData = originalData, + guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), original.hasSameObjectId(as: object) else { @@ -1155,7 +1155,7 @@ extension ParseUser { } let mapper = { (data: Data) -> Self in let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) - guard let originalData = originalData, + guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), original.hasSameObjectId(as: object) else { From aa9c6da799556d476613824ebe26de2ec80fdbd4 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Fri, 14 Jan 2022 18:14:31 -0500 Subject: [PATCH 09/26] Make sure originalData never saves to Keychain --- .../Objects/ParseInstallation.swift | 3 +- Sources/ParseSwift/Objects/ParseUser.swift | 3 +- .../ParseInstallationAsyncTests.swift | 40 ++++++++ .../ParseObjectAsyncTests.swift | 94 ++++++++++++++++++- Tests/ParseSwiftTests/ParseUserTests.swift | 33 +++++++ 5 files changed, 170 insertions(+), 3 deletions(-) diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 6245c8994..3c228a65a 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -267,8 +267,9 @@ public extension ParseInstallation { } internal static func saveCurrentContainerToKeychain() { + Self.currentContainer.currentInstallation?.originalData = nil #if !os(Linux) && !os(Android) && !os(Windows) - try? KeychainStore.shared.set(Self.currentContainer, for: ParseStorage.Keys.currentInstallation) + try? KeychainStore.shared.set(currentContainer, for: ParseStorage.Keys.currentInstallation) #endif } diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index dc853129a..762cc8583 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -124,8 +124,9 @@ public extension ParseUser { } internal static func saveCurrentContainerToKeychain() { + Self.currentContainer?.currentUser?.originalData = nil #if !os(Linux) && !os(Android) && !os(Windows) - try? KeychainStore.shared.set(Self.currentContainer, for: ParseStorage.Keys.currentUser) + try? KeychainStore.shared.set(currentContainer, for: ParseStorage.Keys.currentUser) #endif } diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index b1c71c358..2d499a237 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -184,6 +184,46 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b } } + func testOriginalDataNeverSavesToKeychain() async throws { + // Save current Installation + try saveCurrentInstallation() + MockURLProtocol.removeAll() + + Installation.current?.originalData = Data() + let original = Installation.current + Installation.saveCurrentContainerToKeychain() + + let expectation1 = XCTestExpectation(description: "Original installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let original = original, + let saved = Installation.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameInstallationId(as: original)) + XCTAssertTrue(saved.hasSameObjectId(as: original)) + XCTAssertNotNil(original.originalData) + XCTAssertNil(saved.originalData) + XCTAssertEqual(saved.customKey, original.customKey) + XCTAssertEqual(saved.badge, original.badge) + XCTAssertEqual(saved.deviceType, original.deviceType) + XCTAssertEqual(saved.deviceToken, original.deviceToken) + XCTAssertEqual(saved.channels, original.channels) + XCTAssertEqual(saved.installationId, original.installationId) + XCTAssertEqual(saved.timeZone, original.timeZone) + XCTAssertEqual(saved.appName, original.appName) + XCTAssertEqual(saved.appVersion, original.appVersion) + XCTAssertEqual(saved.appIdentifier, original.appIdentifier) + XCTAssertEqual(saved.parseVersion, original.parseVersion) + XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, original.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } + @MainActor func testFetch() async throws { try saveCurrentInstallation() diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index 31da4cd48..c5a03f7cb 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -13,7 +13,7 @@ import XCTest class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_length - struct GameScore: ParseObject { + struct GameScore: ParseObject, ParseObjectMutable { //: These are required by ParseObject var objectId: String? @@ -27,6 +27,20 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var points: Int? var player: String? + //: Implement your own version of merge + func merge(_ object: Self) throws -> Self { + var updated = try mergeParse(object) + if updated.shouldRestoreKey(\.points, + original: object) { + updated.points = object.points + } + if updated.shouldRestoreKey(\.player, + original: object) { + updated.player = object.player + } + return updated + } + init() { } //custom initializers @@ -143,6 +157,45 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le XCTAssertEqual(saved.ACL, scoreOnServer.ACL) } + @MainActor + func testSaveMutable() async throws { + var original = GameScore(points: 10) + original.objectId = "yarr" + original.player = "beast" + + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(GameScore.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdated = original.mutable + originalUpdated.points = 50 + let updated = originalUpdated + + do { + let saved = try await updated.save() + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.points, 50) + XCTAssertEqual(saved.player, original.player) + XCTAssertEqual(saved.createdAt, response.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testCreate() async throws { let score = GameScore(points: 10) @@ -320,6 +373,45 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le } } + @MainActor + func testUpdateMutable() async throws { + var original = GameScore(points: 10) + original.objectId = "yarr" + original.player = "beast" + + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(GameScore.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdated = original.mutable + originalUpdated.points = 50 + let updated = originalUpdated + + do { + let saved = try await updated.update() + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.points, 50) + XCTAssertEqual(saved.player, original.player) + XCTAssertEqual(saved.createdAt, response.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testDelete() async throws { var score = GameScore(points: 10) diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index ba1c093b2..44fdd94f3 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -112,6 +112,39 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length try ParseStorage.shared.deleteAll() } + func testOriginalDataNeverSavesToKeychain() async throws { + // Signup current User + XCTAssertNil(User.current?.objectId) + try userSignUp() + XCTAssertNotNil(User.current?.objectId) + + User.current?.originalData = Data() + let original = User.current + User.saveCurrentContainerToKeychain() + + let expectation1 = XCTestExpectation(description: "Original installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let original = original, + let saved = User.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameObjectId(as: original)) + XCTAssertNotNil(original.originalData) + XCTAssertNil(saved.originalData) + XCTAssertEqual(saved.customKey, original.customKey) + XCTAssertEqual(saved.email, original.email) + XCTAssertEqual(saved.username, original.username) + XCTAssertEqual(saved.emailVerified, original.emailVerified) + XCTAssertEqual(saved.password, original.password) + XCTAssertEqual(saved.authData, original.authData) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, original.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } func testMerge() throws { // Signup current User XCTAssertNil(User.current?.objectId) From 8c5f2ed834eba4963bfec3318ca4ebc1598870e3 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Fri, 14 Jan 2022 19:27:01 -0500 Subject: [PATCH 10/26] move test to correct file --- .../ParseSwiftTests/ParseUserAsyncTests.swift | 34 +++++++++++++++++++ Tests/ParseSwiftTests/ParseUserTests.swift | 33 ------------------ 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index fd89fd21b..975632e4a 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -102,6 +102,40 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng try ParseStorage.shared.deleteAll() } + func testOriginalDataNeverSavesToKeychain() async throws { + // Signup current User + login() + MockURLProtocol.removeAll() + XCTAssertNotNil(User.current?.objectId) + + User.current?.originalData = Data() + let original = User.current + User.saveCurrentContainerToKeychain() + + let expectation1 = XCTestExpectation(description: "Original installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let original = original, + let saved = User.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameObjectId(as: original)) + XCTAssertNotNil(original.originalData) + XCTAssertNil(saved.originalData) + XCTAssertEqual(saved.customKey, original.customKey) + XCTAssertEqual(saved.email, original.email) + XCTAssertEqual(saved.username, original.username) + XCTAssertEqual(saved.emailVerified, original.emailVerified) + XCTAssertEqual(saved.password, original.password) + XCTAssertEqual(saved.authData, original.authData) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, original.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } + @MainActor func testSignup() async throws { let loginResponse = LoginSignupResponse() diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index 44fdd94f3..ba1c093b2 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -112,39 +112,6 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length try ParseStorage.shared.deleteAll() } - func testOriginalDataNeverSavesToKeychain() async throws { - // Signup current User - XCTAssertNil(User.current?.objectId) - try userSignUp() - XCTAssertNotNil(User.current?.objectId) - - User.current?.originalData = Data() - let original = User.current - User.saveCurrentContainerToKeychain() - - let expectation1 = XCTestExpectation(description: "Original installation1") - DispatchQueue.main.asyncAfter(deadline: .now() + 2) { - guard let original = original, - let saved = User.current else { - XCTFail("Should have a new current installation") - expectation1.fulfill() - return - } - XCTAssertTrue(saved.hasSameObjectId(as: original)) - XCTAssertNotNil(original.originalData) - XCTAssertNil(saved.originalData) - XCTAssertEqual(saved.customKey, original.customKey) - XCTAssertEqual(saved.email, original.email) - XCTAssertEqual(saved.username, original.username) - XCTAssertEqual(saved.emailVerified, original.emailVerified) - XCTAssertEqual(saved.password, original.password) - XCTAssertEqual(saved.authData, original.authData) - XCTAssertEqual(saved.createdAt, original.createdAt) - XCTAssertEqual(saved.updatedAt, original.updatedAt) - expectation1.fulfill() - } - wait(for: [expectation1], timeout: 20.0) - } func testMerge() throws { // Signup current User XCTAssertNil(User.current?.objectId) From 034b652e1a4b5c9405d476f8ef59416b9b652cd8 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Sat, 15 Jan 2022 10:11:47 -0500 Subject: [PATCH 11/26] Update Playgrounds and move ParseObjectMutable into ParseObject --- .../Contents.swift | 22 ++-- .../Contents.swift | 1 + .../Contents.swift | 1 + .../Contents.swift | 20 +-- .../Contents.swift | 1 + .../Contents.swift | 3 +- .../Contents.swift | 3 +- .../Contents.swift | 3 +- .../Contents.swift | 13 +- .../Contents.swift | 1 + .../Contents.swift | 3 +- .../Contents.swift | 4 +- .../5 - ACL.xcplaygroundpage/Contents.swift | 3 +- .../Contents.swift | 3 +- .../Contents.swift | 1 + .../Contents.swift | 17 ++- .../9 - Files.xcplaygroundpage/Contents.swift | 3 +- ParseSwift.xcodeproj/project.pbxproj | 10 -- Sources/ParseSwift/Objects/ParseObject.swift | 35 ++++-- Sources/ParseSwift/Objects/ParseRole.swift | 6 +- .../Protocols/ParseObjectMutable.swift | 117 ------------------ Sources/ParseSwift/Types/ParseACL.swift | 12 +- Tests/ParseSwiftTests/ParseACLTests.swift | 6 +- .../ParseInstallationAsyncTests.swift | 2 +- .../ParseInstallationTests.swift | 2 +- .../ParseObjectAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseObjectTests.swift | 4 +- Tests/ParseSwiftTests/ParseRoleTests.swift | 10 +- .../ParseSwiftTests/ParseUserAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseUserTests.swift | 2 +- 30 files changed, 114 insertions(+), 198 deletions(-) delete mode 100644 Sources/ParseSwift/Protocols/ParseObjectMutable.swift diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 039c31a2f..94dacd9a0 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -30,13 +30,14 @@ do { } //: Create your own value typed `ParseObject`. -struct GameScore: ParseObject, ParseObjectMutable { +struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? @@ -72,6 +73,7 @@ struct GameData: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var polygon: ParsePolygon? @@ -86,7 +88,7 @@ struct GameData: ParseObject { original: object) { updated.polygon = object.polygon } - if shouldRestoreKey(\.points, + if shouldRestoreKey(\.bytes, original: object) { updated.bytes = object.bytes } @@ -129,15 +131,10 @@ score.save { result in changedScore.points = 200 changedScore.save { result in switch result { - case .success(var savedChangedScore): + case .success(let savedChangedScore): assert(savedChangedScore.points == 200) assert(savedScore.objectId == savedChangedScore.objectId) - /*: Note that savedChangedScore is mutable since it's - a var after success. - */ - savedChangedScore.points = 500 - case .failure(let error): assertionFailure("Error saving: \(error)") } @@ -158,7 +155,10 @@ var score2ForFetchedLater: GameScore? otherResults.forEach { otherResult in switch otherResult { case .success(let savedScore): - print("Saved \"\(savedScore.className)\" with points \(savedScore.points) successfully") + print(""" + Saved \"\(savedScore.className)\" with + points \(String(describing: savedScore.points)) successfully + """) if index == 1 { score2ForFetchedLater = savedScore } @@ -218,7 +218,7 @@ assert(savedScore?.points == 10) parse server as opposed to the whole object. */ guard var changedScore = savedScore?.mutable else { - fatalError() + fatalError("Should have produced mutable changedScore") } changedScore.points = 200 @@ -246,7 +246,7 @@ assert(otherResults != nil) otherResults!.forEach { result in switch result { case .success(let savedScore): - print("Saved \"\(savedScore.className)\" with points \(savedScore.points) successfully") + print("Saved \"\(savedScore.className)\" with points \(String(describing: savedScore.points)) successfully") case .failure(let error): assertionFailure("Error saving: \(error)") } diff --git a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift index cac94a25a..b5c888900 100644 --- a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift @@ -107,6 +107,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift index 8ce37b81c..f73d12e26 100644 --- a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift @@ -17,6 +17,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index 3ab339cfc..889723d65 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -20,6 +20,7 @@ struct User: ParseUser { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: These are required by `ParseUser`. var username: String? @@ -50,33 +51,31 @@ struct Role: ParseRole { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Provided by Role. - var name: String + var name: String? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { var updated = try mergeParse(object) - if updated.shouldRestoreKey(\.points, + if updated.shouldRestoreKey(\.name, original: object) { - updated.points = object.points + updated.name = object.name } return updated } - - init() { - self.name = "" - } } //: Create your own value typed `ParseObject`. -struct GameScore: ParseObject, ParseObjectMutable { +struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? @@ -253,7 +252,10 @@ do { savedRole!.queryRoles?.find { result in switch result { case .success(let relatedRoles): - print("The following roles are part of the \"\(savedRole!.name) role: \(relatedRoles)") + print(""" + The following roles are part of the + \"\(String(describing: savedRole!.name)) role: \(relatedRoles) + """) case .failure(let error): print("Error saving role: \(error)") diff --git a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift index e6102431c..a4e4e1854 100644 --- a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift @@ -20,6 +20,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift index 7e3dd03bf..c3b99b909 100644 --- a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift @@ -21,13 +21,14 @@ npm start -- --appId applicationId --clientKey clientKey --masterKey masterKey - initializeParseCustomObjectId() //: Create your own value typed `ParseObject`. -struct GameScore: ParseObject, ParseObjectMutable { +struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift index 77a1be4d8..1e629a079 100644 --- a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift @@ -26,6 +26,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? @@ -118,7 +119,7 @@ struct ContentView: View { //: Warning - List seems to only work in Playgrounds Xcode 13+. List(viewModel.results, id: \.id) { result in VStack(alignment: .leading) { - Text("Points: \(result.points)") + Text("Points: \(String(describing: result.points))") .font(.headline) if let createdAt = result.createdAt { Text("\(createdAt.description)") diff --git a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift index 42b3ae0dc..17bdfd639 100644 --- a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift @@ -27,6 +27,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? @@ -112,7 +113,7 @@ struct ContentView: View { //: Warning - List seems to only work in Playgrounds Xcode 13+. List(viewModel.objects, id: \.id) { object in VStack(alignment: .leading) { - Text("Points: \(object.points)") + Text("Points: \(String(describing: object.points))") .font(.headline) if let createdAt = object.createdAt { Text("\(createdAt.description)") diff --git a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift index 6ef85ac83..8246d5cc4 100644 --- a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift @@ -25,9 +25,10 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. - var points: Int = 0 + var points: Int? = 0 var location: ParseGeoPoint? var name: String? @@ -84,15 +85,15 @@ struct ContentView: View { switch event.event { case .entered(let object): - Text("Entered with points: \(object.points)") + Text("Entered with points: \(String(describing: object.points))") case .left(let object): - Text("Left with points: \(object.points)") + Text("Left with points: \(String(describing: object.points))") case .created(let object): - Text("Created with points: \(object.points)") + Text("Created with points: \(String(describing: object.points))") case .updated(let object): - Text("Updated with points: \(object.points)") + Text("Updated with points: \(String(describing: object.points))") case .deleted(let object): - Text("Deleted with points: \(object.points)") + Text("Deleted with points: \(String(describing: object.points))") } } else { Text("Not subscribed to a query") diff --git a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift index dbdcf775d..a10bad0bd 100644 --- a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift @@ -19,6 +19,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift index 95b7c45d9..638a81c44 100644 --- a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift @@ -13,13 +13,14 @@ PlaygroundPage.current.needsIndefiniteExecution = true import ParseSwift initializeParse() -struct User: ParseUser, ParseObjectMutable { +struct User: ParseUser { //: These are required by `ParseObject`. var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: These are required by `ParseUser`. var username: String? diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index 0cac9b222..2dd872fc6 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -13,13 +13,14 @@ import ParseSwift PlaygroundPage.current.needsIndefiniteExecution = true initializeParse() -struct User: ParseUser, ParseObjectMutable { +struct User: ParseUser { //: These are required by `ParseObject`. var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: These are required by `ParseUser`. var username: String? @@ -76,6 +77,7 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var points: Int? = 0 diff --git a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift index 8a885408a..b62aed71e 100644 --- a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift @@ -30,9 +30,10 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties - var points: Int + var points: Int? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index 87edea150..54186b2ff 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -13,13 +13,14 @@ import ParseSwift PlaygroundPage.current.needsIndefiniteExecution = true initializeParse() -struct Installation: ParseInstallation, ParseObjectMutable { +struct Installation: ParseInstallation { //: These are required by `ParseObject`. var objectId: String? var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: These are required by `ParseInstallation`. var installationId: String? diff --git a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift index e622504d7..abcf7b72f 100644 --- a/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift @@ -22,6 +22,7 @@ struct GameScore: ParseObject { var ACL: ParseACL? var score: Double? var location: ParseGeoPoint? + var originalData: Data? //: Your own properties var points: Int? diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index 00ed66fa3..3b73408b1 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -21,10 +21,11 @@ struct Book: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? - var relatedBook: Pointer? + var originalData: Data? //: Your own properties. var title: String? + var relatedBook: Pointer? //: Implement your own version of merge func merge(_ object: Self) throws -> Self { @@ -33,6 +34,10 @@ struct Book: ParseObject { original: object) { updated.title = object.title } + if updated.shouldRestoreKey(\.relatedBook, + original: object) { + updated.relatedBook = object.relatedBook + } return updated } } @@ -53,6 +58,7 @@ struct Author: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. var name: String? @@ -155,7 +161,9 @@ query2.first { results in switch results { case .success(let author): //: Save the book to use later - newBook = author.book + if let book = author.book { + newBook = book + } print("Found author and included \"book\": \(author)") @@ -211,9 +219,10 @@ do { case .success(let author): print("Found author and included \"book\": \(author)") //: Setup related books. - newBook.relatedBook = try? author.otherBooks?.first?.toPointer() + var modifiedNewBook = newBook.mutable + modifiedNewBook.relatedBook = try? author.otherBooks?.first?.toPointer() - newBook.save { result in + modifiedNewBook.save { result in switch result { case .success(let updatedBook): assert(updatedBook.objectId != nil) diff --git a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift index 18aaa3645..62615f0ac 100644 --- a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift @@ -21,9 +21,10 @@ struct GameScore: ParseObject { var updatedAt: Date? var ACL: ParseACL? var score: Double? + var originalData: Data? //: Your own properties. - var points: Int = 0 + var points: Int? = 0 var profilePicture: ParseFile? var myData: ParseFile? diff --git a/ParseSwift.xcodeproj/project.pbxproj b/ParseSwift.xcodeproj/project.pbxproj index 4943f0c33..570382058 100644 --- a/ParseSwift.xcodeproj/project.pbxproj +++ b/ParseSwift.xcodeproj/project.pbxproj @@ -675,10 +675,6 @@ 91F346C3269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; }; 91F346C4269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; }; 91F346C5269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; }; - CD106A00272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; }; - CD106A01272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; }; - CD106A02272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; }; - CD106A03272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; }; F971F4F624DE381A006CB79B /* ParseEncoderExtraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F971F4F524DE381A006CB79B /* ParseEncoderExtraTests.swift */; }; F97B45CE24D9C6F200F4A88B /* ParseCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97B45B424D9C6F200F4A88B /* ParseCoding.swift */; }; F97B45CF24D9C6F200F4A88B /* ParseCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97B45B424D9C6F200F4A88B /* ParseCoding.swift */; }; @@ -1073,7 +1069,6 @@ 91F346B8269B766C005727B6 /* CloudViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudViewModel.swift; sourceTree = ""; }; 91F346BD269B77B5005727B6 /* CloudObservable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudObservable.swift; sourceTree = ""; }; 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloudViewModelTests.swift; sourceTree = ""; }; - CD1069FF272D481800939151 /* ParseObjectMutable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseObjectMutable.swift; sourceTree = ""; }; F971F4F524DE381A006CB79B /* ParseEncoderExtraTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseEncoderExtraTests.swift; sourceTree = ""; }; F97B45B424D9C6F200F4A88B /* ParseCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseCoding.swift; sourceTree = ""; }; F97B45B524D9C6F200F4A88B /* AnyDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyDecodable.swift; sourceTree = ""; }; @@ -1405,7 +1400,6 @@ F97B45C524D9C6F200F4A88B /* Fetchable.swift */, 705A9A2E25991C1400B3547F /* Fileable.swift */, 70BC988F252A5B5C00FF3074 /* Objectable.swift */, - CD1069FF272D481800939151 /* ParseObjectMutable.swift */, 70647E9B259E3A9A004C1004 /* ParseType.swift */, F97B45C824D9C6F200F4A88B /* Queryable.swift */, 91BB8FCE2690BA70005A6BA5 /* QueryObservable.swift */, @@ -2261,7 +2255,6 @@ 703B090226BD9652005A112F /* ParseAnalytics+async.swift in Sources */, 703B093F26BF47AC005A112F /* ParseApple+async.swift in Sources */, F97B45E624D9C6F200F4A88B /* Query.swift in Sources */, - CD106A00272D481800939151 /* ParseObjectMutable.swift in Sources */, 703B093526BF43D9005A112F /* ParseAnonymous+async.swift in Sources */, 705D950825BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */, 70C5509225B4A99100B5DBC2 /* AddRelation.swift in Sources */, @@ -2493,7 +2486,6 @@ 703B090326BD9652005A112F /* ParseAnalytics+async.swift in Sources */, 703B094026BF47AC005A112F /* ParseApple+async.swift in Sources */, F97B45E724D9C6F200F4A88B /* Query.swift in Sources */, - CD106A01272D481800939151 /* ParseObjectMutable.swift in Sources */, 703B093626BF43D9005A112F /* ParseAnonymous+async.swift in Sources */, 705D950925BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */, 70C5509325B4A99100B5DBC2 /* AddRelation.swift in Sources */, @@ -2829,7 +2821,6 @@ 703B090526BD9652005A112F /* ParseAnalytics+async.swift in Sources */, 703B094226BF47AC005A112F /* ParseApple+async.swift in Sources */, F97B466724D9C88600F4A88B /* SecureStorage.swift in Sources */, - CD106A03272D481800939151 /* ParseObjectMutable.swift in Sources */, 703B093826BF43D9005A112F /* ParseAnonymous+async.swift in Sources */, 705D950B25BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */, 70C5509525B4A99100B5DBC2 /* AddRelation.swift in Sources */, @@ -2968,7 +2959,6 @@ 703B090426BD9652005A112F /* ParseAnalytics+async.swift in Sources */, 703B094126BF47AC005A112F /* ParseApple+async.swift in Sources */, F97B466624D9C88600F4A88B /* SecureStorage.swift in Sources */, - CD106A02272D481800939151 /* ParseObjectMutable.swift in Sources */, 703B093726BF43D9005A112F /* ParseAnonymous+async.swift in Sources */, 705D950A25BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */, 70C5509425B4A99100B5DBC2 /* AddRelation.swift in Sources */, diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 19f01f975..c80970f3d 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -16,17 +16,19 @@ import Foundation If you are using value types the the compiler will assist you with conforming to `ParseObject` protocol. If you are thinking of using reference types, see the warning. - It's recommended the developer conforms to the `ParseObjectMutable` protocol. - Gets an empty version of the respective object. This can be used when you only need to update a - a subset of the fields of an object as oppose to updating every field of an object. Using an empty object and updating - a subset of the fields reduces the amount of data sent between client and server when using `save` and `saveAll` - to update objects. + After a `ParseObject`is saved/created to a Parse Server. Updates to the `ParseObject` should occur on + a copy of the `mutable` property. This allows a subset of the fields to be updated (PATCH) of an object + as oppose to replacing all of the fields of an object (PUT). This reduces the amount of data + sent between client and server when using `save`, `saveAll`, `update`, + `updateAll`, `replace`, `replaceAll`, to update objects. - - important: It is recommended that all added properties be optional properties so they can eventually be used as + - important: It is required that all added properties be optional properties so they can eventually be used as Parse `Pointer`'s. If a developer really wants to have a required key, they should require it on the server-side or create methods to check the respective properties on the client-side before saving objects. See [here](https://github.com/parse-community/Parse-Swift/issues/157#issuecomment-858671025) for more information. + - important: To take advantage of `mutable`, the developer should implement the `merge` method in every + `ParseObject`. - important: The property, "score," is a Parse Server designated keyword and you should avoid naming any of your `ParseObject` properties "score". Doing so may result in decoding issues. - warning: If you plan to use "reference types" (classes), you are using at your risk as this SDK is not designed @@ -58,6 +60,15 @@ public protocol ParseObject: Objectable, */ var originalData: Data? { get set } + /** + An empty copy of the respective object that allows you to update a + a subset of the fields (PATCH) of an object as oppose to replacing an object (PUT). + - note: It is recommended to use this to create a mutable copy of your `ParseObject`. + - warning: `mutable` should only be used on `ParseObject`'s that have already + been saved at least once to a Parse Server and have a valid `objectId`. + */ + var mutable: Self { get } + /** Determines if a `KeyPath` of the current `ParseObject` should be restored by comparing it to another `ParseObject`. @@ -83,7 +94,7 @@ public protocol ParseObject: Objectable, Merges two `ParseObject`'s resulting in modified and unchanged keys. //: Create your own value typed `ParseObject`. - struct GameScore: ParseObject, ParseObjectMutable { + struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? @@ -117,6 +128,8 @@ public protocol ParseObject: Objectable, use `shouldRestoreKey` to compare key modifications between objects. */ func merge(_ object: Self) throws -> Self + + init() } // MARK: Default Implementations @@ -134,6 +147,14 @@ public extension ParseObject { return objectId } + var mutable: Self { + var object = Self() + object.objectId = objectId + object.createdAt = createdAt + object.originalData = try? ParseCoding.jsonEncoder().encode(self) + return object + } + /** Determines if two objects have the same objectId. - parameter as: Object to compare. diff --git a/Sources/ParseSwift/Objects/ParseRole.swift b/Sources/ParseSwift/Objects/ParseRole.swift index 876cec669..91d2a80d1 100644 --- a/Sources/ParseSwift/Objects/ParseRole.swift +++ b/Sources/ParseSwift/Objects/ParseRole.swift @@ -25,12 +25,11 @@ public protocol ParseRole: ParseObject { and cannot be set once the role has been saved. - warning: A role's name can only contain alphanumeric characters, `_`, `-`, and spaces. */ - var name: String { get set } + var name: String? { get set } /** Create a `ParseRole`. It's best to use the provided initializers, `init(name: String)` - or `init(name: String, acl: ParseACL)`. The provided initializers will overwrite - whatever name is specified here, so you can use `self.name = ""` + or `init(name: String, acl: ParseACL)`. */ init() } @@ -49,6 +48,7 @@ public extension ParseRole { init(name: String) throws { try Self.checkName(name) self.init() + self.name = name } /** diff --git a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift b/Sources/ParseSwift/Protocols/ParseObjectMutable.swift deleted file mode 100644 index 67c49773f..000000000 --- a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// ParseObjectMutable.swift -// ParseSwift -// -// Created by Damian Van de Kauter on 30/10/2021. -// Copyright © 2021 Parse Community. All rights reserved. -// - -import Foundation - -/** - The `ParseObjectMutable` protocol creates an empty copy of the respective object. - This can be used when you only need to update a subset of the fields (PATCH) of an object - as oppose to replacing (PUT) an object. - Using the mutable copy and updating a subset of the fields reduces the amount of data - sent between client and server when using `save` and `saveAll` - to update objects. - - **Example use case for `ParseUser`:** - ```` - struct User: ParseUser, ParseObjectMutable { - //: These are required by `ParseObject`. - var objectId: String? - var createdAt: Date? - var updatedAt: Date? - var ACL: ParseACL? - var score: Double? - var originalData: Data? - - //: These are required by `ParseUser`. - var username: String? - var email: String? - var emailVerified: Bool? - var password: String? - var authData: [String: [String: String]?]? - - //: Your custom keys. - var customKey: String? - var gameScore: GameScore? - var targetScore: GameScore? - var allScores: [GameScore]? - } - - var user = User.current?.mutable - user?.customKey = "newValue" - - do { - try await user?.save() - } catch { - // Handle error - } - ```` - - **Example use case for a general `ParseObject`:** - ```` - struct GameScore: ParseObject, ParseObjectMutable { - //: These are required by ParseObject - var objectId: String? - var createdAt: Date? - var updatedAt: Date? - var ACL: ParseACL? - var score: Double? - var originalData: Data? - - //: Your own properties. - var points: Int = 0 - } - //: It's recommended to place custom initializers in an extension - //: to preserve the convenience initializer. - extension GameScore { - - init(points: Int) { - self.points = points - } - - init(objectId: String?) { - self.objectId = objectId - } - } - - var newScore = GameScore(points: 10).mutable - newScore.points = 200 - - do { - try await newScore.save() - } catch { - // Handle error - } - ```` - - - warning: Using the `ParseObjectMutable` protocol requires the developer to - initialize all of the `ParseObject` properties. This can be accomplished by making all properties - optional or setting default values for non-optional properties. - This also allows your objects to be used as Parse `Pointer`‘s. - It's recommended to place custom initializers in an extension - to preserve the convenience initializer. -*/ -public protocol ParseObjectMutable: ParseObject { - init() - - /** - An empty copy of the respective object that allows you to update a - a subset of the fields of an object as oppose to updating every field of an object. - - note: It is recommended to use this to create a mutable copy of your `ParseObject`. - */ - var mutable: Self { get } -} - -public extension ParseObjectMutable { - var mutable: Self { - var object = Self() - object.objectId = objectId - object.createdAt = createdAt - object.originalData = try? ParseCoding.jsonEncoder().encode(self) - return object - } -} diff --git a/Sources/ParseSwift/Types/ParseACL.swift b/Sources/ParseSwift/Types/ParseACL.swift index 8e3df7255..ca8c39c48 100644 --- a/Sources/ParseSwift/Types/ParseACL.swift +++ b/Sources/ParseSwift/Types/ParseACL.swift @@ -202,7 +202,8 @@ public struct ParseACL: ParseType, - returns: `true` if the `ParseRole` has read access, otherwise `false`. */ public func getReadAccess(role: T) -> Bool where T: ParseRole { - get(toRole(roleName: role.name), access: .read) + guard let name = role.name else { return false } + return get(toRole(roleName: name), access: .read) } /** @@ -224,7 +225,8 @@ public struct ParseACL: ParseType, - returns: `true` if the role has read access, otherwise `false`. */ public func getWriteAccess(role: T) -> Bool where T: ParseRole { - get(toRole(roleName: role.name), access: .write) + guard let name = role.name else { return false } + return get(toRole(roleName: name), access: .write) } /** @@ -244,7 +246,8 @@ public struct ParseACL: ParseType, - parameter role: The `ParseRole` to set access for. */ public mutating func setReadAccess(role: T, value: Bool) where T: ParseRole { - set(toRole(roleName: role.name), access: .read, value: value) + guard let name = role.name else { return } + set(toRole(roleName: name), access: .read, value: value) } /** @@ -264,7 +267,8 @@ public struct ParseACL: ParseType, - parameter role: The `ParseRole` to set access for. */ public mutating func setWriteAccess(role: T, value: Bool) where T: ParseRole { - set(toRole(roleName: role.name), access: .write, value: value) + guard let name = role.name else { return } + set(toRole(roleName: name), access: .write, value: value) } private func toRole(roleName: String) -> String { diff --git a/Tests/ParseSwiftTests/ParseACLTests.swift b/Tests/ParseSwiftTests/ParseACLTests.swift index 57f221bc5..578c44755 100644 --- a/Tests/ParseSwiftTests/ParseACLTests.swift +++ b/Tests/ParseSwiftTests/ParseACLTests.swift @@ -98,11 +98,7 @@ class ParseACLTests: XCTestCase { var originalData: Data? // provided by Role - var name: String - - init() { - self.name = "roleMe" - } + var name: String? } func testCantSetDefaultACLWhenNotLoggedIn() throws { diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 2d499a237..f75cb3260 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -67,7 +67,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b } } - struct Installation: ParseInstallation, ParseObjectMutable { + struct Installation: ParseInstallation { var installationId: String? var deviceType: String? var deviceToken: String? diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index d4344b45c..bc241dd9e 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -66,7 +66,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l } } - struct Installation: ParseInstallation, ParseObjectMutable { + struct Installation: ParseInstallation { var installationId: String? var deviceType: String? var deviceToken: String? diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index c5a03f7cb..4e9c2782c 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -13,7 +13,7 @@ import XCTest class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_length - struct GameScore: ParseObject, ParseObjectMutable { + struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index 03c8fb3cd..a5d5770cb 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -31,7 +31,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length } } - struct GameScore: ParseObject, ParseObjectMutable { + struct GameScore: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? @@ -85,7 +85,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length } } - struct Game: ParseObject, ParseObjectMutable { + struct Game: ParseObject { //: These are required by ParseObject var objectId: String? var createdAt: Date? diff --git a/Tests/ParseSwiftTests/ParseRoleTests.swift b/Tests/ParseSwiftTests/ParseRoleTests.swift index 3694ba813..fbf4ae592 100644 --- a/Tests/ParseSwiftTests/ParseRoleTests.swift +++ b/Tests/ParseSwiftTests/ParseRoleTests.swift @@ -67,11 +67,7 @@ class ParseRoleTests: XCTestCase { var originalData: Data? // provided by Role - var name: String - - init() { - self.name = "roleMe" - } + var name: String? } struct Level: ParseObject { @@ -121,7 +117,7 @@ class ParseRoleTests: XCTestCase { func testName() throws { let role1 = try Role(name: "Hello9_- ") - let role2 = try Role(name: "Hello9_- ", acl: ParseACL()) + let role2 = try Role(name: "Hello10_- ", acl: ParseACL()) let roles = [role1: "hello", role2: "world"] XCTAssertEqual(role1, role1) @@ -129,7 +125,7 @@ class ParseRoleTests: XCTestCase { XCTAssertEqual(roles[role1], "hello") XCTAssertEqual(roles[role2], "world") XCTAssertThrowsError(try Role(name: "Hello9!")) - XCTAssertThrowsError(try Role(name: "Hello9!", acl: ParseACL())) + XCTAssertThrowsError(try Role(name: "Hello10!", acl: ParseACL())) } func testEndPoint() throws { diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 975632e4a..8559fe006 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -13,7 +13,7 @@ import XCTest class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_length - struct User: ParseUser, ParseObjectMutable { + struct User: ParseUser { //: These are required by ParseObject var objectId: String? diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index ba1c093b2..4b1e303db 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -12,7 +12,7 @@ import XCTest class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length - struct User: ParseUser, ParseObjectMutable { + struct User: ParseUser { //: These are required by ParseObject var objectId: String? From d180c633525d54de1372a5d07171ddef104deae5 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Sat, 15 Jan 2022 10:26:30 -0500 Subject: [PATCH 12/26] doc updates --- Sources/ParseSwift/Objects/ParseObject.swift | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index c80970f3d..ea90ccabc 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -50,13 +50,14 @@ public protocol ParseObject: Objectable, CustomDebugStringConvertible, CustomStringConvertible { /** - The weight/rank of a `QueryConstraint.matchesText()`. + The weight/rank of a `QueryConstraint.matchesText()`. */ var score: Double? { get } /** - This `ParseObject` before `ParseObject.mutable` was called. - - warning: This property should not be set or modified by the developer. + A JSON encoded version of this `ParseObject` before `mutable` was called and + properties were changed. + - warning: This property is not intended to be set or modified by the developer. */ var originalData: Data? { get set } @@ -65,7 +66,8 @@ public protocol ParseObject: Objectable, a subset of the fields (PATCH) of an object as oppose to replacing an object (PUT). - note: It is recommended to use this to create a mutable copy of your `ParseObject`. - warning: `mutable` should only be used on `ParseObject`'s that have already - been saved at least once to a Parse Server and have a valid `objectId`. + been saved at least once to a Parse Server and have a valid `objectId`. In addition, + the developer should have implemented added all of their properties to `merge`. */ var mutable: Self { get } @@ -79,19 +81,21 @@ public protocol ParseObject: Objectable, original: Self) -> Bool where W: Equatable /** - Merges two `ParseObject`'s resulting in modified and unchanged Parse keys. + Merges two `ParseObject`'s with the resulting object consisting of all modified + and unchanged Parse properties. - parameter object: The original installation. - returns: The updated installation. - throws: An error of type `ParseError`. - - note: Use this in combination with `ParseMutable` to only send updated - keys to the server and then merge those changes with the original object. + - note: This is used in combination with `merge` to only send updated + properties to the server and then merge those changes with the original object. - warning: You should only call this method and shouldn't implement it directly as it's already implemented for developers to use. */ func mergeParse(_ object: Self) throws -> Self /** - Merges two `ParseObject`'s resulting in modified and unchanged keys. + Merges two `ParseObject`'s with the resulting object consisting of all modified + and unchanged properties. //: Create your own value typed `ParseObject`. struct GameScore: ParseObject { @@ -120,11 +124,11 @@ public protocol ParseObject: Objectable, - returns: The merged object. - throws: An error of type `ParseError`. - note: Use this in combination with `ParseMutable` to only send updated - keys to the server and then merge those changes with the original object. + properties to the server and then merge those changes with the original object. - important: It is recommend you provide an implementation of this method - for all of your `ParseObject`'s as the developer has access to all keys of a + for all of your `ParseObject`'s as the developer has access to all properties of a `ParseObject`. You should always call `mergeParse` - in the beginning of your implementation to handle all default Parse keys. In addition, + in the beginning of your implementation to handle all default Parse properties. In addition, use `shouldRestoreKey` to compare key modifications between objects. */ func merge(_ object: Self) throws -> Self From 0f64ca78f276a02148385e341afeb0ad6597b064 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Sat, 15 Jan 2022 11:31:52 -0500 Subject: [PATCH 13/26] coverage --- .../Contents.swift | 5 +- Sources/ParseSwift/Types/ParseRelation.swift | 9 -- .../ParseInstallationAsyncTests.swift | 97 +++++++++++++++++++ .../ParseSwiftTests/ParseUserAsyncTests.swift | 82 ++++++++++++++++ 4 files changed, 183 insertions(+), 10 deletions(-) diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index 889723d65..2850a9590 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -168,7 +168,10 @@ do { try savedRole!.users.query(templateUser).find { result in switch result { case .success(let relatedUsers): - print("The following users are part of the \"\(savedRole!.name) role: \(relatedUsers)") + print(""" + The following users are part of the + \"\(String(describing: savedRole!.name)) role: \(relatedUsers) + """) case .failure(let error): print("Error saving role: \(error)") diff --git a/Sources/ParseSwift/Types/ParseRelation.swift b/Sources/ParseSwift/Types/ParseRelation.swift index 870f50e39..315fd8239 100644 --- a/Sources/ParseSwift/Types/ParseRelation.swift +++ b/Sources/ParseSwift/Types/ParseRelation.swift @@ -344,12 +344,3 @@ extension ParseRelation: CustomStringConvertible { debugDescription } } - -struct StoredParseRelation: Decodable { - var className: String - var key: String - - func createParseRelation(_ parent: T) -> ParseRelation { - ParseRelation(parent: parent, key: key, className: className) - } -} diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index f75cb3260..e39579e4c 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -98,6 +98,26 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b } } + struct InstallationDefault: ParseInstallation { + var installationId: String? + var deviceType: String? + var deviceToken: String? + var badge: Int? + var timeZone: String? + var channels: [String]? + var appName: String? + var appIdentifier: String? + var appVersion: String? + var parseVersion: String? + var localeIdentifier: String? + var objectId: String? + var createdAt: Date? + var updatedAt: Date? + var ACL: ParseACL? + var score: Double? + var originalData: Data? + } + let testInstallationObjectId = "yarr" let loginUserName = "hello10" @@ -518,6 +538,83 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b } } + func testUpdateMutableMergeCurrentInstallationDefault() async throws { + // Save current Installation + try saveCurrentInstallation() + MockURLProtocol.removeAll() + + guard let original = InstallationDefault.current else { + XCTFail("Should unwrap") + return + } + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(InstallationDefault.self, + from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdate = original.mutable + originalUpdate.deviceToken = "1234" + let updated = originalUpdate + + do { + let saved = try await updated.update() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentInstallation = Installation.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameInstallationId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentInstallation)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.badge, original.badge) + XCTAssertEqual(saved.deviceType, original.deviceType) + XCTAssertEqual(saved.deviceToken, updated.deviceToken) + XCTAssertEqual(saved.channels, original.channels) + XCTAssertEqual(saved.installationId, original.installationId) + XCTAssertEqual(saved.timeZone, original.timeZone) + XCTAssertEqual(saved.appName, original.appName) + XCTAssertEqual(saved.appVersion, original.appVersion) + XCTAssertEqual(saved.appIdentifier, original.appIdentifier) + XCTAssertEqual(saved.parseVersion, original.parseVersion) + XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.badge, newCurrentInstallation.badge) + XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) + XCTAssertEqual(saved.deviceToken, newCurrentInstallation.deviceToken) + XCTAssertEqual(saved.channels, newCurrentInstallation.channels) + XCTAssertEqual(saved.installationId, newCurrentInstallation.installationId) + XCTAssertEqual(saved.timeZone, newCurrentInstallation.timeZone) + XCTAssertEqual(saved.appName, newCurrentInstallation.appName) + XCTAssertEqual(saved.appVersion, newCurrentInstallation.appVersion) + XCTAssertEqual(saved.appIdentifier, newCurrentInstallation.appIdentifier) + XCTAssertEqual(saved.parseVersion, newCurrentInstallation.parseVersion) + XCTAssertEqual(saved.localeIdentifier, newCurrentInstallation.localeIdentifier) + XCTAssertEqual(saved.createdAt, newCurrentInstallation.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentInstallation.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testUpdateClientMissingObjectId() async throws { var installation = Installation() diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 8559fe006..6300dbe69 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -44,6 +44,24 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng } } + struct UserDefault: ParseUser { + + //: These are required by ParseObject + var objectId: String? + var createdAt: Date? + var updatedAt: Date? + var ACL: ParseACL? + var score: Double? + var originalData: Data? + + // These are required by ParseUser + var username: String? + var email: String? + var emailVerified: Bool? + var password: String? + var authData: [String: [String: String]?]? + } + struct LoginSignupResponse: ParseUser { var objectId: String? @@ -819,6 +837,70 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng } } + func testUpdateMutableMergeCurrentUserDefault() async throws { + // Signup current User + login() + MockURLProtocol.removeAll() + XCTAssertNotNil(UserDefault.current?.objectId) + + guard let original = UserDefault.current else { + XCTFail("Should unwrap") + return + } + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(UserDefault.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + var originalUpdated = original.mutable + originalUpdated.username = "mode" + let updated = originalUpdated + + do { + let saved = try await updated.update() + let expectation1 = XCTestExpectation(description: "Update installation1") + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + guard let newCurrentUser = User.current else { + XCTFail("Should have a new current installation") + expectation1.fulfill() + return + } + XCTAssertTrue(saved.hasSameObjectId(as: newCurrentUser)) + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.email, original.email) + XCTAssertEqual(saved.username, updated.username) + XCTAssertEqual(saved.emailVerified, original.emailVerified) + XCTAssertEqual(saved.password, original.password) + XCTAssertEqual(saved.authData, original.authData) + XCTAssertEqual(saved.createdAt, original.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertEqual(saved.email, newCurrentUser.email) + XCTAssertEqual(saved.username, newCurrentUser.username) + XCTAssertEqual(saved.emailVerified, newCurrentUser.emailVerified) + XCTAssertEqual(saved.password, newCurrentUser.password) + XCTAssertEqual(saved.authData, newCurrentUser.authData) + XCTAssertEqual(saved.createdAt, newCurrentUser.createdAt) + XCTAssertEqual(saved.updatedAt, newCurrentUser.updatedAt) + expectation1.fulfill() + } + wait(for: [expectation1], timeout: 20.0) + } catch { + XCTFail(error.localizedDescription) + } + } + @MainActor func testDelete() async throws { login() From f1e4a0afba0fc92c4154c5d5a57f0232dbba8c81 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Sat, 15 Jan 2022 17:51:16 -0500 Subject: [PATCH 14/26] update Playgrounds --- CHANGELOG.md | 17 ++++++- .../Contents.swift | 1 + .../Contents.swift | 2 +- Sources/ParseSwift/API/API+Command.swift | 14 +++++- .../Objects/ParseInstallation.swift | 8 ++- Sources/ParseSwift/Objects/ParseUser.swift | 8 ++- Sources/ParseSwift/ParseConstants.swift | 2 +- .../ParseInstallationAsyncTests.swift | 2 + .../ParseInstallationTests.swift | 1 + .../ParseObjectAsyncTests.swift | 49 +++++++++++++++++++ .../ParseSwiftTests/ParseUserAsyncTests.swift | 2 + Tests/ParseSwiftTests/ParseUserTests.swift | 1 + 12 files changed, 97 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 986c4a87c..0041a4321 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,22 @@ ### main -[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.0...main) +[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.0.0...main) * _Contributing to this repo? Add info about your change here to be included in the next release_ +### 4.0.0 +[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.0...4.0.0) + +__New features__ +- (Breaking Change) Add the ability to merge updated ParseObject's with original objects when using the + .mutable property. To do this, developers need to add an implementation of merge() to + respective ParseObject's. The compiler will recommend the new originalData property be added to + every ParseObject. If you used ParseObjectMutable in the past, you should remove it as it is now + part of ParseObject. In addition, all ParseObject properties should be optional and every object + needs to have a default initilizer of init(). See the Playgrounds for recommendations on how to + define a ParseObject. Look at the PR for + details on why this is important when using the SDK ([#315](https://github.com/parse-community/Parse-Swift/pull/315)), thanks to [Corey Baker](https://github.com/cbaker6). + ### 3.1.0 [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.0.0...3.1.0) @@ -18,7 +31,7 @@ __New features__ - Adds equalTo QueryConstraint along with ability to change the SDK default behavior of using $eq QueryConstraint parameter or not ([#310](https://github.com/parse-community/Parse-Swift/pull/310)), thanks to [Corey Baker](https://github.com/cbaker6). - Adds isNull and isNotNull QueryConstraint along with the ability set/forceSet null using ParseOperation ([#308](https://github.com/parse-community/Parse-Swift/pull/308)), thanks to [Corey Baker](https://github.com/cbaker6). - Adds auth support for GitHub, Google, and LinkedIn ([#307](https://github.com/parse-community/Parse-Swift/pull/307)), thanks to [Corey Baker](https://github.com/cbaker6). -- (Breaking Change) Adds options to matchesText QueryConstraint along with the ability to see matching score. The compiler should recommend the new score property to all ParseObjects ([#306](https://github.com/parse-community/Parse-Swift/pull/306)), thanks to [Corey Baker](https://github.com/cbaker6). +- (Breaking Change) Adds options to matchesText QueryConstraint along with the ability to see matching score. The compiler will recommend the new score property be added to all ParseObjects ([#306](https://github.com/parse-community/Parse-Swift/pull/306)), thanks to [Corey Baker](https://github.com/cbaker6). - Adds withCount query ([#306](https://github.com/parse-community/Parse-Swift/pull/306)), thanks to [Corey Baker](https://github.com/cbaker6). __Improvements__ diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 94dacd9a0..019c5e555 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -225,6 +225,7 @@ changedScore.points = 200 let savedChangedScore: GameScore? do { savedChangedScore = try changedScore.save() + print("Updated score: \(String(describing: savedChangedScore))") } catch { savedChangedScore = nil fatalError("Error saving: \(error)") diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index 2dd872fc6..70dce2351 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -246,7 +246,7 @@ User.anonymous.login { result in } //: Convert the anonymous user to a real new user. -var currentUser2 = User.current +var currentUser2 = User.current?.mutable currentUser2?.username = "bye" currentUser2?.password = "world" currentUser2?.signup { result in diff --git a/Sources/ParseSwift/API/API+Command.swift b/Sources/ParseSwift/API/API+Command.swift index 0759728dc..e0475bb82 100644 --- a/Sources/ParseSwift/API/API+Command.swift +++ b/Sources/ParseSwift/API/API+Command.swift @@ -419,7 +419,12 @@ internal extension API.Command { message: "objectId must not be nil") } let mapper = { (mapperData: Data) -> T in - let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: mapperData).apply(to: object) + var updatedObject = object + updatedObject.originalData = nil + let object = try ParseCoding + .jsonDecoder() + .decode(ReplaceResponse.self, from: mapperData) + .apply(to: updatedObject) guard let originalData = data, let original = try? ParseCoding.jsonDecoder().decode(T.self, from: originalData), @@ -440,7 +445,12 @@ internal extension API.Command { message: "objectId must not be nil") } let mapper = { (mapperData: Data) -> T in - let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: mapperData).apply(to: object) + var updatedObject = object + updatedObject.originalData = nil + let object = try ParseCoding + .jsonDecoder() + .decode(UpdateResponse.self, from: mapperData) + .apply(to: updatedObject) guard let originalData = data, let original = try? ParseCoding.jsonDecoder().decode(T.self, from: originalData), diff --git a/Sources/ParseSwift/Objects/ParseInstallation.swift b/Sources/ParseSwift/Objects/ParseInstallation.swift index 3c228a65a..3386014e7 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation.swift @@ -768,7 +768,9 @@ extension ParseInstallation { message: "objectId must not be nil") } let mapper = { (data: Data) -> Self in - let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + var updatedObject = self + updatedObject.originalData = nil + let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: updatedObject) // MARK: The lines below should be removed when server supports PATCH. guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, @@ -790,7 +792,9 @@ extension ParseInstallation { message: "objectId must not be nil") } let mapper = { (data: Data) -> Self in - let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + var updatedObject = self + updatedObject.originalData = nil + let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: updatedObject) guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), diff --git a/Sources/ParseSwift/Objects/ParseUser.swift b/Sources/ParseSwift/Objects/ParseUser.swift index b67fb689b..dc1770739 100644 --- a/Sources/ParseSwift/Objects/ParseUser.swift +++ b/Sources/ParseSwift/Objects/ParseUser.swift @@ -1118,7 +1118,9 @@ extension ParseUser { #endif } let mapper = { (data: Data) -> Self in - let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: self) + var updatedObject = self + updatedObject.originalData = nil + let object = try ParseCoding.jsonDecoder().decode(ReplaceResponse.self, from: data).apply(to: updatedObject) // MARK: The lines below should be removed when server supports PATCH. guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, @@ -1155,7 +1157,9 @@ extension ParseUser { #endif } let mapper = { (data: Data) -> Self in - let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: self) + var updatedObject = self + updatedObject.originalData = nil + let object = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data).apply(to: updatedObject) guard let originalData = self.originalData, let original = try? ParseCoding.jsonDecoder().decode(Self.self, from: originalData), diff --git a/Sources/ParseSwift/ParseConstants.swift b/Sources/ParseSwift/ParseConstants.swift index 1bad86624..4f8da54fb 100644 --- a/Sources/ParseSwift/ParseConstants.swift +++ b/Sources/ParseSwift/ParseConstants.swift @@ -10,7 +10,7 @@ import Foundation enum ParseConstants { static let sdk = "swift" - static let version = "3.1.0" + static let version = "4.0.0" static let fileManagementDirectory = "parse/" static let fileManagementPrivateDocumentsDirectory = "Private Documents/" static let fileManagementLibraryDirectory = "Library/" diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index e39579e4c..22a1c0eb4 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -516,6 +516,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.customKey, newCurrentInstallation.customKey) XCTAssertEqual(saved.badge, newCurrentInstallation.badge) XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) @@ -594,6 +595,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.badge, newCurrentInstallation.badge) XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) XCTAssertEqual(saved.deviceToken, newCurrentInstallation.deviceToken) diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index bc241dd9e..c6f00bb1e 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -535,6 +535,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l XCTAssertEqual(saved.localeIdentifier, original.localeIdentifier) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.customKey, newCurrentInstallation.customKey) XCTAssertEqual(saved.badge, newCurrentInstallation.badge) XCTAssertEqual(saved.deviceType, newCurrentInstallation.deviceType) diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index 4e9c2782c..6e2594354 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -57,6 +57,17 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le } } + struct GameScoreDefault: ParseObject { + + //: These are required by ParseObject + var objectId: String? + var createdAt: Date? + var updatedAt: Date? + var ACL: ParseACL? + var score: Double? + var originalData: Data? + } + override func setUpWithError() throws { try super.setUpWithError() guard let url = URL(string: "http://localhost:1337/1") else { @@ -191,6 +202,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le XCTAssertEqual(saved.player, original.player) XCTAssertEqual(saved.createdAt, response.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) } catch { XCTFail(error.localizedDescription) } @@ -407,6 +419,43 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le XCTAssertEqual(saved.player, original.player) XCTAssertEqual(saved.createdAt, response.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) + } catch { + XCTFail(error.localizedDescription) + } + } + + @MainActor + func testUpdateMutableDefault() async throws { + var original = GameScoreDefault() + original.objectId = "yarr" + + var originalResponse = original.mutable + originalResponse.createdAt = nil + originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) + + let encoded: Data! + do { + encoded = try originalResponse.getEncoder().encode(originalResponse, skipKeys: .none) + //Get dates in correct format from ParseDecoding strategy + originalResponse = try originalResponse.getDecoder().decode(GameScoreDefault.self, from: encoded) + } catch { + XCTFail("Should encode/decode. Error \(error)") + return + } + MockURLProtocol.mockRequests { _ in + return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) + } + let response = originalResponse + let originalUpdated = original.mutable + let updated = originalUpdated + + do { + let saved = try await updated.update() + XCTAssertTrue(saved.hasSameObjectId(as: response)) + XCTAssertEqual(saved.createdAt, response.createdAt) + XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) } catch { XCTFail(error.localizedDescription) } diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 6300dbe69..472fbf34e 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -821,6 +821,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng XCTAssertEqual(saved.authData, original.authData) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.customKey, newCurrentUser.customKey) XCTAssertEqual(saved.email, newCurrentUser.email) XCTAssertEqual(saved.username, newCurrentUser.username) @@ -886,6 +887,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng XCTAssertEqual(saved.authData, original.authData) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.email, newCurrentUser.email) XCTAssertEqual(saved.username, newCurrentUser.username) XCTAssertEqual(saved.emailVerified, newCurrentUser.emailVerified) diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index 4b1e303db..6ff119980 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -879,6 +879,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length XCTAssertEqual(saved.authData, original.authData) XCTAssertEqual(saved.createdAt, original.createdAt) XCTAssertEqual(saved.updatedAt, response.updatedAt) + XCTAssertNil(saved.originalData) XCTAssertEqual(saved.customKey, newCurrentUser.customKey) XCTAssertEqual(saved.email, newCurrentUser.email) XCTAssertEqual(saved.username, newCurrentUser.username) From 4d0d802895ddcbd3407712773ed13c606c5bbf47 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Sun, 16 Jan 2022 12:52:46 -0500 Subject: [PATCH 15/26] tested and nit playgrounds --- .../Contents.swift | 2 +- .../Contents.swift | 2 +- .../Contents.swift | 1 - Sources/ParseSwift/Coding/ParseCoding.swift | 3 ++- Sources/ParseSwift/Coding/ParseEncoder.swift | 21 ++++++++++++++----- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index 2850a9590..6cfc2e7f8 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -301,7 +301,7 @@ let score2 = GameScore(points: 57) switch result { case .success(let saved): print("The relation saved successfully: \(saved)") - print("Check \"pointss\" field in your \"_User\" class in Parse Dashboard.") + print("Check \"points\" field in your \"_User\" class in Parse Dashboard.") case .failure(let error): print("Error saving role: \(error)") diff --git a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift index a10bad0bd..b54b5fd2b 100644 --- a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift @@ -136,7 +136,7 @@ query.withCount { results in } //: Query based on relative time. -let queryRelative = GameScore.query(relative("createdAt" < "10 minutes ago")) +let queryRelative = GameScore.query(relative("createdAt" < "in 10 minutes")) queryRelative.find { results in switch results { case .success(let scores): diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index 3b73408b1..da49dfa58 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -228,7 +228,6 @@ do { assert(updatedBook.objectId != nil) assert(updatedBook.createdAt != nil) assert(updatedBook.updatedAt != nil) - assert(updatedBook.ACL == nil) assert(updatedBook.relatedBook != nil) print("Saved \(updatedBook)") diff --git a/Sources/ParseSwift/Coding/ParseCoding.swift b/Sources/ParseSwift/Coding/ParseCoding.swift index 7b232314e..14d7df0f1 100644 --- a/Sources/ParseSwift/Coding/ParseCoding.swift +++ b/Sources/ParseSwift/Coding/ParseCoding.swift @@ -37,7 +37,8 @@ extension ParseCoding { /// types in a way meaninful for a Parse Server to consume. static func parseEncoder() -> ParseEncoder { ParseEncoder( - dateEncodingStrategy: parseDateEncodingStrategy + dateEncodingStrategy: parseDateEncodingStrategy, + outputFormatting: .sortedKeys ) } } diff --git a/Sources/ParseSwift/Coding/ParseEncoder.swift b/Sources/ParseSwift/Coding/ParseEncoder.swift index 328749e9b..6e682af88 100644 --- a/Sources/ParseSwift/Coding/ParseEncoder.swift +++ b/Sources/ParseSwift/Coding/ParseEncoder.swift @@ -54,6 +54,7 @@ extension Dictionary: _JSONStringDictionaryEncodableMarker where Key == String, */ public struct ParseEncoder { let dateEncodingStrategy: JSONEncoder.DateEncodingStrategy? + let outputFormatting: JSONEncoder.OutputFormatting? /// Keys to skip during encoding. public enum SkipKeys { @@ -96,16 +97,20 @@ public struct ParseEncoder { } init( - dateEncodingStrategy: JSONEncoder.DateEncodingStrategy? = nil + dateEncodingStrategy: JSONEncoder.DateEncodingStrategy? = nil, + outputFormatting: JSONEncoder.OutputFormatting? = .sortedKeys ) { self.dateEncodingStrategy = dateEncodingStrategy + self.outputFormatting = outputFormatting } func encode(_ value: Encodable) throws -> Data { let encoder = _ParseEncoder(codingPath: [], dictionary: NSMutableDictionary(), skippingKeys: SkipKeys.none.keys()) if let dateEncodingStrategy = dateEncodingStrategy { encoder.dateEncodingStrategy = dateEncodingStrategy - encoder.outputFormatting = .sortedKeys + } + if let outputFormatting = outputFormatting { + encoder.outputFormatting = outputFormatting } return try encoder.encodeObject(value, collectChildren: false, @@ -125,7 +130,9 @@ public struct ParseEncoder { if let dateEncodingStrategy = dateEncodingStrategy { encoder.dateEncodingStrategy = dateEncodingStrategy } - encoder.outputFormatting = .sortedKeys + if let outputFormatting = outputFormatting { + encoder.outputFormatting = outputFormatting + } return try encoder.encodeObject(value, collectChildren: false, uniquePointer: nil, @@ -147,7 +154,9 @@ public struct ParseEncoder { if let dateEncodingStrategy = dateEncodingStrategy { encoder.dateEncodingStrategy = dateEncodingStrategy } - encoder.outputFormatting = .sortedKeys + if let outputFormatting = outputFormatting { + encoder.outputFormatting = outputFormatting + } return try encoder.encodeObject(value, collectChildren: true, uniquePointer: try? value.toPointer(), @@ -170,7 +179,9 @@ public struct ParseEncoder { if let dateEncodingStrategy = dateEncodingStrategy { encoder.dateEncodingStrategy = dateEncodingStrategy } - encoder.outputFormatting = .sortedKeys + if let outputFormatting = outputFormatting { + encoder.outputFormatting = outputFormatting + } return try encoder.encodeObject(value, collectChildren: collectChildren, uniquePointer: nil, From 509c19f9b21f586e89cbf5b1a24391306e51a664 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 17 Jan 2022 15:32:11 -0500 Subject: [PATCH 16/26] fix merge conflicts --- CHANGELOG.md | 7 +- .../Contents.swift | 8 -- .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 12 -- .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 1 - .../Contents.swift | 8 -- .../5 - ACL.xcplaygroundpage/Contents.swift | 4 - .../Contents.swift | 4 - .../Contents.swift | 10 -- .../9 - Files.xcplaygroundpage/Contents.swift | 4 - .../BaseParseInstallation.swift | 4 - .../InternalObjects/BaseParseUser.swift | 4 - Sources/ParseSwift/Objects/ParseObject.swift | 14 --- Sources/ParseSwift/ParseConstants.swift | 4 - .../Protocols/ParseObjectMutable.swift | 114 ------------------ Tests/ParseSwiftTests/APICommandTests.swift | 10 -- Tests/ParseSwiftTests/IOS13Tests.swift | 9 -- .../ParseSwiftTests/InitializeSDKTests.swift | 4 - Tests/ParseSwiftTests/ParseACLTests.swift | 12 -- .../ParseAnonymousAsyncTests.swift | 8 -- .../ParseAnonymousCombineTests.swift | 8 -- .../ParseSwiftTests/ParseAnonymousTests.swift | 8 -- .../ParseAppleAsyncTests.swift | 8 -- .../ParseAppleCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseAppleTests.swift | 8 -- .../ParseAuthenticationAsyncTests.swift | 8 -- .../ParseAuthenticationCombineTests.swift | 8 -- .../ParseAuthenticationTests.swift | 8 -- .../ParseConfigAsyncTests.swift | 8 -- .../ParseConfigCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseConfigTests.swift | 8 -- .../ParseFacebookAsyncTests.swift | 8 -- .../ParseFacebookCombineTests.swift | 8 -- .../ParseSwiftTests/ParseFacebookTests.swift | 8 -- .../ParseGitHubCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseGitHubTests.swift | 8 -- .../ParseGoogleCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseGoogleTests.swift | 8 -- .../ParseInstallationAsyncTests.swift | 13 -- .../ParseInstallationCombineTests.swift | 12 -- .../ParseInstallationTests.swift | 12 -- .../ParseSwiftTests/ParseLDAPAsyncTests.swift | 8 -- .../ParseLDAPCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseLDAPTests.swift | 8 -- .../ParseLinkedInCombineTests.swift | 8 -- .../ParseSwiftTests/ParseLinkedInTests.swift | 8 -- .../ParseSwiftTests/ParseLiveQueryTests.swift | 4 - .../ParseObjectAsyncTests.swift | 5 - .../ParseObjectBatchTests.swift | 8 -- .../ParseObjectCombineTests.swift | 4 - .../ParseObjectCustomObjectIdTests.swift | 21 ---- Tests/ParseSwiftTests/ParseObjectTests.swift | 33 ----- .../ParseOperationAsyncTests.swift | 4 - .../ParseOperationCombineTests.swift | 4 - .../ParseSwiftTests/ParseOperationTests.swift | 8 -- .../ParsePointerAsyncTests.swift | 4 - .../ParsePointerCombineTests.swift | 4 - Tests/ParseSwiftTests/ParsePointerTests.swift | 4 - .../ParseQueryAsyncTests.swift | 4 - .../ParseQueryCombineTests.swift | 4 - Tests/ParseSwiftTests/ParseQueryTests.swift | 4 - .../ParseQueryViewModelTests.swift | 4 - .../ParseSwiftTests/ParseRelationTests.swift | 8 -- Tests/ParseSwiftTests/ParseRoleTests.swift | 16 --- Tests/ParseSwiftTests/ParseSessionTests.swift | 4 - .../ParseTwitterAsyncTests.swift | 8 -- .../ParseTwitterCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseTwitterTests.swift | 8 -- .../ParseSwiftTests/ParseUserAsyncTests.swift | 9 -- .../ParseUserCombineTests.swift | 8 -- Tests/ParseSwiftTests/ParseUserTests.swift | 8 -- 78 files changed, 1 insertion(+), 689 deletions(-) delete mode 100644 Sources/ParseSwift/Protocols/ParseObjectMutable.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f317f022..688d9d6da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,11 @@ ### main -<<<<<<< HEAD [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.0.0...main) * _Contributing to this repo? Add info about your change here to be included in the next release_ ### 4.0.0 -[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.1...4.0.0) +[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.2...4.0.0) __New features__ - (Breaking Change) Add the ability to merge updated ParseObject's with original objects when using the @@ -18,9 +17,6 @@ __New features__ needs to have a default initilizer of init(). See the Playgrounds for recommendations on how to define a ParseObject. Look at the PR for details on why this is important when using the SDK ([#315](https://github.com/parse-community/Parse-Swift/pull/315)), thanks to [Corey Baker](https://github.com/cbaker6). -======= -[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.2...main) -* _Contributing to this repo? Add info about your change here to be included in the next release_ ### 3.1.2 [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.1...3.1.2) @@ -28,7 +24,6 @@ __New features__ __Fixes__ - Allowing building of the Swift SDK for Swift 5.5.0 and 5.5.1 re-enabling builds for Xcode 13.0 and 13.1. Note that async/await functionality is only available for Swift 5.5.2+ and Xcode 13.2+ ([#320](https://github.com/parse-community/Parse-Swift/pull/320)), thanks to [Corey Baker](https://github.com/cbaker6). - Move the var score: Double? to a protocol named ParseQueryScorable. When developers want to sort by score using a matchesText QueryConstraint, they just conform their ParseObject's to ParseQueryScorable ([#319](https://github.com/parse-community/Parse-Swift/pull/319)), thanks to [Corey Baker](https://github.com/cbaker6). ->>>>>>> main ### 3.1.1 [Full Changelog](https://github.com/parse-community/Parse-Swift/compare/3.1.0...3.1.1) diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 7d8ac7e5b..7e89364c8 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -36,11 +36,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? @@ -75,11 +71,7 @@ struct GameData: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var polygon: ParsePolygon? diff --git a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift index 6b39d4d06..7319682ba 100644 --- a/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/10 - Cloud Code.xcplaygroundpage/Contents.swift @@ -106,11 +106,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift index 23a032d50..e49ae8cae 100644 --- a/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/11 - LiveQuery.xcplaygroundpage/Contents.swift @@ -16,11 +16,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift index f73a0c030..5379d8401 100644 --- a/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift @@ -19,11 +19,7 @@ struct User: ParseUser { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: These are required by `ParseUser`. var username: String? @@ -53,11 +49,7 @@ struct Role: ParseRole { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Provided by Role. var name: String? @@ -80,11 +72,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift index b6aaa986f..92a964ea6 100644 --- a/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift @@ -19,11 +19,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift index 1481402ed..54814fb16 100644 --- a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift @@ -27,11 +27,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift index 10a216ad4..06654652f 100644 --- a/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/17 - SwiftUI - Finding Objects.xcplaygroundpage/Contents.swift @@ -25,11 +25,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift index 38af0e3d9..059e9d968 100644 --- a/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/18 - SwiftUI - Finding Objects With Custom ViewModel.xcplaygroundpage/Contents.swift @@ -26,11 +26,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift index 1d2372650..c79743a10 100644 --- a/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/19 - SwiftUI - LiveQuery.xcplaygroundpage/Contents.swift @@ -24,11 +24,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? = 0 diff --git a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift index a7f5ee40d..fb5df2e62 100644 --- a/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift @@ -18,11 +18,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? diff --git a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift index 638a81c44..d95110d40 100644 --- a/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/3 - User - Sign Up.xcplaygroundpage/Contents.swift @@ -19,7 +19,6 @@ struct User: ParseUser { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? var originalData: Data? //: These are required by `ParseUser`. diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index 38286e304..d949278f9 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -19,11 +19,7 @@ struct User: ParseUser { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: These are required by `ParseUser`. var username: String? @@ -79,11 +75,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? = 0 diff --git a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift index 214aad743..d04f21d50 100644 --- a/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/5 - ACL.xcplaygroundpage/Contents.swift @@ -29,11 +29,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index 4af25a794..721c4a522 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -19,11 +19,7 @@ struct Installation: ParseInstallation { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: These are required by `ParseInstallation`. var installationId: String? diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index 7051b8e53..dac15e7d4 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -21,15 +21,11 @@ struct Book: ParseObject, ParseQueryScorable { var updatedAt: Date? var ACL: ParseACL? var score: Double? -<<<<<<< HEAD var originalData: Data? -======= ->>>>>>> main //: Your own properties. var title: String? var relatedBook: Pointer? -<<<<<<< HEAD //: Implement your own version of merge func merge(_ object: Self) throws -> Self { @@ -44,8 +40,6 @@ struct Book: ParseObject, ParseQueryScorable { } return updated } -======= ->>>>>>> main } //: It's recommended to place custom initializers in an extension @@ -63,11 +57,7 @@ struct Author: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var name: String? diff --git a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift index 7473c93ed..f3547875f 100644 --- a/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/9 - Files.xcplaygroundpage/Contents.swift @@ -20,11 +20,7 @@ struct GameScore: ParseObject { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties. var points: Int? = 0 diff --git a/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift b/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift index 1bf6410fb..a4476c3b3 100644 --- a/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift +++ b/Sources/ParseSwift/InternalObjects/BaseParseInstallation.swift @@ -24,11 +24,7 @@ internal struct BaseParseInstallation: ParseInstallation { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main static func createNewInstallationIfNeeded() { guard let installationId = Self.currentContainer.installationId, diff --git a/Sources/ParseSwift/InternalObjects/BaseParseUser.swift b/Sources/ParseSwift/InternalObjects/BaseParseUser.swift index 8879c0e86..9516445a7 100644 --- a/Sources/ParseSwift/InternalObjects/BaseParseUser.swift +++ b/Sources/ParseSwift/InternalObjects/BaseParseUser.swift @@ -18,9 +18,5 @@ internal struct BaseParseUser: ParseUser { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main } diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 003e20a52..286d6538e 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -27,13 +27,8 @@ import Foundation create methods to check the respective properties on the client-side before saving objects. See [here](https://github.com/parse-community/Parse-Swift/issues/157#issuecomment-858671025) for more information. -<<<<<<< HEAD - important: To take advantage of `mutable`, the developer should implement the `merge` method in every `ParseObject`. - - important: The property, "score," is a Parse Server designated keyword and you should avoid naming any of - your `ParseObject` properties "score". Doing so may result in decoding issues. -======= ->>>>>>> main - warning: If you plan to use "reference types" (classes), you are using at your risk as this SDK is not designed for reference types and may have unexpected behavior when it comes to threading. You will also need to implement your own `==` method to conform to `Equatable` along with with the `hash` method to conform to `Hashable`. @@ -51,12 +46,7 @@ public protocol ParseObject: Objectable, Identifiable, Hashable, CustomDebugStringConvertible, -<<<<<<< HEAD CustomStringConvertible { - /** - The weight/rank of a `QueryConstraint.matchesText()`. - */ - var score: Double? { get } /** A JSON encoded version of this `ParseObject` before `mutable` was called and @@ -108,7 +98,6 @@ public protocol ParseObject: Objectable, var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? //: Your own properties. var points: Int? @@ -139,9 +128,6 @@ public protocol ParseObject: Objectable, init() } -======= - CustomStringConvertible { } ->>>>>>> main // MARK: Default Implementations public extension ParseObject { diff --git a/Sources/ParseSwift/ParseConstants.swift b/Sources/ParseSwift/ParseConstants.swift index b24daff71..4f8da54fb 100644 --- a/Sources/ParseSwift/ParseConstants.swift +++ b/Sources/ParseSwift/ParseConstants.swift @@ -10,11 +10,7 @@ import Foundation enum ParseConstants { static let sdk = "swift" -<<<<<<< HEAD static let version = "4.0.0" -======= - static let version = "3.1.2" ->>>>>>> main static let fileManagementDirectory = "parse/" static let fileManagementPrivateDocumentsDirectory = "Private Documents/" static let fileManagementLibraryDirectory = "Library/" diff --git a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift b/Sources/ParseSwift/Protocols/ParseObjectMutable.swift deleted file mode 100644 index 297239083..000000000 --- a/Sources/ParseSwift/Protocols/ParseObjectMutable.swift +++ /dev/null @@ -1,114 +0,0 @@ -// -// ParseObjectMutable.swift -// ParseSwift -// -// Created by Damian Van de Kauter on 30/10/2021. -// Copyright © 2021 Parse Community. All rights reserved. -// - -import Foundation - -/** - The `ParseObjectMutable` protocol creates an empty copy of the respective object. - This can be used when you only need to update a subset of the fields (PATCH) of an object - as oppose to replacing (PUT) an object. - Using the mutable copy and updating a subset of the fields reduces the amount of data - sent between client and server when using `save` and `saveAll` - to update objects. - - **Example use case for `ParseUser`:** - ```` - struct User: ParseUser, ParseObjectMutable { - //: These are required by `ParseObject`. - var objectId: String? - var createdAt: Date? - var updatedAt: Date? - var ACL: ParseACL? - var score: Double? - - //: These are required by `ParseUser`. - var username: String? - var email: String? - var emailVerified: Bool? - var password: String? - var authData: [String: [String: String]?]? - - //: Your custom keys. - var customKey: String? - var gameScore: GameScore? - var targetScore: GameScore? - var allScores: [GameScore]? - } - - var user = User.current?.mutable - user?.customKey = "newValue" - - do { - try await user?.save() - } catch { - // Handle error - } - ```` - - **Example use case for a general `ParseObject`:** - ```` - struct GameScore: ParseObject, ParseObjectMutable { - //: These are required by ParseObject - var objectId: String? - var createdAt: Date? - var updatedAt: Date? - var ACL: ParseACL? - var score: Double? - - //: Your own properties. - var points: Int = 0 - } - //: It's recommended to place custom initializers in an extension - //: to preserve the convenience initializer. - extension GameScore { - - init(points: Int) { - self.points = points - } - - init(objectId: String?) { - self.objectId = objectId - } - } - - var newScore = GameScore(points: 10).mutable - newScore.points = 200 - - do { - try await newScore.save() - } catch { - // Handle error - } - ```` - - - warning: Using the `ParseObjectMutable` protocol requires the developer to - initialize all of the `ParseObject` properties. This can be accomplished by making all properties - optional or setting default values for non-optional properties. - This also allows your objects to be used as Parse `Pointer`‘s. - It's recommended to place custom initializers in an extension - to preserve the convenience initializer. -*/ -public protocol ParseObjectMutable: ParseObject { - init() - - /** - An empty copy of the respective object that allows you to update a - a subset of the fields of an object as oppose to updating every field of an object. - - note: It is recommended to use this to create a mutable copy of your `ParseObject`. - */ - var mutable: Self { get } -} - -public extension ParseObjectMutable { - var mutable: Self { - var object = Self() - object.objectId = objectId - object.createdAt = createdAt - return object - } -} diff --git a/Tests/ParseSwiftTests/APICommandTests.swift b/Tests/ParseSwiftTests/APICommandTests.swift index 8040f3b1b..1ec49d01e 100644 --- a/Tests/ParseSwiftTests/APICommandTests.swift +++ b/Tests/ParseSwiftTests/APICommandTests.swift @@ -22,13 +22,8 @@ class APICommandTests: XCTestCase { var ACL: ParseACL? var name = "First" -<<<<<<< HEAD - - var score: Double? var originalData: Data? -======= ->>>>>>> main } override func setUpWithError() throws { @@ -60,7 +55,6 @@ class APICommandTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? var originalData: Data? // These are required by ParseUser @@ -81,11 +75,7 @@ class APICommandTests: XCTestCase { var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/IOS13Tests.swift b/Tests/ParseSwiftTests/IOS13Tests.swift index 29cd01d11..51effb8c8 100644 --- a/Tests/ParseSwiftTests/IOS13Tests.swift +++ b/Tests/ParseSwiftTests/IOS13Tests.swift @@ -20,13 +20,8 @@ class IOS13Tests: XCTestCase { // swiftlint:disable:this type_body_length var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? - var originalData: Data? -======= ->>>>>>> main var name = "First" } @@ -37,11 +32,7 @@ class IOS13Tests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/InitializeSDKTests.swift b/Tests/ParseSwiftTests/InitializeSDKTests.swift index 33b8c06ef..1f61965fb 100644 --- a/Tests/ParseSwiftTests/InitializeSDKTests.swift +++ b/Tests/ParseSwiftTests/InitializeSDKTests.swift @@ -27,11 +27,7 @@ class InitializeSDKTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseACLTests.swift b/Tests/ParseSwiftTests/ParseACLTests.swift index 908a0a243..44ca16be8 100644 --- a/Tests/ParseSwiftTests/ParseACLTests.swift +++ b/Tests/ParseSwiftTests/ParseACLTests.swift @@ -40,11 +40,7 @@ class ParseACLTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -64,11 +60,7 @@ class ParseACLTests: XCTestCase { var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -100,11 +92,7 @@ class ParseACLTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // provided by Role var name: String? diff --git a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift index 7e4a17fda..5c60fd928 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift @@ -22,11 +22,7 @@ class ParseAnonymousAsyncTests: XCTestCase { // swiftlint:disable:this type_body var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseAnonymousAsyncTests: XCTestCase { // swiftlint:disable:this type_body var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift b/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift index 313dd855f..a5e3f678b 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousCombineTests.swift @@ -22,11 +22,7 @@ class ParseAnonymousCombineTests: XCTestCase { // swiftlint:disable:this type_bo var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseAnonymousCombineTests: XCTestCase { // swiftlint:disable:this type_bo var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAnonymousTests.swift b/Tests/ParseSwiftTests/ParseAnonymousTests.swift index 8cf2d13e8..02b47cb12 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousTests.swift @@ -19,11 +19,7 @@ class ParseAnonymousTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -40,11 +36,7 @@ class ParseAnonymousTests: XCTestCase { var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift index 7b6967105..b133a7599 100644 --- a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift @@ -22,11 +22,7 @@ class ParseAppleAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseAppleAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleCombineTests.swift b/Tests/ParseSwiftTests/ParseAppleCombineTests.swift index 97c03bdda..10da1b71b 100644 --- a/Tests/ParseSwiftTests/ParseAppleCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleCombineTests.swift @@ -22,11 +22,7 @@ class ParseAppleCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseAppleCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAppleTests.swift b/Tests/ParseSwiftTests/ParseAppleTests.swift index f82799b25..c651ebbe1 100644 --- a/Tests/ParseSwiftTests/ParseAppleTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleTests.swift @@ -18,11 +18,7 @@ class ParseAppleTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -39,11 +35,7 @@ class ParseAppleTests: XCTestCase { var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift index 91b615d3f..2f73ef4dd 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift @@ -25,11 +25,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -46,11 +42,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift index f33018560..ebf465945 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift @@ -25,11 +25,7 @@ class ParseAuthenticationCombineTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -46,11 +42,7 @@ class ParseAuthenticationCombineTests: XCTestCase { var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift index 687edc282..083973325 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift @@ -25,11 +25,7 @@ class ParseAuthenticationTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -46,11 +42,7 @@ class ParseAuthenticationTests: XCTestCase { var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift index 807618224..f0bd52a09 100644 --- a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift @@ -27,11 +27,7 @@ class ParseConfigAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -51,11 +47,7 @@ class ParseConfigAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigCombineTests.swift b/Tests/ParseSwiftTests/ParseConfigCombineTests.swift index 511633266..e8b3d93f0 100644 --- a/Tests/ParseSwiftTests/ParseConfigCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigCombineTests.swift @@ -27,11 +27,7 @@ class ParseConfigCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -51,11 +47,7 @@ class ParseConfigCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseConfigTests.swift b/Tests/ParseSwiftTests/ParseConfigTests.swift index e0d5054f5..b5627881b 100644 --- a/Tests/ParseSwiftTests/ParseConfigTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigTests.swift @@ -24,11 +24,7 @@ class ParseConfigTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -48,11 +44,7 @@ class ParseConfigTests: XCTestCase { // swiftlint:disable:this type_body_length var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift index 091583166..cbfced4f0 100644 --- a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift @@ -22,11 +22,7 @@ class ParseFacebookAsyncTests: XCTestCase { // swiftlint:disable:this type_body_ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseFacebookAsyncTests: XCTestCase { // swiftlint:disable:this type_body_ var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift b/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift index ecbebfc95..fa86f2995 100644 --- a/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookCombineTests.swift @@ -22,11 +22,7 @@ class ParseFacebookCombineTests: XCTestCase { // swiftlint:disable:this type_bod var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseFacebookCombineTests: XCTestCase { // swiftlint:disable:this type_bod var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseFacebookTests.swift b/Tests/ParseSwiftTests/ParseFacebookTests.swift index 49c4cda0e..fc2567c89 100644 --- a/Tests/ParseSwiftTests/ParseFacebookTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookTests.swift @@ -18,11 +18,7 @@ class ParseFacebookTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -39,11 +35,7 @@ class ParseFacebookTests: XCTestCase { var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift b/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift index 216f72a4a..542a82c36 100644 --- a/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubCombineTests.swift @@ -22,11 +22,7 @@ class ParseGitHubCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseGitHubCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGitHubTests.swift b/Tests/ParseSwiftTests/ParseGitHubTests.swift index 6c5e1ff98..5afa3da85 100644 --- a/Tests/ParseSwiftTests/ParseGitHubTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubTests.swift @@ -21,11 +21,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -42,11 +38,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift b/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift index d6c44022d..314ffed97 100644 --- a/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleCombineTests.swift @@ -22,11 +22,7 @@ class ParseGoogleCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseGoogleCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseGoogleTests.swift b/Tests/ParseSwiftTests/ParseGoogleTests.swift index 709031871..60779a872 100644 --- a/Tests/ParseSwiftTests/ParseGoogleTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleTests.swift @@ -21,11 +21,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -42,11 +38,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index c1cda9f4c..140188126 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -23,11 +23,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -47,11 +43,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -92,11 +84,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var customKey: String? //: Implement your own version of merge @@ -126,7 +114,6 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? var originalData: Data? } diff --git a/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift b/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift index f1ad6ff10..b4ff30e2a 100644 --- a/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationCombineTests.swift @@ -22,11 +22,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -46,11 +42,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -91,11 +83,7 @@ class ParseInstallationCombineTests: XCTestCase { // swiftlint:disable:this type var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index e749f3583..4b4420ab0 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -19,11 +19,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -88,11 +80,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var customKey: String? //: Implement your own version of merge diff --git a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift index 66ab74acc..d2ce5910d 100644 --- a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift @@ -22,11 +22,7 @@ class ParseLDAPAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseLDAPAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift b/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift index 437b15d57..fe28deb27 100644 --- a/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPCombineTests.swift @@ -22,11 +22,7 @@ class ParseLDAPCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseLDAPCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLDAPTests.swift b/Tests/ParseSwiftTests/ParseLDAPTests.swift index 1b4350712..a594ac426 100644 --- a/Tests/ParseSwiftTests/ParseLDAPTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPTests.swift @@ -18,11 +18,7 @@ class ParseLDAPTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -39,11 +35,7 @@ class ParseLDAPTests: XCTestCase { var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift b/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift index 03b33be3e..5eb909168 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInCombineTests.swift @@ -22,11 +22,7 @@ class ParseLinkedInCombineTests: XCTestCase { // swiftlint:disable:this type_bod var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseLinkedInCombineTests: XCTestCase { // swiftlint:disable:this type_bod var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLinkedInTests.swift b/Tests/ParseSwiftTests/ParseLinkedInTests.swift index 3f83b7b29..bd5d4adf3 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInTests.swift @@ -21,11 +21,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -42,11 +38,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseLiveQueryTests.swift b/Tests/ParseSwiftTests/ParseLiveQueryTests.swift index 521d86d21..6253aeea3 100644 --- a/Tests/ParseSwiftTests/ParseLiveQueryTests.swift +++ b/Tests/ParseSwiftTests/ParseLiveQueryTests.swift @@ -17,11 +17,7 @@ class ParseLiveQueryTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int = 0 diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index 21a49e939..830133646 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -23,11 +23,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? @@ -70,7 +66,6 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? var originalData: Data? } diff --git a/Tests/ParseSwiftTests/ParseObjectBatchTests.swift b/Tests/ParseSwiftTests/ParseObjectBatchTests.swift index 76e2336f1..1144573b9 100644 --- a/Tests/ParseSwiftTests/ParseObjectBatchTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectBatchTests.swift @@ -18,11 +18,7 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // Custom properties var points: Int = 0 @@ -47,11 +43,7 @@ class ParseObjectBatchTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var name = "Hello" diff --git a/Tests/ParseSwiftTests/ParseObjectCombineTests.swift b/Tests/ParseSwiftTests/ParseObjectCombineTests.swift index 20d8b84ae..13d31f77a 100644 --- a/Tests/ParseSwiftTests/ParseObjectCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectCombineTests.swift @@ -21,11 +21,7 @@ class ParseObjectCombineTests: XCTestCase { // swiftlint:disable:this type_body_ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift b/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift index b9ac059b9..af84d5c26 100644 --- a/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectCustomObjectIdTests.swift @@ -20,13 +20,8 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? - var originalData: Data? -======= ->>>>>>> main var name = "First" } @@ -36,11 +31,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? @@ -69,11 +60,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var gameScore: GameScore @@ -97,11 +84,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -130,11 +113,7 @@ class ParseObjectCustomObjectIdTests: XCTestCase { // swiftlint:disable:this typ var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var customKey: String? } diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index 6f50397d0..25e4508b6 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -22,13 +22,8 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var name: String? -<<<<<<< HEAD - var score: Double? - var originalData: Data? -======= ->>>>>>> main init() { name = "First" } @@ -40,11 +35,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? @@ -97,11 +88,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var gameScore: GameScore @@ -125,11 +112,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var name = "Hello" @@ -143,11 +126,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int @@ -206,11 +185,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var gameScore: GameScoreClass @@ -266,11 +241,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -290,11 +261,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift index b841ba068..6840eb432 100644 --- a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift @@ -21,11 +21,7 @@ class ParseOperationAsyncTests: XCTestCase { // swiftlint:disable:this type_body var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseOperationCombineTests.swift b/Tests/ParseSwiftTests/ParseOperationCombineTests.swift index 64835184e..2a1b30f8b 100644 --- a/Tests/ParseSwiftTests/ParseOperationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationCombineTests.swift @@ -21,11 +21,7 @@ class ParseOperationCombineTests: XCTestCase { // swiftlint:disable:this type_bo var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseOperationTests.swift b/Tests/ParseSwiftTests/ParseOperationTests.swift index aba65b387..fe146aafa 100644 --- a/Tests/ParseSwiftTests/ParseOperationTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationTests.swift @@ -17,11 +17,7 @@ class ParseOperationTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? @@ -48,11 +44,7 @@ class ParseOperationTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift index dcfa82f3c..2d5765897 100644 --- a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift @@ -22,11 +22,7 @@ class ParsePointerAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParsePointerCombineTests.swift b/Tests/ParseSwiftTests/ParsePointerCombineTests.swift index f8b175e48..339b0b6db 100644 --- a/Tests/ParseSwiftTests/ParsePointerCombineTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerCombineTests.swift @@ -21,11 +21,7 @@ class ParsePointerCombineTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParsePointerTests.swift b/Tests/ParseSwiftTests/ParsePointerTests.swift index 37658d96a..e389e1987 100644 --- a/Tests/ParseSwiftTests/ParsePointerTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerTests.swift @@ -18,11 +18,7 @@ class ParsePointerTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int diff --git a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift index a61b113e1..1a116a0bf 100644 --- a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift @@ -21,11 +21,7 @@ class ParseQueryAsyncTests: XCTestCase { // swiftlint:disable:this type_body_len var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseQueryCombineTests.swift b/Tests/ParseSwiftTests/ParseQueryCombineTests.swift index d7ae2ade3..7176f8ea7 100644 --- a/Tests/ParseSwiftTests/ParseQueryCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryCombineTests.swift @@ -21,11 +21,7 @@ class ParseQueryCombineTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int? diff --git a/Tests/ParseSwiftTests/ParseQueryTests.swift b/Tests/ParseSwiftTests/ParseQueryTests.swift index 0dc6228fa..3b415c17f 100644 --- a/Tests/ParseSwiftTests/ParseQueryTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryTests.swift @@ -40,11 +40,7 @@ class ParseQueryTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main var points: Int? } diff --git a/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift b/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift index 89ca7bbcf..b15bce6c4 100644 --- a/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryViewModelTests.swift @@ -18,11 +18,7 @@ class ParseQueryViewModelTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int = 0 diff --git a/Tests/ParseSwiftTests/ParseRelationTests.swift b/Tests/ParseSwiftTests/ParseRelationTests.swift index 6dc804f80..5dee388fd 100644 --- a/Tests/ParseSwiftTests/ParseRelationTests.swift +++ b/Tests/ParseSwiftTests/ParseRelationTests.swift @@ -17,11 +17,7 @@ class ParseRelationTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int @@ -43,11 +39,7 @@ class ParseRelationTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParseRoleTests.swift b/Tests/ParseSwiftTests/ParseRoleTests.swift index a27012370..e14961021 100644 --- a/Tests/ParseSwiftTests/ParseRoleTests.swift +++ b/Tests/ParseSwiftTests/ParseRoleTests.swift @@ -17,11 +17,7 @@ class ParseRoleTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var points: Int @@ -45,11 +41,7 @@ class ParseRoleTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -69,11 +61,7 @@ class ParseRoleTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // provided by Role var name: String? @@ -85,11 +73,7 @@ class ParseRoleTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main //: Your own properties var level: Int diff --git a/Tests/ParseSwiftTests/ParseSessionTests.swift b/Tests/ParseSwiftTests/ParseSessionTests.swift index 09dd634e3..118b00c58 100644 --- a/Tests/ParseSwiftTests/ParseSessionTests.swift +++ b/Tests/ParseSwiftTests/ParseSessionTests.swift @@ -20,11 +20,7 @@ class ParseSessionTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift index 4e6a298b4..80dc2d1d7 100644 --- a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift @@ -22,11 +22,7 @@ class ParseTwitterAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseTwitterAsyncTests: XCTestCase { // swiftlint:disable:this type_body_l var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift b/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift index 106754fb0..8d66df2d6 100644 --- a/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterCombineTests.swift @@ -22,11 +22,7 @@ class ParseTwitterCombineTests: XCTestCase { // swiftlint:disable:this type_body var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -43,11 +39,7 @@ class ParseTwitterCombineTests: XCTestCase { // swiftlint:disable:this type_body var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseTwitterTests.swift b/Tests/ParseSwiftTests/ParseTwitterTests.swift index 898c40287..b2e377e03 100644 --- a/Tests/ParseSwiftTests/ParseTwitterTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterTests.swift @@ -18,11 +18,7 @@ class ParseTwitterTests: XCTestCase { var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -39,11 +35,7 @@ class ParseTwitterTests: XCTestCase { var sessionToken: String? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index c672c1d66..7b688b8e2 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -23,11 +23,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -57,7 +53,6 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? - var score: Double? var originalData: Data? // These are required by ParseUser @@ -75,11 +70,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserCombineTests.swift b/Tests/ParseSwiftTests/ParseUserCombineTests.swift index ece8dd22b..1a04b4d37 100644 --- a/Tests/ParseSwiftTests/ParseUserCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseUserCombineTests.swift @@ -22,11 +22,7 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -46,11 +42,7 @@ class ParseUserCombineTests: XCTestCase { // swiftlint:disable:this type_body_le var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index 41ad36bd2..c8a38f28f 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -19,11 +19,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length var createdAt: Date? var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? @@ -53,11 +49,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length var sessionToken: String var updatedAt: Date? var ACL: ParseACL? -<<<<<<< HEAD - var score: Double? var originalData: Data? -======= ->>>>>>> main // These are required by ParseUser var username: String? From 388968258b384c788c49587ac076685228b52bd8 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 17 Jan 2022 16:06:10 -0500 Subject: [PATCH 17/26] mutable -> mergeable --- CHANGELOG.md | 2 +- .../Contents.swift | 4 ++-- .../Contents.swift | 4 ++-- .../Contents.swift | 6 +++--- .../Contents.swift | 2 +- .../8 - Pointers.xcplaygroundpage/Contents.swift | 2 +- Sources/ParseSwift/Objects/ParseObject.swift | 16 ++++++++-------- .../ParseInstallationAsyncTests.swift | 8 ++++---- .../ParseSwiftTests/ParseInstallationTests.swift | 8 ++++---- .../ParseSwiftTests/ParseObjectAsyncTests.swift | 12 ++++++------ Tests/ParseSwiftTests/ParseObjectTests.swift | 10 +++++----- Tests/ParseSwiftTests/ParseUserAsyncTests.swift | 8 ++++---- Tests/ParseSwiftTests/ParseUserTests.swift | 8 ++++---- 13 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 688d9d6da..eaa66d26d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ __New features__ - (Breaking Change) Add the ability to merge updated ParseObject's with original objects when using the - .mutable property. To do this, developers need to add an implementation of merge() to + .mergeable property. To do this, developers need to add an implementation of merge() to respective ParseObject's. The compiler will recommend the new originalData property be added to every ParseObject. If you used ParseObjectMutable in the past, you should remove it as it is now part of ParseObject. In addition, all ParseObject properties should be optional and every object diff --git a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift index 7e89364c8..f4c98cb13 100644 --- a/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift @@ -125,7 +125,7 @@ score.save { result in allows you to only send the updated keys to the parse server as opposed to the whole object. */ - var changedScore = savedScore.mutable + var changedScore = savedScore.mergeable changedScore.points = 200 changedScore.save { result in switch result { @@ -215,7 +215,7 @@ assert(savedScore?.points == 10) allows you to only send the updated keys to the parse server as opposed to the whole object. */ -guard var changedScore = savedScore?.mutable else { +guard var changedScore = savedScore?.mergeable else { fatalError("Should have produced mutable changedScore") } changedScore.points = 200 diff --git a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift index 54814fb16..fd697cb92 100644 --- a/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift @@ -78,11 +78,11 @@ score.save { result in print("Saved score: \(savedScore)") /*: To modify, need to make it a var as the value type - was initialized as immutable. Using `mutable` + was initialized as immutable. Using `.mergeable` allows you to only send the updated keys to the parse server as opposed to the whole object. */ - var changedScore = savedScore.mutable + var changedScore = savedScore.mergeable changedScore.points = 200 changedScore.save { result in switch result { diff --git a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift index d949278f9..9ce4c2bf5 100644 --- a/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift @@ -137,10 +137,10 @@ User.login(username: "hello", password: "world") { result in Asynchrounously - Performs work on background queue and returns to specified callbackQueue. If no callbackQueue is specified it returns to main queue. - Using `mutable` allows you to only send the updated keys to the + Using `.mergeable` allows you to only send the updated keys to the parse server as opposed to the whole object. */ -var currentUser = User.current?.mutable +var currentUser = User.current?.mergeable currentUser?.customKey = "myCustom" currentUser?.gameScore = GameScore(points: 12) currentUser?.targetScore = GameScore(points: 100) @@ -244,7 +244,7 @@ User.anonymous.login { result in } //: Convert the anonymous user to a real new user. -var currentUser2 = User.current?.mutable +var currentUser2 = User.current?.mergeable currentUser2?.username = "bye" currentUser2?.password = "world" currentUser2?.signup { result in diff --git a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift index 721c4a522..31fa843ee 100644 --- a/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift @@ -70,7 +70,7 @@ currentInstallation?.save { results in designated callbackQueue. If no callbackQueue is specified it returns to main queue. */ -var installationToUpdate = Installation.current?.mutable +var installationToUpdate = Installation.current?.mergeable installationToUpdate?.customKey = "myCustomInstallationKey2" installationToUpdate?.save { results in diff --git a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift index dac15e7d4..5ef18160c 100644 --- a/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/8 - Pointers.xcplaygroundpage/Contents.swift @@ -218,7 +218,7 @@ do { case .success(let author): print("Found author and included \"book\": \(author)") //: Setup related books. - var modifiedNewBook = newBook.mutable + var modifiedNewBook = newBook.mergeable modifiedNewBook.relatedBook = try? author.otherBooks?.first?.toPointer() modifiedNewBook.save { result in diff --git a/Sources/ParseSwift/Objects/ParseObject.swift b/Sources/ParseSwift/Objects/ParseObject.swift index 286d6538e..03731e668 100644 --- a/Sources/ParseSwift/Objects/ParseObject.swift +++ b/Sources/ParseSwift/Objects/ParseObject.swift @@ -16,8 +16,8 @@ import Foundation If you are using value types the the compiler will assist you with conforming to `ParseObject` protocol. If you are thinking of using reference types, see the warning. - After a `ParseObject`is saved/created to a Parse Server. Updates to the `ParseObject` should occur on - a copy of the `mutable` property. This allows a subset of the fields to be updated (PATCH) of an object + After a `ParseObject`is saved/created to a Parse Server. It is recommended to conduct the rest of your updates on a + `mergeable` copy of your `ParseObject`. This allows a subset of the fields to be updated (PATCH) of an object as oppose to replacing all of the fields of an object (PUT). This reduces the amount of data sent between client and server when using `save`, `saveAll`, `update`, `updateAll`, `replace`, `replaceAll`, to update objects. @@ -27,7 +27,7 @@ import Foundation create methods to check the respective properties on the client-side before saving objects. See [here](https://github.com/parse-community/Parse-Swift/issues/157#issuecomment-858671025) for more information. - - important: To take advantage of `mutable`, the developer should implement the `merge` method in every + - important: To take advantage of `mergeable`, the developer should implement the `merge` method in every `ParseObject`. - warning: If you plan to use "reference types" (classes), you are using at your risk as this SDK is not designed for reference types and may have unexpected behavior when it comes to threading. You will also need to implement @@ -49,7 +49,7 @@ public protocol ParseObject: Objectable, CustomStringConvertible { /** - A JSON encoded version of this `ParseObject` before `mutable` was called and + A JSON encoded version of this `ParseObject` before `mergeable` was called and properties were changed. - warning: This property is not intended to be set or modified by the developer. */ @@ -58,12 +58,12 @@ public protocol ParseObject: Objectable, /** An empty copy of the respective object that allows you to update a a subset of the fields (PATCH) of an object as oppose to replacing an object (PUT). - - note: It is recommended to use this to create a mutable copy of your `ParseObject`. - - warning: `mutable` should only be used on `ParseObject`'s that have already + - note: It is recommended to use this to create a mergeable copy of your `ParseObject`. + - warning: `mergeable` should only be used on `ParseObject`'s that have already been saved at least once to a Parse Server and have a valid `objectId`. In addition, the developer should have implemented added all of their properties to `merge`. */ - var mutable: Self { get } + var mergeable: Self { get } /** Determines if a `KeyPath` of the current `ParseObject` should be restored @@ -144,7 +144,7 @@ public extension ParseObject { return objectId } - var mutable: Self { + var mergeable: Self { var object = Self() object.objectId = objectId object.createdAt = createdAt diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 140188126..346ed35bb 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -467,7 +467,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b XCTFail("Should unwrap") return } - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -484,7 +484,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdate = original.mutable + var originalUpdate = original.mergeable originalUpdate.customKey = "hello" originalUpdate.deviceToken = "1234" let updated = originalUpdate @@ -547,7 +547,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b XCTFail("Should unwrap") return } - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -565,7 +565,7 @@ class ParseInstallationAsyncTests: XCTestCase { // swiftlint:disable:this type_b return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdate = original.mutable + var originalUpdate = original.mergeable originalUpdate.deviceToken = "1234" let updated = originalUpdate diff --git a/Tests/ParseSwiftTests/ParseInstallationTests.swift b/Tests/ParseSwiftTests/ParseInstallationTests.swift index 4b4420ab0..8c70fb639 100644 --- a/Tests/ParseSwiftTests/ParseInstallationTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationTests.swift @@ -278,7 +278,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l acl.publicRead = true original.ACL = acl - var updated = original.mutable + var updated = original.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.badge = 1 updated.deviceToken = "12345" @@ -316,7 +316,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l acl.publicRead = true original.ACL = acl - var updated = original.mutable + var updated = original.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.customKey = "newKey" let merged = try updated.merge(original) @@ -486,7 +486,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l XCTFail("Should unwrap") return } - var response = original.mutable + var response = original.mergeable response.createdAt = nil response.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -502,7 +502,7 @@ class ParseInstallationTests: XCTestCase { // swiftlint:disable:this type_body_l MockURLProtocol.mockRequests { _ in return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } - var updated = original.mutable + var updated = original.mergeable updated.customKey = "hello" updated.deviceToken = "1234" diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index 830133646..ea3bfc59a 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -175,7 +175,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le original.objectId = "yarr" original.player = "beast" - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -192,7 +192,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdated = original.mutable + var originalUpdated = original.mergeable originalUpdated.points = 50 let updated = originalUpdated @@ -392,7 +392,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le original.objectId = "yarr" original.player = "beast" - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -409,7 +409,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdated = original.mutable + var originalUpdated = original.mergeable originalUpdated.points = 50 let updated = originalUpdated @@ -431,7 +431,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le var original = GameScoreDefault() original.objectId = "yarr" - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -448,7 +448,7 @@ class ParseObjectAsyncTests: XCTestCase { // swiftlint:disable:this type_body_le return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - let originalUpdated = original.mutable + let originalUpdated = original.mergeable let updated = originalUpdated do { diff --git a/Tests/ParseSwiftTests/ParseObjectTests.swift b/Tests/ParseSwiftTests/ParseObjectTests.swift index 25e4508b6..4799ba063 100644 --- a/Tests/ParseSwiftTests/ParseObjectTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectTests.swift @@ -368,7 +368,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length var score = GameScore(points: 19, name: "fire") score.objectId = "yolo" score.createdAt = Date() - let empty = score.mutable + let empty = score.mergeable XCTAssertTrue(score.hasSameObjectId(as: empty)) XCTAssertEqual(score.createdAt, empty.createdAt) } @@ -388,7 +388,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length score.level = level score.levels = [level] score.nextLevel = level2 - var updated = score.mutable + var updated = score.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.points = 30 updated.player = "moreFire" @@ -409,7 +409,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length score.objectId = "yolo" score.createdAt = Date() score.updatedAt = Date() - var updated = score.mutable + var updated = score.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.name = "moreFire" let merged = try updated.merge(score) @@ -756,7 +756,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length score.createdAt = Date() score.updatedAt = score.createdAt - let command = try score.mutable.saveCommand() + let command = try score.mergeable.saveCommand() XCTAssertNotNil(command) XCTAssertEqual(command.path.urlComponent, "/classes/\(className)/\(objectId)") XCTAssertEqual(command.method, API.Method.PUT) @@ -775,7 +775,7 @@ class ParseObjectTests: XCTestCase { // swiftlint:disable:this type_body_length let decoded = try XCTUnwrap(String(data: encoded, encoding: .utf8)) XCTAssertEqual(decoded, expected) - var empty = score.mutable + var empty = score.mergeable empty.player = "Jennifer" let command2 = try empty.saveCommand() guard let body2 = command2.body else { diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 7b688b8e2..497a969b3 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -780,7 +780,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng XCTFail("Should unwrap") return } - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -797,7 +797,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdated = original.mutable + var originalUpdated = original.mergeable originalUpdated.customKey = "beast" originalUpdated.username = "mode" let updated = originalUpdated @@ -848,7 +848,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng XCTFail("Should unwrap") return } - var originalResponse = original.mutable + var originalResponse = original.mergeable originalResponse.createdAt = nil originalResponse.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -865,7 +865,7 @@ class ParseUserAsyncTests: XCTestCase { // swiftlint:disable:this type_body_leng return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } let response = originalResponse - var originalUpdated = original.mutable + var originalUpdated = original.mergeable originalUpdated.username = "mode" let updated = originalUpdated diff --git a/Tests/ParseSwiftTests/ParseUserTests.swift b/Tests/ParseSwiftTests/ParseUserTests.swift index c8a38f28f..ff83e3384 100644 --- a/Tests/ParseSwiftTests/ParseUserTests.swift +++ b/Tests/ParseSwiftTests/ParseUserTests.swift @@ -128,7 +128,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length acl.publicRead = true original.ACL = acl - var updated = original.mutable + var updated = original.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.email = "swift@parse.com" updated.username = "12345" @@ -161,7 +161,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length acl.publicRead = true original.ACL = acl - var updated = original.mutable + var updated = original.mergeable updated.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) updated.customKey = "newKey" let merged = try updated.merge(original) @@ -838,7 +838,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length XCTFail("Should unwrap") return } - var response = original.mutable + var response = original.mergeable response.createdAt = nil response.updatedAt = Calendar.current.date(byAdding: .init(day: 1), to: Date()) @@ -854,7 +854,7 @@ class ParseUserTests: XCTestCase { // swiftlint:disable:this type_body_length MockURLProtocol.mockRequests { _ in return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0) } - var updated = original.mutable + var updated = original.mergeable updated.customKey = "beast" updated.username = "mode" From 34866999c29ed8f784530f9fd90c06874a7c487d Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 17 Jan 2022 16:22:18 -0500 Subject: [PATCH 18/26] fix sortByText --- ParseSwift.xcodeproj/project.pbxproj | 2 +- .../Protocols/ParseQueryScorable.swift | 22 ---------- .../Protocols/ParseQueryScorable.swift | 42 +++++++++++++++++++ Sources/ParseSwift/Types/Query.swift | 17 -------- 4 files changed, 43 insertions(+), 40 deletions(-) delete mode 100644 Sources/ParseSwift/LiveQuery/Protocols/ParseQueryScorable.swift create mode 100644 Sources/ParseSwift/Protocols/ParseQueryScorable.swift diff --git a/ParseSwift.xcodeproj/project.pbxproj b/ParseSwift.xcodeproj/project.pbxproj index 6011c6838..3b1b96e98 100644 --- a/ParseSwift.xcodeproj/project.pbxproj +++ b/ParseSwift.xcodeproj/project.pbxproj @@ -1382,7 +1382,6 @@ 700396E925A3892D0052CB31 /* LiveQuerySocketDelegate.swift */, 700396F725A394AE0052CB31 /* ParseLiveQueryDelegate.swift */, 700395D025A147BE0052CB31 /* QuerySubscribable.swift */, - 70A98D812794AB3C009B58F2 /* ParseQueryScorable.swift */, ); path = Protocols; sourceTree = ""; @@ -1406,6 +1405,7 @@ F97B45C524D9C6F200F4A88B /* Fetchable.swift */, 705A9A2E25991C1400B3547F /* Fileable.swift */, 70BC988F252A5B5C00FF3074 /* Objectable.swift */, + 70A98D812794AB3C009B58F2 /* ParseQueryScorable.swift */, 70647E9B259E3A9A004C1004 /* ParseType.swift */, F97B45C824D9C6F200F4A88B /* Queryable.swift */, 91BB8FCE2690BA70005A6BA5 /* QueryObservable.swift */, diff --git a/Sources/ParseSwift/LiveQuery/Protocols/ParseQueryScorable.swift b/Sources/ParseSwift/LiveQuery/Protocols/ParseQueryScorable.swift deleted file mode 100644 index e85163e4b..000000000 --- a/Sources/ParseSwift/LiveQuery/Protocols/ParseQueryScorable.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// ParseQueryScorable.swift -// ParseSwift -// -// Created by Corey Baker on 1/16/22. -// Copyright © 2022 Parse Community. All rights reserved. -// - -import Foundation - -/** - Conform to this protocol to add the required properties to your `ParseObject` - for using `QueryConstraint.matchesText()` and `Query.sortByTextScore()`. - - note: In order to sort you must use `Query.sortByTextScore()`. - To retrieve the weight/rank, access the "score" property of your `ParseObject`. - */ -public protocol ParseQueryScorable { - /** - The weight/rank of a `QueryConstraint.matchesText()`. - */ - var score: Double? { get } -} diff --git a/Sources/ParseSwift/Protocols/ParseQueryScorable.swift b/Sources/ParseSwift/Protocols/ParseQueryScorable.swift new file mode 100644 index 000000000..8762374fb --- /dev/null +++ b/Sources/ParseSwift/Protocols/ParseQueryScorable.swift @@ -0,0 +1,42 @@ +// +// ParseQueryScorable.swift +// ParseSwift +// +// Created by Corey Baker on 1/16/22. +// Copyright © 2022 Parse Community. All rights reserved. +// + +import Foundation + +/** + Conform to this protocol to add the required properties to your `ParseObject` + for using `QueryConstraint.matchesText()` and `Query.sortByTextScore()`. + - note: In order to sort you must use `Query.sortByTextScore()`. + To retrieve the weight/rank, access the "score" property of your `ParseObject`. + */ +public protocol ParseQueryScorable { + /** + The weight/rank of a `QueryConstraint.matchesText()`. + */ + var score: Double? { get } +} + +// MARK: ParseQueryScorable +extension Query { + /** + Method to sort the full text search by text score. + - parameter value: String or Object of index that should be used when executing query. + - note: Your `ParseObject` should conform to `ParseQueryScorable` to retrieve + the weight/rank via the "score" property of your `ParseObject`. + */ + public func sortByTextScore() -> Query where T: ParseObject & ParseQueryScorable { + var mutableQuery = self + let ascendingScore = Order.ascending(QueryConstraint.Comparator.score.rawValue) + if mutableQuery.order != nil { + mutableQuery.order!.append(ascendingScore) + } else { + mutableQuery.order = [ascendingScore] + } + return mutableQuery.select(QueryConstraint.Comparator.score.rawValue) + } +} diff --git a/Sources/ParseSwift/Types/Query.swift b/Sources/ParseSwift/Types/Query.swift index a17510f4d..815351b19 100644 --- a/Sources/ParseSwift/Types/Query.swift +++ b/Sources/ParseSwift/Types/Query.swift @@ -172,23 +172,6 @@ public struct Query: Encodable, Equatable where T: ParseObject { return mutableQuery } - /** - Method to sort the full text search by text score. - - parameter value: String or Object of index that should be used when executing query. - - note: Your `ParseObject` should conform to `ParseQueryScorable` to retrieve - the weight/rank via the "score" property of your `ParseObject`. - */ - public func sortByTextScore() -> Query { - var mutableQuery = self - let ascendingScore = Order.ascending(QueryConstraint.Comparator.score.rawValue) - if mutableQuery.order != nil { - mutableQuery.order!.append(ascendingScore) - } else { - mutableQuery.order = [ascendingScore] - } - return mutableQuery.select(QueryConstraint.Comparator.score.rawValue) - } - /** Changes the read preference that the backend will use when performing the query to the database. - parameter readPreference: The read preference for the main query. From 3a15233c194474a98d89168733a21258b1608e5c Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 17 Jan 2022 16:47:15 -0500 Subject: [PATCH 19/26] add info about POP in README --- CONTRIBUTING.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7026d70f1..f7ed4d130 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,7 +119,7 @@ Currently, we are not making use of the commit _scope_, which would be written a ## Evolution -It's not intended as a port of the Parse Objective-c SDK and has many new philosophies. Please see [this thread](https://github.com/parse-community/Parse-Swift/issues/3) for a detailed discussion about the intended evolution of this SDK. +The ParseSwift SDK is not a port of the [Parse-SDK-iOS-OSX SDK](https://github.com/parse-community/Parse-SDK-iOS-OSX) and though some of it may feel familiar, it is not backwards compatible and is designed using [protocol oriented programming (POP) and value types](https://www.pluralsight.com/guides/protocol-oriented-programming-in-swift) instead of OOP and reference types. You can learn more about POP by watching [this](https://developer.apple.com/videos/play/wwdc2015/408/) or [that](https://developer.apple.com/videos/play/wwdc2016/419/) videos from previous WWDC's. Please see [this thread](https://github.com/parse-community/Parse-Swift/issues/3) for a detailed discussion about the intended evolution of this SDK. ## Code of Conduct diff --git a/README.md b/README.md index 84c9570b2..57f5a0d98 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ A pure Swift library that gives you access to the powerful Parse Server backend from your Swift applications. -For more information about the Parse Platform and its features, see the public [documentation][docs]. The ParseSwift SDK is not a port of the [Parse-SDK-iOS-OSX SDK](https://github.com/parse-community/Parse-SDK-iOS-OSX) and though some of it may feel familiar, it is not backwards compatible and is designed with a new philosophy. For more details visit the [api documentation](http://parseplatform.org/Parse-Swift/api/). +For more information about the Parse Platform and its features, see the public [documentation][docs]. The ParseSwift SDK is not a port of the [Parse-SDK-iOS-OSX SDK](https://github.com/parse-community/Parse-SDK-iOS-OSX) and though some of it may feel familiar, it is not backwards compatible and is designed using [protocol oriented programming (POP) and value types](https://www.pluralsight.com/guides/protocol-oriented-programming-in-swift) instead of OOP and reference types. You can learn more about POP by watching [this](https://developer.apple.com/videos/play/wwdc2015/408/) or [that](https://developer.apple.com/videos/play/wwdc2016/419/) videos from previous WWDC's. For more details about ParseSwift, visit the [api documentation](http://parseplatform.org/Parse-Swift/api/). To learn how to use or experiment with ParseSwift, you can run and edit the [ParseSwift.playground](https://github.com/parse-community/Parse-Swift/tree/main/ParseSwift.playground/Pages). You can use the parse-server in [this repo](https://github.com/netreconlab/parse-hipaa/tree/parse-swift) which has docker compose files (`docker-compose up` gives you a working server) configured to connect with the playground files, has [Parse Dashboard](https://github.com/parse-community/parse-dashboard), and can be used with MongoDB or PostgreSQL. You can also configure the Swift Playgrounds to work with your own Parse Server by editing the configuation in [Common.swift](https://github.com/parse-community/Parse-Swift/blob/e9ba846c399257100b285d25d2bd055628b13b4b/ParseSwift.playground/Sources/Common.swift#L4-L19). To learn more, check out [CONTRIBUTING.md](https://github.com/parse-community/Parse-Swift/blob/main/CONTRIBUTING.md#swift-playgrounds). @@ -57,7 +57,7 @@ import PackageDescription let package = Package( name: "YOUR_PROJECT_NAME", dependencies: [ - .package(url: "https://github.com/parse-community/Parse-Swift", from: "3.1.2"), + .package(url: "https://github.com/parse-community/Parse-Swift", from: "4.0.0"), ] ) ``` From e12b88f13fe02c0a46bc97fc235d8220f8c3841a Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Mon, 17 Jan 2022 18:07:48 -0500 Subject: [PATCH 20/26] Move the where for Swift 5.2 --- Sources/ParseSwift/Protocols/ParseQueryScorable.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/ParseSwift/Protocols/ParseQueryScorable.swift b/Sources/ParseSwift/Protocols/ParseQueryScorable.swift index 8762374fb..f77fb71a4 100644 --- a/Sources/ParseSwift/Protocols/ParseQueryScorable.swift +++ b/Sources/ParseSwift/Protocols/ParseQueryScorable.swift @@ -22,14 +22,14 @@ public protocol ParseQueryScorable { } // MARK: ParseQueryScorable -extension Query { +extension Query where T: ParseObject & ParseQueryScorable { /** Method to sort the full text search by text score. - parameter value: String or Object of index that should be used when executing query. - note: Your `ParseObject` should conform to `ParseQueryScorable` to retrieve the weight/rank via the "score" property of your `ParseObject`. */ - public func sortByTextScore() -> Query where T: ParseObject & ParseQueryScorable { + public func sortByTextScore() -> Query { var mutableQuery = self let ascendingScore = Order.ascending(QueryConstraint.Comparator.score.rawValue) if mutableQuery.order != nil { From 19d1fd9c0c0f99ee3cde7b2c5c20fd90b999a8d0 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 17 Jan 2022 20:03:49 -0500 Subject: [PATCH 21/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57f5a0d98..6ec49f9b8 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ A pure Swift library that gives you access to the powerful Parse Server backend from your Swift applications. -For more information about the Parse Platform and its features, see the public [documentation][docs]. The ParseSwift SDK is not a port of the [Parse-SDK-iOS-OSX SDK](https://github.com/parse-community/Parse-SDK-iOS-OSX) and though some of it may feel familiar, it is not backwards compatible and is designed using [protocol oriented programming (POP) and value types](https://www.pluralsight.com/guides/protocol-oriented-programming-in-swift) instead of OOP and reference types. You can learn more about POP by watching [this](https://developer.apple.com/videos/play/wwdc2015/408/) or [that](https://developer.apple.com/videos/play/wwdc2016/419/) videos from previous WWDC's. For more details about ParseSwift, visit the [api documentation](http://parseplatform.org/Parse-Swift/api/). +For more information about the Parse Platform and its features, see the public [documentation][docs]. The ParseSwift SDK is not a port of the [Parse-SDK-iOS-OSX SDK](https://github.com/parse-community/Parse-SDK-iOS-OSX) and though some of it may feel familiar, it is not backwards compatible and is designed using [protocol oriented programming (POP) and value types](https://www.pluralsight.com/guides/protocol-oriented-programming-in-swift) instead of OOP and reference types. You can learn more about POP by watching [Protocol-Oriented Programming in Swift](https://developer.apple.com/videos/play/wwdc2015/408/) or [Protocol and Value Oriented Programming in UIKit Apps](https://developer.apple.com/videos/play/wwdc2016/419/) videos from previous WWDC's. For more details about ParseSwift, visit the [api documentation](http://parseplatform.org/Parse-Swift/api/). To learn how to use or experiment with ParseSwift, you can run and edit the [ParseSwift.playground](https://github.com/parse-community/Parse-Swift/tree/main/ParseSwift.playground/Pages). You can use the parse-server in [this repo](https://github.com/netreconlab/parse-hipaa/tree/parse-swift) which has docker compose files (`docker-compose up` gives you a working server) configured to connect with the playground files, has [Parse Dashboard](https://github.com/parse-community/parse-dashboard), and can be used with MongoDB or PostgreSQL. You can also configure the Swift Playgrounds to work with your own Parse Server by editing the configuation in [Common.swift](https://github.com/parse-community/Parse-Swift/blob/e9ba846c399257100b285d25d2bd055628b13b4b/ParseSwift.playground/Sources/Common.swift#L4-L19). To learn more, check out [CONTRIBUTING.md](https://github.com/parse-community/Parse-Swift/blob/main/CONTRIBUTING.md#swift-playgrounds). From d0ff845b68837c59eabe81b25ac429371d7759ce Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 17 Jan 2022 22:01:09 -0500 Subject: [PATCH 22/26] try windows action --- .github/workflows/ci.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 966ecf35f..74575ecfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -198,11 +198,20 @@ jobs: windows: runs-on: windows-2019 steps: - - uses: actions/checkout@v2 - - uses: MaxDesiatov/swift-windows-action@v1 + - uses: compnerd/gha-setup-swift@main with: - swift-version: "5.5.1" - shell-action: swift test --enable-test-discovery --enable-code-coverage -v + branch: swift-5.5.2-release + tag: 5.5.2-RELEASE + + - uses: actions/checkout@v2 + - run: swift build + - run: swift test --enable-test-discovery --enable-code-coverage -v + #steps: + # - uses: actions/checkout@v2 + # - uses: MaxDesiatov/swift-windows-action@v1 + # with: + # swift-version: "5.5.1" + # shell-action: swift test --enable-test-discovery --enable-code-coverage -v - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: From 78ea506b5720f3c86e0fedac6e1b991020bf0b59 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 17 Jan 2022 22:08:28 -0500 Subject: [PATCH 23/26] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74575ecfa..542691ee3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,7 +196,7 @@ jobs: fail_ci_if_error: true windows: - runs-on: windows-2019 + runs-on: windows-latest steps: - uses: compnerd/gha-setup-swift@main with: From 5dcfdbb577350611017bb9df77cf93fa6e395ea3 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 17 Jan 2022 22:14:56 -0500 Subject: [PATCH 24/26] Update ci.yml --- .github/workflows/ci.yml | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 542691ee3..966ecf35f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,22 +196,13 @@ jobs: fail_ci_if_error: true windows: - runs-on: windows-latest + runs-on: windows-2019 steps: - - uses: compnerd/gha-setup-swift@main - with: - branch: swift-5.5.2-release - tag: 5.5.2-RELEASE - - uses: actions/checkout@v2 - - run: swift build - - run: swift test --enable-test-discovery --enable-code-coverage -v - #steps: - # - uses: actions/checkout@v2 - # - uses: MaxDesiatov/swift-windows-action@v1 - # with: - # swift-version: "5.5.1" - # shell-action: swift test --enable-test-discovery --enable-code-coverage -v + - uses: MaxDesiatov/swift-windows-action@v1 + with: + swift-version: "5.5.1" + shell-action: swift test --enable-test-discovery --enable-code-coverage -v - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 with: From b1baebbdf6801a0838adcbdfb7d3a447b4257246 Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Tue, 18 Jan 2022 09:21:28 -0500 Subject: [PATCH 25/26] don't build async on windows --- .github/workflows/ci.yml | 2 +- .../3rd Party/ParseApple/ParseApple+async.swift | 2 +- .../3rd Party/ParseFacebook/ParseFacebook+async.swift | 2 +- .../3rd Party/ParseGithub/ParseGitHub+async.swift | 2 +- .../3rd Party/ParseGoogle/ParseGoogle+async.swift | 2 +- .../Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift | 2 +- .../3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift | 2 +- .../3rd Party/ParseTwitter/ParseTwitter+async.swift | 2 +- .../Authentication/Internal/ParseAnonymous+async.swift | 2 +- .../Authentication/Protocols/ParseAuthentication+async.swift | 2 +- .../Authentication/Protocols/ParseAuthentication.swift | 2 +- Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift | 2 +- Sources/ParseSwift/Objects/ParseInstallation+async.swift | 2 +- Sources/ParseSwift/Objects/ParseObject+async.swift | 2 +- Sources/ParseSwift/Objects/ParseUser+async.swift | 2 +- Sources/ParseSwift/Types/ParseAnalytics+async.swift | 2 +- Sources/ParseSwift/Types/ParseCloud+async.swift | 2 +- Sources/ParseSwift/Types/ParseConfig+async.swift | 2 +- Sources/ParseSwift/Types/ParseFile+async.swift | 2 +- Sources/ParseSwift/Types/ParseHealth+async.swift | 2 +- Sources/ParseSwift/Types/ParseOperation+async.swift | 2 +- Sources/ParseSwift/Types/Pointer+async.swift | 2 +- Sources/ParseSwift/Types/Query+async.swift | 2 +- Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAppleAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift | 4 ++-- Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift | 2 +- Tests/ParseSwiftTests/ParseAuthenticationTests.swift | 2 +- Tests/ParseSwiftTests/ParseCloudAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseConfigAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseFileAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseGitHubTests.swift | 2 +- Tests/ParseSwiftTests/ParseGoogleTests.swift | 2 +- Tests/ParseSwiftTests/ParseHealthAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseLinkedInTests.swift | 2 +- Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseObjectAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseOperationAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParsePointerAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseQueryAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseUserAsyncTests.swift | 2 +- 46 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 966ecf35f..e914eaefb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -201,7 +201,7 @@ jobs: - uses: actions/checkout@v2 - uses: MaxDesiatov/swift-windows-action@v1 with: - swift-version: "5.5.1" + swift-version: "5.5.2" shell-action: swift test --enable-test-discovery --enable-code-coverage -v - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift index 32ef296fa..46e80fa45 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseApple { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift index 32c6c62d6..521d052cc 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseFacebook { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift index 48940db38..10af7a0d9 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseGitHub { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift index 8cbe5b812..c3f9b1b1a 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseGoogle { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift index 307d83a98..52bebfabf 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseLDAP { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift index 9a5f589c0..bae5e970f 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseLinkedIn { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift index 78e4afe73..3e03a6577 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseTwitter { diff --git a/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift b/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift index 8bd1ec3db..31b181b02 100644 --- a/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift +++ b/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseAnonymous { diff --git a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift index 6ae2870ae..bd0e2312a 100644 --- a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift +++ b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseAuthentication { diff --git a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift index 7749dfbe9..8bce657d5 100644 --- a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift +++ b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift @@ -138,7 +138,7 @@ public protocol ParseAuthentication: Codable { func unlinkPublisher(options: API.Options) -> Future #endif - #if compiler(>=5.5.2) && canImport(_Concurrency) + #if compiler(>=5.6.2) && canImport(_Concurrency) // MARK: Async/Await /** diff --git a/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift b/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift index 3d10cc93b..68eaa449e 100644 --- a/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift +++ b/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) +#if compiler(>=5.6.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) import Foundation extension ParseLiveQuery { diff --git a/Sources/ParseSwift/Objects/ParseInstallation+async.swift b/Sources/ParseSwift/Objects/ParseInstallation+async.swift index b408548f1..953d704f2 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation+async.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseInstallation { diff --git a/Sources/ParseSwift/Objects/ParseObject+async.swift b/Sources/ParseSwift/Objects/ParseObject+async.swift index 4c423de86..d2ea77823 100644 --- a/Sources/ParseSwift/Objects/ParseObject+async.swift +++ b/Sources/ParseSwift/Objects/ParseObject+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseObject { diff --git a/Sources/ParseSwift/Objects/ParseUser+async.swift b/Sources/ParseSwift/Objects/ParseUser+async.swift index 897568ffa..c3c700c35 100644 --- a/Sources/ParseSwift/Objects/ParseUser+async.swift +++ b/Sources/ParseSwift/Objects/ParseUser+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseUser { diff --git a/Sources/ParseSwift/Types/ParseAnalytics+async.swift b/Sources/ParseSwift/Types/ParseAnalytics+async.swift index 20417f306..9340ec456 100644 --- a/Sources/ParseSwift/Types/ParseAnalytics+async.swift +++ b/Sources/ParseSwift/Types/ParseAnalytics+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if os(iOS) diff --git a/Sources/ParseSwift/Types/ParseCloud+async.swift b/Sources/ParseSwift/Types/ParseCloud+async.swift index 79cf2ceaf..7c1c00449 100644 --- a/Sources/ParseSwift/Types/ParseCloud+async.swift +++ b/Sources/ParseSwift/Types/ParseCloud+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseCloud { diff --git a/Sources/ParseSwift/Types/ParseConfig+async.swift b/Sources/ParseSwift/Types/ParseConfig+async.swift index 4b35fbae2..5d34dfe96 100644 --- a/Sources/ParseSwift/Types/ParseConfig+async.swift +++ b/Sources/ParseSwift/Types/ParseConfig+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseConfig { diff --git a/Sources/ParseSwift/Types/ParseFile+async.swift b/Sources/ParseSwift/Types/ParseFile+async.swift index 9126d9c7c..cd50396dd 100644 --- a/Sources/ParseSwift/Types/ParseFile+async.swift +++ b/Sources/ParseSwift/Types/ParseFile+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Sources/ParseSwift/Types/ParseHealth+async.swift b/Sources/ParseSwift/Types/ParseHealth+async.swift index 4d97e6297..b1e7619ea 100644 --- a/Sources/ParseSwift/Types/ParseHealth+async.swift +++ b/Sources/ParseSwift/Types/ParseHealth+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseHealth { diff --git a/Sources/ParseSwift/Types/ParseOperation+async.swift b/Sources/ParseSwift/Types/ParseOperation+async.swift index baf2dd719..0f386a76a 100644 --- a/Sources/ParseSwift/Types/ParseOperation+async.swift +++ b/Sources/ParseSwift/Types/ParseOperation+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension ParseOperation { diff --git a/Sources/ParseSwift/Types/Pointer+async.swift b/Sources/ParseSwift/Types/Pointer+async.swift index 3bb86e5e6..1009885a0 100644 --- a/Sources/ParseSwift/Types/Pointer+async.swift +++ b/Sources/ParseSwift/Types/Pointer+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation // MARK: Async/Await diff --git a/Sources/ParseSwift/Types/Query+async.swift b/Sources/ParseSwift/Types/Query+async.swift index 542ebf5ec..0a777691b 100644 --- a/Sources/ParseSwift/Types/Query+async.swift +++ b/Sources/ParseSwift/Types/Query+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation public extension Query { diff --git a/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift index 9ded6c7eb..f440a7548 100644 --- a/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift index 5c60fd928..b70bf9a31 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift index b133a7599..fc81e4c9f 100644 --- a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift index 2f73ef4dd..9a08ca465 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking @@ -105,7 +105,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type } #endif - #if compiler(>=5.5.2) && canImport(_Concurrency) + #if compiler(>=5.6.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift index ebf465945..b81a5218d 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift @@ -105,7 +105,7 @@ class ParseAuthenticationCombineTests: XCTestCase { } #endif - #if compiler(>=5.5.2) && canImport(_Concurrency) + #if compiler(>=5.6.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift index 083973325..96eafd31b 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift @@ -105,7 +105,7 @@ class ParseAuthenticationTests: XCTestCase { } #endif - #if compiler(>=5.5.2) && canImport(_Concurrency) + #if compiler(>=5.6.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift b/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift index c3fb627d2..c2b1d9f37 100644 --- a/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift index f0bd52a09..4d1511ae9 100644 --- a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift index cbfced4f0..5776a98d3 100644 --- a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseFileAsyncTests.swift b/Tests/ParseSwiftTests/ParseFileAsyncTests.swift index 4ec6a9898..e6f161512 100644 --- a/Tests/ParseSwiftTests/ParseFileAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFileAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseGitHubTests.swift b/Tests/ParseSwiftTests/ParseGitHubTests.swift index 5afa3da85..d87564d28 100644 --- a/Tests/ParseSwiftTests/ParseGitHubTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubTests.swift @@ -150,7 +150,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseGoogleTests.swift b/Tests/ParseSwiftTests/ParseGoogleTests.swift index 60779a872..141d5418d 100644 --- a/Tests/ParseSwiftTests/ParseGoogleTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleTests.swift @@ -162,7 +162,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift b/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift index e1aaed307..3d0791175 100644 --- a/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 346ed35bb..5615ec1b7 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift index d2ce5910d..ce77a223f 100644 --- a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseLinkedInTests.swift b/Tests/ParseSwiftTests/ParseLinkedInTests.swift index bd5d4adf3..75365c124 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInTests.swift @@ -153,7 +153,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift index adfcb56f1..4741202f2 100644 --- a/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) +#if compiler(>=5.6.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index ea3bfc59a..5caf9b75a 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift index 6840eb432..cd3eb3cba 100644 --- a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift index 2d5765897..0a4b7d518 100644 --- a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift index 1a116a0bf..5f2677f31 100644 --- a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift index 80dc2d1d7..180d00074 100644 --- a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index 497a969b3..f8a095885 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.5.2) && canImport(_Concurrency) +#if compiler(>=5.6.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking From 7fa72f26c48c35482b12940211b009b9381dcf6b Mon Sep 17 00:00:00 2001 From: Corey Baker Date: Tue, 18 Jan 2022 09:36:35 -0500 Subject: [PATCH 26/26] revert async back to Swift 5.5.2 --- .github/workflows/ci.yml | 2 +- .../3rd Party/ParseApple/ParseApple+async.swift | 2 +- .../3rd Party/ParseFacebook/ParseFacebook+async.swift | 2 +- .../3rd Party/ParseGithub/ParseGitHub+async.swift | 2 +- .../3rd Party/ParseGoogle/ParseGoogle+async.swift | 2 +- .../Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift | 2 +- .../3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift | 2 +- .../3rd Party/ParseTwitter/ParseTwitter+async.swift | 2 +- .../Authentication/Internal/ParseAnonymous+async.swift | 2 +- .../Authentication/Protocols/ParseAuthentication+async.swift | 2 +- .../Authentication/Protocols/ParseAuthentication.swift | 2 +- Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift | 2 +- Sources/ParseSwift/Objects/ParseInstallation+async.swift | 2 +- Sources/ParseSwift/Objects/ParseObject+async.swift | 2 +- Sources/ParseSwift/Objects/ParseUser+async.swift | 2 +- Sources/ParseSwift/Types/ParseAnalytics+async.swift | 2 +- Sources/ParseSwift/Types/ParseCloud+async.swift | 2 +- Sources/ParseSwift/Types/ParseConfig+async.swift | 2 +- Sources/ParseSwift/Types/ParseFile+async.swift | 2 +- Sources/ParseSwift/Types/ParseHealth+async.swift | 2 +- Sources/ParseSwift/Types/ParseOperation+async.swift | 2 +- Sources/ParseSwift/Types/Pointer+async.swift | 2 +- Sources/ParseSwift/Types/Query+async.swift | 2 +- Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAppleAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift | 4 ++-- Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift | 2 +- Tests/ParseSwiftTests/ParseAuthenticationTests.swift | 2 +- Tests/ParseSwiftTests/ParseCloudAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseConfigAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseFileAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseGitHubTests.swift | 2 +- Tests/ParseSwiftTests/ParseGoogleTests.swift | 2 +- Tests/ParseSwiftTests/ParseHealthAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseLinkedInTests.swift | 2 +- Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseObjectAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseOperationAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParsePointerAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseQueryAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift | 2 +- Tests/ParseSwiftTests/ParseUserAsyncTests.swift | 2 +- 46 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e914eaefb..966ecf35f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -201,7 +201,7 @@ jobs: - uses: actions/checkout@v2 - uses: MaxDesiatov/swift-windows-action@v1 with: - swift-version: "5.5.2" + swift-version: "5.5.1" shell-action: swift test --enable-test-discovery --enable-code-coverage -v - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift index 46e80fa45..32ef296fa 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseApple/ParseApple+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseApple { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift index 521d052cc..32c6c62d6 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseFacebook/ParseFacebook+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseFacebook { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift index 10af7a0d9..48940db38 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseGithub/ParseGitHub+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseGitHub { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift index c3f9b1b1a..8cbe5b812 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseGoogle/ParseGoogle+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseGoogle { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift index 52bebfabf..307d83a98 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseLDAP/ParseLDAP+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseLDAP { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift index bae5e970f..9a5f589c0 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseLinkedIn/ParseLinkedIn+async.swift @@ -6,7 +6,7 @@ // Copyright © 2022 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseLinkedIn { diff --git a/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift b/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift index 3e03a6577..78e4afe73 100644 --- a/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift +++ b/Sources/ParseSwift/Authentication/3rd Party/ParseTwitter/ParseTwitter+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseTwitter { diff --git a/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift b/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift index 31b181b02..8bd1ec3db 100644 --- a/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift +++ b/Sources/ParseSwift/Authentication/Internal/ParseAnonymous+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseAnonymous { diff --git a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift index bd0e2312a..6ae2870ae 100644 --- a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift +++ b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseAuthentication { diff --git a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift index 8bce657d5..7749dfbe9 100644 --- a/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift +++ b/Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift @@ -138,7 +138,7 @@ public protocol ParseAuthentication: Codable { func unlinkPublisher(options: API.Options) -> Future #endif - #if compiler(>=5.6.2) && canImport(_Concurrency) + #if compiler(>=5.5.2) && canImport(_Concurrency) // MARK: Async/Await /** diff --git a/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift b/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift index 68eaa449e..3d10cc93b 100644 --- a/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift +++ b/Sources/ParseSwift/LiveQuery/ParseLiveQuery+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) +#if compiler(>=5.5.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) import Foundation extension ParseLiveQuery { diff --git a/Sources/ParseSwift/Objects/ParseInstallation+async.swift b/Sources/ParseSwift/Objects/ParseInstallation+async.swift index 953d704f2..b408548f1 100644 --- a/Sources/ParseSwift/Objects/ParseInstallation+async.swift +++ b/Sources/ParseSwift/Objects/ParseInstallation+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseInstallation { diff --git a/Sources/ParseSwift/Objects/ParseObject+async.swift b/Sources/ParseSwift/Objects/ParseObject+async.swift index d2ea77823..4c423de86 100644 --- a/Sources/ParseSwift/Objects/ParseObject+async.swift +++ b/Sources/ParseSwift/Objects/ParseObject+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseObject { diff --git a/Sources/ParseSwift/Objects/ParseUser+async.swift b/Sources/ParseSwift/Objects/ParseUser+async.swift index c3c700c35..897568ffa 100644 --- a/Sources/ParseSwift/Objects/ParseUser+async.swift +++ b/Sources/ParseSwift/Objects/ParseUser+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseUser { diff --git a/Sources/ParseSwift/Types/ParseAnalytics+async.swift b/Sources/ParseSwift/Types/ParseAnalytics+async.swift index 9340ec456..20417f306 100644 --- a/Sources/ParseSwift/Types/ParseAnalytics+async.swift +++ b/Sources/ParseSwift/Types/ParseAnalytics+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if os(iOS) diff --git a/Sources/ParseSwift/Types/ParseCloud+async.swift b/Sources/ParseSwift/Types/ParseCloud+async.swift index 7c1c00449..79cf2ceaf 100644 --- a/Sources/ParseSwift/Types/ParseCloud+async.swift +++ b/Sources/ParseSwift/Types/ParseCloud+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseCloud { diff --git a/Sources/ParseSwift/Types/ParseConfig+async.swift b/Sources/ParseSwift/Types/ParseConfig+async.swift index 5d34dfe96..4b35fbae2 100644 --- a/Sources/ParseSwift/Types/ParseConfig+async.swift +++ b/Sources/ParseSwift/Types/ParseConfig+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseConfig { diff --git a/Sources/ParseSwift/Types/ParseFile+async.swift b/Sources/ParseSwift/Types/ParseFile+async.swift index cd50396dd..9126d9c7c 100644 --- a/Sources/ParseSwift/Types/ParseFile+async.swift +++ b/Sources/ParseSwift/Types/ParseFile+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Sources/ParseSwift/Types/ParseHealth+async.swift b/Sources/ParseSwift/Types/ParseHealth+async.swift index b1e7619ea..4d97e6297 100644 --- a/Sources/ParseSwift/Types/ParseHealth+async.swift +++ b/Sources/ParseSwift/Types/ParseHealth+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseHealth { diff --git a/Sources/ParseSwift/Types/ParseOperation+async.swift b/Sources/ParseSwift/Types/ParseOperation+async.swift index 0f386a76a..baf2dd719 100644 --- a/Sources/ParseSwift/Types/ParseOperation+async.swift +++ b/Sources/ParseSwift/Types/ParseOperation+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension ParseOperation { diff --git a/Sources/ParseSwift/Types/Pointer+async.swift b/Sources/ParseSwift/Types/Pointer+async.swift index 1009885a0..3bb86e5e6 100644 --- a/Sources/ParseSwift/Types/Pointer+async.swift +++ b/Sources/ParseSwift/Types/Pointer+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation // MARK: Async/Await diff --git a/Sources/ParseSwift/Types/Query+async.swift b/Sources/ParseSwift/Types/Query+async.swift index 0a777691b..542ebf5ec 100644 --- a/Sources/ParseSwift/Types/Query+async.swift +++ b/Sources/ParseSwift/Types/Query+async.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation public extension Query { diff --git a/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift index f440a7548..9ded6c7eb 100644 --- a/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnanlyticsAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift index b70bf9a31..5c60fd928 100644 --- a/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAnonymousAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift index fc81e4c9f..b133a7599 100644 --- a/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAppleAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift index 9a08ca465..2f73ef4dd 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking @@ -105,7 +105,7 @@ class ParseAuthenticationAsyncTests: XCTestCase { // swiftlint:disable:this type } #endif - #if compiler(>=5.6.2) && canImport(_Concurrency) + #if compiler(>=5.5.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift index b81a5218d..ebf465945 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationCombineTests.swift @@ -105,7 +105,7 @@ class ParseAuthenticationCombineTests: XCTestCase { } #endif - #if compiler(>=5.6.2) && canImport(_Concurrency) + #if compiler(>=5.5.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift index 96eafd31b..083973325 100644 --- a/Tests/ParseSwiftTests/ParseAuthenticationTests.swift +++ b/Tests/ParseSwiftTests/ParseAuthenticationTests.swift @@ -105,7 +105,7 @@ class ParseAuthenticationTests: XCTestCase { } #endif - #if compiler(>=5.6.2) && canImport(_Concurrency) + #if compiler(>=5.5.2) && canImport(_Concurrency) func login(authData: [String: String], options: API.Options) async throws -> AuthenticatedUser { throw ParseError(code: .unknownError, message: "Not implemented") diff --git a/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift b/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift index c2b1d9f37..c3fb627d2 100644 --- a/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseCloudAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift index 4d1511ae9..f0bd52a09 100644 --- a/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseConfigAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift index 5776a98d3..cbfced4f0 100644 --- a/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFacebookAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseFileAsyncTests.swift b/Tests/ParseSwiftTests/ParseFileAsyncTests.swift index e6f161512..4ec6a9898 100644 --- a/Tests/ParseSwiftTests/ParseFileAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseFileAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseGitHubTests.swift b/Tests/ParseSwiftTests/ParseGitHubTests.swift index d87564d28..5afa3da85 100644 --- a/Tests/ParseSwiftTests/ParseGitHubTests.swift +++ b/Tests/ParseSwiftTests/ParseGitHubTests.swift @@ -150,7 +150,7 @@ class ParseGitHubTests: XCTestCase { // swiftlint:disable:this type_body_length .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseGoogleTests.swift b/Tests/ParseSwiftTests/ParseGoogleTests.swift index 141d5418d..60779a872 100644 --- a/Tests/ParseSwiftTests/ParseGoogleTests.swift +++ b/Tests/ParseSwiftTests/ParseGoogleTests.swift @@ -162,7 +162,7 @@ class ParseGoogleTests: XCTestCase { // swiftlint:disable:this type_body_length .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift b/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift index 3d0791175..e1aaed307 100644 --- a/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseHealthAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift index 5615ec1b7..346ed35bb 100644 --- a/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseInstallationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift index ce77a223f..d2ce5910d 100644 --- a/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLDAPAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseLinkedInTests.swift b/Tests/ParseSwiftTests/ParseLinkedInTests.swift index 75365c124..bd5d4adf3 100644 --- a/Tests/ParseSwiftTests/ParseLinkedInTests.swift +++ b/Tests/ParseSwiftTests/ParseLinkedInTests.swift @@ -153,7 +153,7 @@ class ParseLinkedInTests: XCTestCase { // swiftlint:disable:this type_body_lengt .AuthenticationKeys.id.verifyMandatoryKeys(authData: authDataWrong)) } -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) @MainActor func testLogin() async throws { diff --git a/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift index 4741202f2..adfcb56f1 100644 --- a/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseLiveQueryAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) +#if compiler(>=5.5.2) && canImport(_Concurrency) && !os(Linux) && !os(Android) && !os(Windows) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift index 5caf9b75a..ea3bfc59a 100644 --- a/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseObjectAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift index cd3eb3cba..6840eb432 100644 --- a/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseOperationAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift index 0a4b7d518..2d5765897 100644 --- a/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParsePointerAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift index 5f2677f31..1a116a0bf 100644 --- a/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseQueryAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift index 180d00074..80dc2d1d7 100644 --- a/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseTwitterAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking diff --git a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift index f8a095885..497a969b3 100644 --- a/Tests/ParseSwiftTests/ParseUserAsyncTests.swift +++ b/Tests/ParseSwiftTests/ParseUserAsyncTests.swift @@ -6,7 +6,7 @@ // Copyright © 2021 Parse Community. All rights reserved. // -#if compiler(>=5.6.2) && canImport(_Concurrency) +#if compiler(>=5.5.2) && canImport(_Concurrency) import Foundation #if canImport(FoundationNetworking) import FoundationNetworking