Strategia per evitare gli ID di oggetti duplicati per i dati condivisi su dispositivi che utilizzano iCloud

2

Ho un'app per iOS ad alta intensità di dati che non utilizza CoreData né supporta la sincronizzazione di iCloud (ancora). Tutti i miei oggetti sono creati con chiavi uniche. Io uso una semplice long long inizializzata con l'ora corrente. Quindi, poiché ho bisogno di una nuova chiave, incremento il valore di 1. Ciò ha funzionato bene per alcuni anni con l'app in esecuzione isolata su un singolo dispositivo.

Ora desidero aggiungere il supporto per la sincronizzazione automatica dei dati tra i dispositivi tramite iCloud. Poiché la mia app è scritta, c'è la possibilità che due oggetti creati su due dispositivi diversi possano finire con la stessa chiave. Devo evitare questa possibilità.

Sto cercando idee per risolvere questo problema. Ho alcuni requisiti che la soluzione deve soddisfare:

1) La chiave deve rimanere un singolo tipo di dati integrale. La conversione di tutte le chiavi esistenti in una chiave composta o in una stringa o in un altro tipo influenzerebbe l'intero codice e probabilmente causerebbe più bug di quanti ne valga.

2) La soluzione non può dipendere da una connessione Internet. Un utente deve essere in grado di eseguire l'app e aggiungere dati anche senza connessione Internet. I dati dovrebbero comunque risolversi correttamente in seguito quando i dati si sincronizzano con iCloud una volta disponibile una connessione. Accetterò un'eccezione a questa regola. Se non sono disponibili altre opzioni, potrei essere aperto a richiedere una connessione Internet la prima volta che i dati dell'app vengono inizializzati.

Un'idea con cui mi stavo giocando in testa sta dividendo logicamente la chiave intera in due parti. I 4 o 5 bit alti potrebbero essere usati come una sorta di id del dispositivo mentre il resto rappresenta la chiave effettiva. La parte fuzzy sta scoprendo come escogitare id di dispositivo non conflittuali che si adattano a pochi bit. Questo dovrebbe essere praticabile dal momento che non devo occuparmi di milioni di dispositivi. Devo solo occuparmi dei pochi dispositivi che sarebbero condivisi da un determinato account iCloud.

Sono aperto a suggerimenti. Grazie.

Aggiornamento:

Dopo aver dato questo un po 'di pensiero, ho deciso di prendere il colpo a breve termine e farlo nel modo giusto. L'utilizzo di un GUID è sicuramente la migliore opzione a lungo termine per questo. L'utilizzo di questo approccio elimina la necessità di eseguire una qualsiasi delle varie opzioni per gestire la distribuzione di intervalli di chiavi o la traduzione di chiavi una volta stabilita una connessione Internet.

Il mio requisito originale ha impedito l'opzione GUID perché né SQLite né iOS supportano un semplice tipo intero a 128 bit. Dal momento che ho una grande base di codice esistente scritta in modo tale che le mie chiavi sono semplici tipi interi, richiederà un importante refactoring sia del codice che dello schema del database.

Alla fine, ho deciso che il dolore a breve termine di fare questo refactoring pesa sui problemi a lungo termine della gestione di una soluzione klunky. Prendendo il colpo ora mi dà una soluzione molto più semplice e meno incline agli errori che durerà nel lungo termine.

    
posta rmaddy 03.12.2012 - 20:39
fonte

4 risposte

3

Poiché Lars Viklund indica nel suo commento, potresti look in UUID - sono numeri a 128 bit usati per ID univoci e hanno buone statistiche per l'unicità. Se non riesci a trovare una funzione per generarne una (anche se sono sicuro che Apple ne abbia una), la Versione 4 è piuttosto semplice da implementare.

    
risposta data 03.12.2012 - 22:46
fonte
1

Dipende molto da come vengono usati i tasti e dalle conseguenze dei duplicati accidentali. Alcune scelte ovvie:

(1) il tempo esatto (fino al nanosecondo se possibile) è statisticamente certo di essere unico tra alcuni dispositivi. È sufficiente utilizzare un tempo sufficientemente preciso in quanto è probabile che la chiave abbia un'affidabilità complessiva maggiore rispetto a uno schema più complicato.

(2) Rendi ogni chiave una chiave per dispositivo e assegna una vera chiave univoca quando il dispositivo si sincronizza con il cloud. Mantieni un dizionario nel cloud. (2a) generare chiavi temporanee in serie. Alla prima sincronizzazione, acquisisci un blocco di chiavi permanenti e rinumeralo.

(3) rilasciano blocchi di un miliardo di chiavi così ai dispositivi la prima volta che li collegano, lascia che i dispositivi sostituiscano le chiavi secondo necessità.

    
risposta data 03.12.2012 - 21:30
fonte
1

One idea I have been toying around with in my head is logically splitting the integer key into two parts. The high 4 or 5 bits could be used as some sort of device id while the rest represents the actual key. The fuzzy part is figuring out how to come up with non-conflicting device ids that fit in a few bits

IMO Questa è l'opzione migliore. (Mi piace avere l'ID del dispositivo legato ai dati)

La mia seconda opzione sarebbe avere il server Emettere un blocco di ID al client durante la sincronizzazione. Quindi, quando il client si sincronizza con il server, il server dice che l'ID del cliente è 10000-20000. La prossima volta che il client si sincronizza se ci sono meno di 5k Id rimanenti, il server lo assegna e altri 5k id. Se il client ha esaurito Id, DEVE sincronizzarsi .. (È una buona idea non lasciare che il Client si accumuli una quantità infinita di dati senza sincronizzazione in ogni caso)

    
risposta data 03.12.2012 - 23:51
fonte
0

L'altra opzione sarebbe quella di continuare ad assegnare chiavi sul client come al momento, ma quando si esegue la sincronizzazione, si genera nuovamente la chiave sul server che la rende unica. Dovrai ricordarti di aggiornare la chiave su qualsiasi entità figlia per assicurarti che facciano il link correttamente.

    
risposta data 04.12.2012 - 14:54
fonte

Leggi altre domande sui tag