CloudKit CKModifyRecordsOperation gibt mir eine "Schutzdaten stimmte nicht überein"

8

Ich versuche einige Datensatzänderungen mit CloudKit hochzuladen. Ich bin dabei, eine CKModifyRecordsOperation zu verwenden, um einen Batch-Upload von Datensätzen durchzuführen, die sich auf dem Gerät geändert haben. Die Datensätze befinden sich alle in einer benutzerdefinierten Zone.

Aus irgendeinem Grund kommt die Operation immer wieder mit einem Fehler zurück, der mir sagt: "Die Schutzdaten stimmen nicht überein"

Hier ist der Code:

%Vor%

Hier ist der Fehler, den es mir gibt:

%Vor%     
Jonathan 12.09.2014, 20:12
quelle

4 Antworten

5

Was genau ist in Ihrem self.localChanges -Array? CKRecord Ich nehme an, aber sind die geänderten Datensätze, die Sie hochladen, auf denselben CKRecord-Objekten basiert, die Sie von CloudKit heruntergeladen haben?

Ich hatte eine ähnliche (wenn auch nicht exakte) Fehlermeldung, als ich versuchte, ein frisch zugewiesenes CKRecord mit meinen lokalen Änderungen hochzuladen und erwartete, dass es die Kopie des Servers überschreiben würde. Ich habe es behoben, indem ich die Remote-Kopie meines Objekts heruntergeladen habe, Updates für die CKRecord-Instanz, die ich von CloudKit erhalten habe, übernommen und dann hochgeladen habe.

    
Dave Teare 04.10.2014, 00:45
quelle
7

Wenn Sie savePolicy von CKRecordSaveIfServerRecordUnchanged verwenden, müssen Sie eine entfernte CKRecord vorab holen (und diese bestimmte Instanz aktualisieren), bevor CKModifyRecordsOperation . Wenn Sie eine "lokale" CKRecord zuweisen und sie über CKRecordID mit einer übereinstimmenden initWithRecordName: referenzieren, kann CloudKit ein entferntes Änderungs-Tag nicht mit einem (fehlenden) lokalen Änderungs-Tag vergleichen, sodass es mit% co_de fehlschlägt % und die etwas vage Fehlermeldung: "Schutzdaten stimmen nicht überein".

Wenn jedoch ein entfernter CKErrorServerRecordChanged überhaupt nicht existiert, hat sich der Server-Datensatz sicher nicht geändert und der Speichervorgang kann fortgesetzt werden. Dieses Verhalten ist die Grundlage für den Anwendungsfall "Save If Not Exists" (SQL: INSERT über einen PRIMARY KEY). Wenn Sie eine "lokale" CKRecord zuweisen und die CKRecord von savePolicy verwenden, wird INSERT, aber niemals UPDATE.

Wenn Sie die CKRecordSaveIfServerRecordUnchanged von savePolicy und die CKRecordSaveAllKeys CKRecordZoneID von ownerName verwenden, sollten Sie in der Lage sein, (SQL: UPDATE, mit INSERT falls erforderlich) durch ein "lokal" zugeordnet CKOwnerDefaultName , Speichern eines (Pre-Fetch) Trips über das Netzwerk.

Der Anwendungsfall "Save If Exists" (SQL: UPDATE über einen PRIMARY KEY) kann wahrscheinlich nicht ohne einen (Verifikations-) Trip über das Netzwerk durchgeführt werden.

Ein Haken: Es ist nicht möglich, sowohl eine CKRecord INSERT als auch eine CKRecordSaveIfServerRecordUnchanged UPDATE in eine atomare Transaktion zu rollen, da CloudKit Transaktionen nur eine einzige CKRecordSaveAllKeys über mehrere CKModifyRecordsOperation / CKRecord Instanzen umfassen . Philosophisch gesehen sollte eine "Transaktion" mehrere "Operationen" (SQL: Abfragen) umfassen können, nicht nur mehrere "Datensätze" (SQL: Zeilen).

    
Gary 07.08.2015 06:13
quelle
2

Sie sollten Schreibrechte für die entsprechenden Datensatztypen im Dashboard festlegen, denke ich.

    
János 17.09.2014 07:25
quelle
0

Es ist erwähnenswert, dass die Lösung dafür zweifach war. Ich habe auch versucht, eine benutzerdefinierte Zone zu verwenden. Wo auch immer ich eine CKRecordZoneID initialisiert habe, sah der Code so aus:

%Vor%

Das hätte so aussehen sollen

%Vor%

Ich glaube, dass dies ein Teil dessen ist, was die "Schutzdaten, die nicht dem Fehler entsprechen" verursacht hat, aber die Antwort von Dave Teare war auch notwendig, um es zu beheben.

    
Jonathan 09.10.2014 04:59
quelle

Tags und Links