2014-07-16 12 views
6

Sto tentando di creare un tipo di record che contiene valori univoci e che fungerà da oggetto di riferimento di destinazione per un altro tipo di record. Ad esempio, Record Type - Movies conterrà un elenco univoco di film inviati dagli utenti. E FavoriteMovies conterrebbe un riferimento di utenti e un riferimento di film. Gli utenti possono selezionare da un elenco di film esistenti o aggiungerne di nuovi.CloudKit - Come salvare il record se non esiste

Il problema si verifica se creo un nuovo record Film, mentre un altro utente crea un nuovo record con lo stesso nome (dopo aver recuperato l'elenco dei film, ma prima di tentare di aggiungerne uno nuovo). I due nuovi record sono considerati record diversi con recordID diversi. Ciò significa che una volta salvato il nuovo, ci saranno due istanze di Movies con il nome di salvataggio.

Non riesco a trovare un modo per eseguire un'operazione di salvataggio Se non esiste digitare il tipo di record di filmati. Potrei fare un salvataggio nel completamentoBlocco di una query, ma quelle due azioni non sarebbero una transazione atomica per garantire l'unicità. Per quanto ne so questo è anche il caso di concatenare CKQueryOperation con CKModifyRecordsOperation.

C'è un modo per inserire un record solo se il valore non esiste in una singola transazione?

risposta

6

Se ho capito bene il tuo caso d'uso, è possibile rendere movieRecord.recordID.recordName il nome del filmato e utilizzare CKModifyRecordsOperation con savePolicyIfServerRecordUnchanged per salvare in modo efficace se non esiste. Sarebbe poi tornare un errore che si può ignorare se si tenta di salvare un record che già esiste sul server:

let saveRecordsOperation = CKModifyRecordsOperation() 
saveRecordsOperation.recordsToSave = [movieRecord] 
saveRecordsOperation.savePolicy = .IfServerRecordUnchanged 

Con il savePolicy IfServerRecordUnchanged questa operazione farà risparmiare un nuovo record di film se non esiste ancora sul server (Salva se non esiste) ma restituirà l'errore di seguito in qualsiasi tentativo successivo di sovrascrivere un record filmato già esistente sul server (a condizione che non sia una versione modificata più recente di un record che è stato recuperato dal server):

<CKError 0x14d23980: "Server Record Changed" (14/2017); server message = "record to insert already exists"> 

si potrebbe far fronte a questo conflitto nel perRecordCompletionBlock ma nel tuo caso d'uso specifico che si non può fare nulla sull'errore di conflitto, quindi ogni record di film sarà il primo record salvato con quel CKRecordID.

+0

Purtroppo questo non funziona per me. Sto creando una nuova istanza di movieRecord da aggiungere alla lista. Se un altro utente ha creato un record con lo stesso nome (dopo aver recuperato l'elenco dei film, ma prima di tentare di aggiungerne uno nuovo), vengono considerati record diversi poiché hanno recordID diversi. Ciò significa che anche se il mio savePolicy è impostato su IfServerRecordUnchanged, l'operazione non genera un errore. Invece vedrei due dischi diversi con lo stesso nome. – Denis

+0

Capito. Funzionerebbe se hai fatto movieRecord.recordID.recordName il nome del film. Ho un caso d'uso simile usando il database pubblico e questo è quello che sto facendo per mantenere unici i record pubblici. Ho apportato una modifica alla risposta per notare quell'ipotesi. –

+0

Buona idea, questo lavoro lo farà per me. Grazie! – Denis