@@ -426,6 +426,32 @@ extension ParseInstallation {
426426 - important: If an object saved has the same objectId as current, it will automatically update the current.
427427 */
428428 public func save( options: API . Options = [ ] ) throws -> Self {
429+ try save ( isIgnoreCustomObjectIdConfig: false ,
430+ options: options)
431+ }
432+
433+ /**
434+ Saves the `ParseInstallation` *synchronously* and throws an error if there's an issue.
435+
436+ - parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
437+ when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
438+ `objectId` environments. Defaults to false.
439+ - parameter options: A set of header options sent to the server. Defaults to an empty set.
440+ - throws: An error of type `ParseError`.
441+ - returns: Returns saved `ParseInstallation`.
442+ - important: If an object saved has the same objectId as current, it will automatically update the current.
443+ - warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
444+ and plan to generate all of your `objectId`'s on the client-side then you should leave
445+ `isIgnoreCustomObjectIdConfig = false`. Setting
446+ `ParseConfiguration.allowCustomObjectId = true` and
447+ `isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
448+ and the server will generate an `objectId` only when the client does not provide one. This can
449+ increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
450+ different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
451+ client-side checks are disabled. Developers are responsible for handling such cases.
452+ */
453+ public func save( isIgnoreCustomObjectIdConfig: Bool ,
454+ options: API . Options = [ ] ) throws -> Self {
429455 var options = options
430456 options. insert ( . cachePolicy( . reloadIgnoringLocalCacheData) )
431457 var childObjects : [ String : PointerType ] ?
@@ -445,7 +471,7 @@ extension ParseInstallation {
445471 throw error
446472 }
447473
448- let result : Self = try saveCommand ( )
474+ let result : Self = try saveCommand ( isIgnoreCustomObjectIdConfig : isIgnoreCustomObjectIdConfig )
449475 . execute ( options: options,
450476 callbackQueue: . main,
451477 childObjects: childObjects,
@@ -457,13 +483,26 @@ extension ParseInstallation {
457483 /**
458484 Saves the `ParseInstallation` *asynchronously* and executes the given callback block.
459485
486+ - parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
487+ when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
488+ `objectId` environments. Defaults to false.
460489 - parameter options: A set of header options sent to the server. Defaults to an empty set.
461490 - parameter callbackQueue: The queue to return to after completion. Default value of .main.
462491 - parameter completion: The block to execute.
463492 It should have the following argument signature: `(Result<Self, ParseError>)`.
464493 - important: If an object saved has the same objectId as current, it will automatically update the current.
494+ - warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
495+ and plan to generate all of your `objectId`'s on the client-side then you should leave
496+ `isIgnoreCustomObjectIdConfig = false`. Setting
497+ `ParseConfiguration.allowCustomObjectId = true` and
498+ `isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
499+ and the server will generate an `objectId` only when the client does not provide one. This can
500+ increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
501+ different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
502+ client-side checks are disabled. Developers are responsible for handling such cases.
465503 */
466504 public func save(
505+ isIgnoreCustomObjectIdConfig: Bool = false ,
467506 options: API . Options = [ ] ,
468507 callbackQueue: DispatchQueue = . main,
469508 completion: @escaping ( Result < Self , ParseError > ) -> Void
@@ -473,7 +512,7 @@ extension ParseInstallation {
473512 self . ensureDeepSave ( options: options) { ( savedChildObjects, savedChildFiles, error) in
474513 guard let parseError = error else {
475514 do {
476- try self . saveCommand ( )
515+ try self . saveCommand ( isIgnoreCustomObjectIdConfig : isIgnoreCustomObjectIdConfig )
477516 . executeAsync ( options: options,
478517 callbackQueue: callbackQueue,
479518 childObjects: savedChildObjects,
@@ -515,8 +554,8 @@ extension ParseInstallation {
515554 }
516555 }
517556
518- func saveCommand( ) throws -> API . Command < Self , Self > {
519- if ParseSwift . configuration. allowCustomObjectId && objectId == nil {
557+ func saveCommand( isIgnoreCustomObjectIdConfig : Bool = false ) throws -> API . Command < Self , Self > {
558+ if ParseSwift . configuration. allowCustomObjectId && objectId == nil && !isIgnoreCustomObjectIdConfig {
520559 throw ParseError ( code: . missingObjectId, message: " objectId must not be nil " )
521560 }
522561 if isSaved {
@@ -643,6 +682,9 @@ public extension Sequence where Element: ParseInstallation {
643682 - parameter batchLimit: The maximum number of objects to send in each batch. If the items to be batched.
644683 is greater than the `batchLimit`, the objects will be sent to the server in waves up to the `batchLimit`.
645684 Defaults to 50.
685+ - parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
686+ when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
687+ `objectId` environments. Defaults to false.
646688 - parameter options: A set of header options sent to the server. Defaults to an empty set.
647689 - parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
648690 prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
@@ -653,9 +695,19 @@ public extension Sequence where Element: ParseInstallation {
653695 - warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
654696 objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
655697 the transactions can fail.
698+ - warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
699+ and plan to generate all of your `objectId`'s on the client-side then you should leave
700+ `isIgnoreCustomObjectIdConfig = false`. Setting
701+ `ParseConfiguration.allowCustomObjectId = true` and
702+ `isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
703+ and the server will generate an `objectId` only when the client does not provide one. This can
704+ increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
705+ different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
706+ client-side checks are disabled. Developers are responsible for handling such cases.
656707 */
657708 func saveAll( batchLimit limit: Int ? = nil , // swiftlint:disable:this function_body_length
658709 transaction: Bool = false ,
710+ isIgnoreCustomObjectIdConfig: Bool = false ,
659711 options: API . Options = [ ] ) throws -> [ ( Result < Self . Element , ParseError > ) ] {
660712 var options = options
661713 options. insert ( . cachePolicy( . reloadIgnoringLocalCacheData) )
@@ -703,7 +755,9 @@ public extension Sequence where Element: ParseInstallation {
703755 }
704756
705757 var returnBatch = [ ( Result < Self . Element , ParseError > ) ] ( )
706- let commands = try map { try $0. saveCommand ( ) }
758+ let commands = try map {
759+ try $0. saveCommand ( isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
760+ }
707761 let batchLimit : Int !
708762 if transaction {
709763 batchLimit = commands. count
@@ -731,6 +785,9 @@ public extension Sequence where Element: ParseInstallation {
731785 Defaults to 50.
732786 - parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
733787 prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
788+ - parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
789+ when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
790+ `objectId` environments. Defaults to false.
734791 - parameter options: A set of header options sent to the server. Defaults to an empty set.
735792 - parameter callbackQueue: The queue to return to after completion. Default value of .main.
736793 - parameter completion: The block to execute.
@@ -739,10 +796,20 @@ public extension Sequence where Element: ParseInstallation {
739796 - warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
740797 objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
741798 the transactions can fail.
799+ - warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
800+ and plan to generate all of your `objectId`'s on the client-side then you should leave
801+ `isIgnoreCustomObjectIdConfig = false`. Setting
802+ `ParseConfiguration.allowCustomObjectId = true` and
803+ `isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
804+ and the server will generate an `objectId` only when the client does not provide one. This can
805+ increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
806+ different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
807+ client-side checks are disabled. Developers are responsible for handling such cases.
742808 */
743809 func saveAll( // swiftlint:disable:this function_body_length cyclomatic_complexity
744810 batchLimit limit: Int ? = nil ,
745811 transaction: Bool = false ,
812+ isIgnoreCustomObjectIdConfig: Bool = false ,
746813 options: API . Options = [ ] ,
747814 callbackQueue: DispatchQueue = . main,
748815 completion: @escaping ( Result < [ ( Result < Element , ParseError > ) ] , ParseError > ) -> Void
@@ -805,7 +872,9 @@ public extension Sequence where Element: ParseInstallation {
805872
806873 do {
807874 var returnBatch = [ ( Result < Self . Element , ParseError > ) ] ( )
808- let commands = try map { try $0. saveCommand ( ) }
875+ let commands = try map {
876+ try $0. saveCommand ( isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
877+ }
809878 let batchLimit : Int !
810879 if transaction {
811880 batchLimit = commands. count
0 commit comments