I'm having a regular issue with my project, using Parse Server. First, I call a Parse Cloud function to populate a user's data list :
var dataSet: Set<MyData>?
func loadData(withParameters parameters: [String : Any]) {
PFCloud.callFunction(inBackground: "loadData", withParameters: parameters) { (success, error) in
if let objects = success as? [[String : Any]] {
let dataTable: [MyData] = objects.map({ (object) -> MyData in
let myData = MyData(dataSource: PFObject(className: "MyData",
dictionary: object))
myData.dataSource?.objectId = object["objectId"] as? String
return myData
})
if self.dataSet == nil {
self.dataSet = []
}
self.dataSet = Set(dataTable)
}
}
}
On the code mentioned above, I have to set the objectId
because without this, no matter how many objects I fetch from Parse, when I reduce the array to a set with the last instruction I end up with only one object in it.
However, although this works, when I call this function again to update user's data, I get this error on the myData.dataSource?.objectId = temp["objectId"] as? String
line :
Attempted to change an objectId to one that's already known to the Offline Store.
Tried to find some information about it but nothing very relevant...
Thanks for your help.
This is no really an answer, but too long for a comment:
I understand the following:
Your cloud function loadData
returns success
, which is an array of dictionaries or, probably in case of an error, nil
. If nil
is returned, you do nothing.
If an array is returned, it is referred as objects
.
This array is then mapped to an array of elements of type MyData
.
For every element returned from the cloud function, called object
, a MyData
instance is created using as dataSource
a new PFObject
instance of class MyData
and properties given by the object dictionary.
I do not understand the next statement by which you assign the objectId
of the object returned from the cloud function to the newly created PFObject
: As far as I know, objectIds
must be unique, and cannot (or at least should not) be assigned to other PFObjects
.
But you said you have to do this or otherwise you end up with a single element in the resulting set (see below).
Anyway, you have now an array of MyData
instances in dataTable
.
Then, you initialise dataSet
, which is not required since it will be overwritten anyway by your last statement.
This statement makes a set of the dataTable
array.
Now, when you get a single element in this set in case you do not set the objectId
property of the elements of the dataTable
array, this means that all elements of this array are the same object. And this means that your init function
MyData(dataSource: PFObject(className: "MyData",
dictionary: object))
returns always the same object, and this object is made to a different one by setting its objectId
property. This is very strange to me. Please check what it going on there.
Now if you call loadData
once more to update the data, the cloud function probably returns some or all of the previous objects again. In this case, you would assign an old objectId
, that has already been assigned earlier to a PFObject
created in the map function, to another newly created PFObject
created there, which is not allowed, thus the error message.
To cut it short:
If the same object is returned from the cloud function repeatedly, you must not create different PFObjects
for them, and assign them the same objectId
.
I hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With