IOS ParseError: Attempting to change an Id object to one already known in offline storage

I have a regular problem with my project using Parse Server. First, I call the Parse Cloud function to populate the list of user data:

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) } } } 

In the code above, I have to set objectId , because without it, no matter how many objects I retrieve from Parse, when I reduce the array to a set with the last instruction, I get only one object in this.

However, although this works when I call this function again to update user data, I get this error in the string myData.dataSource?.objectId = temp["objectId"] as? String myData.dataSource?.objectId = temp["objectId"] as? String :

Trying to change the ID object to one that is already known to offline storage.

Tried to find some information about this, but nothing very relevant ...

Thank you for your help.

+5
source share
2 answers

This is actually not an answer, but too long for a comment:

I understand the following:
The cloud function loadData returns success , which is an array of dictionaries or, possibly, in case of an error, nil . If nil returns, you do nothing.
If the array is returned, it is called objects .
Then this array is mapped to an array of elements of type MyData .
For each item returned from a cloud function called object , an instance of MyData is created using the dataSource new PFObject instance of the MyData class and the properties specified by the dictionary object.
I do not understand the following statement, according to which you assign the objectId 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 that you need to do this or else you will get one element in the result set (see below).
Anyway, now you have an array of MyData instances in the dataTable .
Then you initialize the dataSet , which is not required since it will be overwritten anyway with your last expression.
This statement creates a collection of dataTable .

Now, when you get one element in this set, if 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. That means your init function

 MyData(dataSource: PFObject(className: "MyData", dictionary: object)) 

always returns the same object, and this object is created by another, setting its property objectId . This is very strange for me. Please check what happens there.

Now, if you call loadData again to update the data, the cloud function will probably return some or all of the previous objects again. In this case, you assigned the old objectId , which was already assigned earlier by PFObject , created in the map function, to another PFObject created there, which is not allowed, therefore an error message.

Shorten this:
If the same object is repeatedly returned from a cloud function, you should not create different PFObjects for them and assign them the same objectId .

Hope this helps!

0
source

http://parseplatform.org/Parse-SDK-iOS-OSX/api/Protocols/PFSubclassing.html

If a subclass of PFObject matches PFSubclassing and calls PFObject. + registerSubclass, Framework Parse will be able to use this class as a native class for the Parse cloud object.

For instance:

1.Create your subclass of PFObject

 import Parse class Question: PFObject, PFSubclassing { @NSManaged var category: String? @NSManaged var text: String @NSManaged var image: PFFile? @NSManaged var answerType: String @NSManaged var order: NSNumber static func parseClassName() -> String { return "Question" } } class User: PFUser { @NSManaged var fullname: String } 

2. Subclass of the subclass

 extension Parse { class func registerSubclasses() { User.registerSubclass() Question.registerSubclass() } } 

3.Install the parsing service after starting the application

 Parse.registerSubclasses() Parse.enableLocalDatastore() Parse.setApplicationId(PARSE_APP_ID, clientKey: PARSE_APP_KEY) 

4.Now PFUser == User , Question == PFObject(className: "Question")

5.It works for cloud function

 PFCloud.callFunctionInBackground("fetchQuestions", withParameters: parameters) { questions, error in if let questions = questions as? [Question] { completion?(questions, nil) } else { completion?(nil, error) } } 

Note: the fast code may be old, there should be some changes when using the faster version.

0
source

Source: https://habr.com/ru/post/1272875/


All Articles