Saltar al contenido

Swift / CloudKit: después de cambiar el registro, la carga activa "Registro de servicio cambiado"

Te recomendamos que revises esta respuesta en un entorno controlado antes de pasarlo a producción, saludos.

Solución:

Parece que está creando un nuevo CKRecord cada vez que guarda.

CloudKit está regresando ServerRecordChanged para decirle que ya existe un registro con el mismo recordID en el servidor, y su intento de guardar fue rechazado porque la versión del registro del servidor era diferente.

Cada registro tiene una etiqueta de cambio que le permite al servidor rastrear cuándo se guardó ese registro. Cuando guarda un registro, CloudKit compara la etiqueta de cambio en su copia local del registro con la del servidor. Si las dos etiquetas no coinciden, lo que significa que existe un conflicto potencial, el servidor usa el valor en el [savePolicy property of CKModifyRecordsOperation] para determinar cómo proceder.

Fuente: CKModifyRecordsReferencia de operación

Aunque esté utilizando el CKDatabase.saveRecord método de conveniencia, esto todavía se aplica. La política de guardado predeterminada es ifServerRecordUnchanged.

En primer lugar, sugeriría hacer la transición a CKModifyRecordsOperation, especialmente si está guardando varios registros. Te da mucho más control sobre el proceso.

En segundo lugar, debe realizar cambios en el CKRecord desde el servidor al guardar los cambios en un registro existente. Puede lograr esto mediante cualquiera de los siguientes:

  1. Solicitar el CKRecord de CloudKit, realizar cambios en ese CKRecord y luego volver a guardarlo en CloudKit.
  2. Almacenar el CKRecord guardado (el que se devuelve en el bloque de finalización después de guardar) usando el consejo en el CKRecord Referencia, conservando estos datos y luego desarchivándolos para recuperar un CKRecord que puede modificar y guardar en el servidor. (Esto evita algunos viajes de ida y vuelta de la red para solicitar el servidor CKRecord).

Almacenamiento de registros localmente

Si almacena registros en una base de datos local, use el método encodeSystemFields(with:) para codificar y almacenar los metadatos del registro. Los metadatos contienen el ID de registro y la etiqueta de cambio que se necesitan más adelante para sincronizar registros en una base de datos local con los almacenados por CloudKit.

let record = ...

// archive CKRecord to NSData
let archivedData = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWithMutableData: archivedData)
archiver.requiresSecureCoding = true
record.encodeSystemFieldsWithCoder(archiver)
archiver.finishEncoding()

// unarchive CKRecord from NSData
let unarchiver = NSKeyedUnarchiver(forReadingWithData: archivedData)  
unarchiver.requiresSecureCoding = true 
let unarchivedRecord = CKRecord(coder: unarchiver)

Fuente: Consejos y trucos de CloudKit - WWDC 2015

Tenga en cuenta: todavía puede encontrar el ServerRecordChanged error si otro dispositivo guarda un cambio en el registro después de que usted lo solicitó/lo guardó por última vez y almacenó el registro del servidor. Debe manejar este error obteniendo el último registro del servidor y volviendo a aplicar sus cambios a ese CKRecord.

Acuérdate de que tienes concesión de decir si tropezaste tu atolladero en el momento justo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada.