Skip to content

Create witch custom id #225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.8...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

__Improvements__
- Added createWithCustomObjectId parameter in .save() functions to remove the need of setting isIgnoreCustomObjectIdConfig = true and allowCustomObjectId = true for a mixed custom objectId environment. ([#225](https://github.com/parse-community/Parse-Swift/pull/225)), thanks to [Lukas Smilek](https://github.com/lsmilek1)

### 1.9.8
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.9.7...1.9.8)

Expand Down
6 changes: 3 additions & 3 deletions Sources/ParseSwift/API/API+Commands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,11 @@ internal extension API.Command {

// MARK: Saving ParseObjects
static func save<T>(_ object: T,
isIgnoreCustomObjectIdConfig: Bool) throws -> API.Command<T, T> where T: ParseObject {
if ParseSwift.configuration.allowCustomObjectId && object.objectId == nil && !isIgnoreCustomObjectIdConfig {
isIgnoreCustomObjectIdConfig: Bool, createWithCustomObjectId: Bool) throws -> API.Command<T, T> where T: ParseObject {
if (ParseSwift.configuration.allowCustomObjectId && object.objectId == nil && !isIgnoreCustomObjectIdConfig) || (object.objectId == nil && createWithCustomObjectId) {
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
}
if object.isSaved {
if object.isSaved && !createWithCustomObjectId {
return update(object)
}
return create(object)
Expand Down
32 changes: 32 additions & 0 deletions Sources/ParseSwift/Objects/ParseInstallation+combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,30 @@ public extension ParseInstallation {
/**
Saves the `ParseInstallation` *asynchronously* and publishes when complete.

- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- important: If an object saved has the same objectId as current, it will automatically update the current.
- warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
and plan to generate all of your `objectId`'s on the client-side then you should leave
`isIgnoreCustomObjectIdConfig = false`. Setting
`ParseConfiguration.allowCustomObjectId = true` and
`isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
and the server will generate an `objectId` only when the client does not provide one. This can
increase the probability of colliiding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
*/
func savePublisher(isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) -> Future<Self, ParseError> {
Future { promise in
self.save(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig,
createWithCustomObjectId: createWithCustomObjectId,
options: options,
completion: promise)
}
Expand Down Expand Up @@ -95,21 +111,37 @@ public extension Sequence where Element: ParseInstallation {
Defaults to 50.
- parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- important: If an object saved has the same objectId as current, it will automatically update the current.
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
the transactions can fail.
- warning: If you are using `ParseConfiguration.allowCustomObjectId = true`
and plan to generate all of your `objectId`'s on the client-side then you should leave
`isIgnoreCustomObjectIdConfig = false`. Setting
`ParseConfiguration.allowCustomObjectId = true` and
`isIgnoreCustomObjectIdConfig = true` means the client will generate `objectId`'s
and the server will generate an `objectId` only when the client does not provide one. This can
increase the probability of colliiding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
*/
func saveAllPublisher(batchLimit limit: Int? = nil,
transaction: Bool = false,
isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
Future { promise in
self.saveAll(batchLimit: limit,
transaction: transaction,
isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig,
createWithCustomObjectId: createWithCustomObjectId,
options: options,
completion: promise)
}
Expand Down
29 changes: 21 additions & 8 deletions Sources/ParseSwift/Objects/ParseInstallation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ extension ParseInstallation {
*/
public func save(options: API.Options = []) throws -> Self {
try save(isIgnoreCustomObjectIdConfig: false,
createWithCustomObjectId: false,
options: options)
}

Expand All @@ -436,6 +437,8 @@ extension ParseInstallation {
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- throws: An error of type `ParseError`.
- returns: Returns saved `ParseInstallation`.
Expand All @@ -450,7 +453,8 @@ extension ParseInstallation {
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
*/
public func save(isIgnoreCustomObjectIdConfig: Bool,
public func save(isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) throws -> Self {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
Expand All @@ -471,7 +475,7 @@ extension ParseInstallation {
throw error
}

let result: Self = try saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
let result: Self = try saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig, createWithCustomObjectId: createWithCustomObjectId)
.execute(options: options,
callbackQueue: .main,
childObjects: childObjects,
Expand All @@ -486,6 +490,8 @@ extension ParseInstallation {
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
- parameter completion: The block to execute.
Expand All @@ -503,6 +509,7 @@ extension ParseInstallation {
*/
public func save(
isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = [],
callbackQueue: DispatchQueue = .main,
completion: @escaping (Result<Self, ParseError>) -> Void
Expand All @@ -512,7 +519,7 @@ extension ParseInstallation {
self.ensureDeepSave(options: options) { (savedChildObjects, savedChildFiles, error) in
guard let parseError = error else {
do {
try self.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
try self.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig, createWithCustomObjectId: createWithCustomObjectId)
.executeAsync(options: options,
callbackQueue: callbackQueue,
childObjects: savedChildObjects,
Expand Down Expand Up @@ -554,11 +561,11 @@ extension ParseInstallation {
}
}

func saveCommand(isIgnoreCustomObjectIdConfig: Bool = false) throws -> API.Command<Self, Self> {
if ParseSwift.configuration.allowCustomObjectId && objectId == nil && !isIgnoreCustomObjectIdConfig {
func saveCommand(isIgnoreCustomObjectIdConfig: Bool = false, createWithCustomObjectId: Bool = false) throws -> API.Command<Self, Self> {
if (ParseSwift.configuration.allowCustomObjectId && objectId == nil && !isIgnoreCustomObjectIdConfig) || (objectId == nil && createWithCustomObjectId) {
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
}
if isSaved {
if isSaved && !createWithCustomObjectId{
return updateCommand()
}
return createCommand()
Expand Down Expand Up @@ -685,6 +692,8 @@ public extension Sequence where Element: ParseInstallation {
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
Expand All @@ -708,6 +717,7 @@ public extension Sequence where Element: ParseInstallation {
func saveAll(batchLimit limit: Int? = nil, // swiftlint:disable:this function_body_length
transaction: Bool = false,
isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) throws -> [(Result<Self.Element, ParseError>)] {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
Expand Down Expand Up @@ -756,7 +766,7 @@ public extension Sequence where Element: ParseInstallation {

var returnBatch = [(Result<Self.Element, ParseError>)]()
let commands = try map {
try $0.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
try $0.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig, createWithCustomObjectId: createWithCustomObjectId)
}
let batchLimit: Int!
if transaction {
Expand Down Expand Up @@ -788,6 +798,8 @@ public extension Sequence where Element: ParseInstallation {
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
- parameter completion: The block to execute.
Expand All @@ -810,6 +822,7 @@ public extension Sequence where Element: ParseInstallation {
batchLimit limit: Int? = nil,
transaction: Bool = false,
isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = [],
callbackQueue: DispatchQueue = .main,
completion: @escaping (Result<[(Result<Element, ParseError>)], ParseError>) -> Void
Expand Down Expand Up @@ -873,7 +886,7 @@ public extension Sequence where Element: ParseInstallation {
do {
var returnBatch = [(Result<Self.Element, ParseError>)]()
let commands = try map {
try $0.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig)
try $0.saveCommand(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig, createWithCustomObjectId: createWithCustomObjectId)
}
let batchLimit: Int!
if transaction {
Expand Down
11 changes: 11 additions & 0 deletions Sources/ParseSwift/Objects/ParseObject+combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,21 @@ public extension ParseObject {
/**
Saves the `ParseObject` *asynchronously* and publishes when complete.

- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- important: If an object saved has the same objectId as current, it will automatically update the current.
*/
func savePublisher(isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) -> Future<Self, ParseError> {
Future { promise in
self.save(isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig,
createWithCustomObjectId: createWithCustomObjectId,
options: options,
completion: promise)
}
Expand Down Expand Up @@ -94,6 +101,8 @@ public extension Sequence where Element: ParseObject {
- parameter isIgnoreCustomObjectIdConfig: Ignore checking for `objectId`
when `ParseConfiguration.allowCustomObjectId = true` to allow for mixed
`objectId` environments. Defaults to false.
- parameter createWithCustomObjectId: Ignore checking `ParseConfiguration.allowCustomObjectId = true`
and try to create object with given custom `objectId` to allow for mixed `objectId` environments. Defaults to false.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- important: If an object saved has the same objectId as current, it will automatically update the current.
Expand All @@ -113,11 +122,13 @@ public extension Sequence where Element: ParseObject {
func saveAllPublisher(batchLimit limit: Int? = nil,
transaction: Bool = false,
isIgnoreCustomObjectIdConfig: Bool = false,
createWithCustomObjectId: Bool = false,
options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
Future { promise in
self.saveAll(batchLimit: limit,
transaction: transaction,
isIgnoreCustomObjectIdConfig: isIgnoreCustomObjectIdConfig,
createWithCustomObjectId: createWithCustomObjectId,
options: options,
completion: promise)
}
Expand Down
Loading