Progettazione per mantenere i dati del profilo utente locale sincronizzati con il server

0

Quindi sto lavorando su un'app iOS e sto pensando a come mantenere i dati del profilo utente sincronizzati tra server e client.

La prima idea che mi viene in mente è creare una classe chiamata User . Sarebbe una sottoclasse di NSMutableDictionary .

Quindi dichiarerei un'istanza condivisa all'interno di User in modo che tutti i controller di visualizzazione e le altre classi possano fare riferimento a esso senza dover creare le proprie istanze.

L'utente avrebbe proprietà di sola lettura come:

User.DisplayName = "User1234"
User.ProfileUrl = "http://server.com/profile/121234.png"
User.Points = 12345
User.IAPs = ["removeAds","accountUpgrade"]

Quindi creerò una funzione chiamata User.update() che richiama userdata dal server e popola le proprietà della classe User. Questa è l'unica funzione che è possibile scrivere sulle proprietà dell'utente.

Eseguirò la funzione User.update() in momenti come:

  • Avvio dell'app
  • App riaperta dal sonno
  • Aggiornamento profilo
  • Dopo l'acquisto in-app
  • ecc.

Questo sembra un progetto ragionevole per mantenere i dati del profilo utente locale sincronizzati con il server?

    
posta PeterP 23.12.2016 - 06:15
fonte

2 risposte

1

Poche cose da prendere in considerazione

Nomi delle lettere maiuscole

Then I'd make a function called User.update() that just pulls userdata from the server and populates the User class properties. This is the only function that would be allowed to write over the User properties.

Chiunque abbia familiarità con il modello di progettazione Active Record verrebbe ingannato dal nome del metodo.

Il nome potrebbe farci credere che stiamo apportando modifiche al server, ma in realtà - in base alla domanda - faremmo l'opposto !!!

Se stiamo tirando l'ultima rappresentazione User , dovremmo prendere in considerazione la possibilità di cambiare il nome del metodo per qualcosa come recuperare , aggiornare o ricaricare . Se stiamo veramente sincronizzando, sync sarebbe più accurato di update .

Troppe richieste

I would run the User.update() function during times such as:

  • App launch
  • App re-opened from sleep
  • Profile update
  • After in-app-purchase
  • etc.

Se abbiamo bisogno di riorganizzare il User così spesso, probabilmente significa che non dovremmo mantenere tutto il suo stato. O almeno non completamente. 1

Idealmente, richiediamo i dati più recenti quando c'è una prova di cambiamenti e dobbiamo essere consapevoli di loro. Ad esempio, dopo specifiche operazioni commerciali.

Altrimenti, ci rendiamo conto che qualsiasi evento evento | azione | momento è buono come qualsiasi altro. Tale casualità, alla fine, ci porta a recuperare metà DB senza ragioni coerenti.

Se App re-opened from sleep è un buon momento per aggiornare il User , perché non dovrebbe essere buono per qualsiasi altra entità?

Ricorda che le connessioni consumano risorse e hanno anche un impatto sul piano dati. Quindi, considererei la limitazione delle richieste all'essenziale.

Memorizzazione nella cache solo dell'essenziale

Considera di tenere gli URI al posto della rappresentazione completa. Ad esempio, potremmo richiedere e conservare dati che è improbabile che cambino.

GET /user/1    HTTP/1.1
HTTP 200 OK
{
  "fullname":"Han Solo"
}

Memorizzare nella cache il nome completo e tenere gli URI di tali risorse sensibili ai cambiamenti. Ad esempio, /user/1/profile e /user/1/score .

In seguito, possiamo recuperare queste risorse solo quando l'azienda ha bisogno di esse invece che casualmente dopo determinati eventi dell'applicazione.

Infine, pensa a chi altro cambierà il User accanto all'utente stesso. Se non c'è concorrenza sui dati, probabilmente l'applicazione client ha sempre la rappresentazione più aggiornata.

1: Quello che facciamo con lo storage locale è il caching. Se dobbiamo scadere spesso con la cache, significa che non abbiamo affatto bisogno della cache o stiamo memorizzando nella cache i dati sbagliati.

    
risposta data 03.08.2017 - 18:27
fonte
0

The first idea that comes to mind is to create a class called User. It would be a subclass of NSMutableDictionary.

Questo è un grosso errore. Se la tua classe utente è una sottoclasse di NSMutableDictionary, qualsiasi altro oggetto con un riferimento ad esso può assegnare qualsiasi valore a qualsiasi proprietà che desiderano. Potrebbero persino modificare il tipo di una proprietà o aggiungere nuove proprietà. È una pessima scelta architettonica.

Invece, crea al tuo utente una struttura che abbia le proprietà corrette con i tipi corretti. Quindi crea una classe singleton, chiamata Session che è l'unica fonte di verità per l'oggetto User. Rendi osservabile la sessione (secondo lo schema di Osservatore) in modo che ogni volta che il suo stato cambia, tutti gli osservatori saranno avvisati in modo che possano aggiornare di conseguenza.

potresti eliminare la classe Session e rendere l'utente una classe singleton osservabile, ma questo IMHO dà troppe responsabilità alla classe User.

I would run the User.update() function during times such as:

  • App launch
  • App re-opened from sleep
  • Profile update
  • After in-app-purchase
  • etc.

Ecco un caso d'uso per te. Ho l'app aperta sul mio telefono e sul mio tablet. Apporto le modifiche sul telefono e poi guardo il tablet e aspetto che le modifiche appaiano lì, ma non lo fanno perché non sto facendo nulla sul tablet che potrebbe causare la chiamata alla funzione update() .

Se si desidera veramente mantenere i dati sincronizzati, consultare la configurazione di un server socket che invia i dati al dispositivo ogni volta che si verificano cambiamenti.

    
risposta data 04.07.2017 - 16:26
fonte

Leggi altre domande sui tag