CocoaHeads Lyon - Mode Déconnecté dans une app iOS

Preview:

DESCRIPTION

Présentation du 14/11/2013 à CocoaHeads Lyon. Comment faire une application qui fonctionne hors connexion ? Le code des exemples est sur github : https://github.com/creynaud/notes-iphone-app https://github.com/creynaud/notes-server Le post de blog (en anglais) : https://www.clairereynaud.net/blog/adding-offline-mode-to-your-mobile-app/

Citation preview

LET'S TAKE THIS OFFLINEComment faire une application qui fonctionne hors connexion ?

www.babelbytes.com

@ClaireReynaud

Et vous ?

Sujet de cette présentationDes méthodes pour implémenter des applicationsen mode déconnectéExemples:

iOSREST APIDjango REST Framework

Le code de la démohttps://github.com/creynaud/notes-iphone-apphttps://github.com/creynaud/notes-serverhttps://awesomenotes.herokuapp.com/api/

Qu'est-ce que j'entendspar "fonctionner en mode

déconnecté" ?

Photo by Danka PeterPas de réseau ou un réseau lent

Photo by James EvansPas de réseau ou un réseau lent

Pas de réseau ou un réseau lent

Un utilisateur ne devrait pas attendrepour relire du contenu auquel il a déjà

accédé

Pas de réseau ou un réseau lent

Un utilisateur devrait pouvoir poster ducontenu à tout moment

Pourquoi implémenter unmode déconnecté ?

L'application Facebook il y a un an

Pas vraiment l'expérienceutilisateur qu'on souhaite

avoir...

On s'attend à toujours voir du contenu

Les réseaux mobiles sont différentsLa latence est élevéeLa vitesse est très variable, ce qui est le pire enterme d'expérience utilisateur"Faster Websites: Crash Course on FrontendPerformance (Part 1/2)", Devoxx 2012

Comment se comporte mon appen conditions réelles ?

Et si on réimplémentaitEvernote ?

Enfin, juste la partie notes de texte ;)

En 3 étapesLire des notes en mode déconnecté1.Créer des notes en mode déconnecté2.Mettre à jour des notes en mode déconnecté etrésoudre des conflits

3.

Une seule chose àretenir : versioner les

objets notes !

Architecture d'une application mobile

REST APIGET /notesGET /notes/{uuid}POST /notesPUT /notes/{uuid}DELETE /notes/{uuid}

1. Lire des notes en modedéconnecté

Photo by Ilham Rahmansyah

Lire des notes en mode déconnecté

Lire les documents JSON depuis uncache local côté client

HTTP a un mécanismede cache, non ?

On a besoin d'un cache de plus hautniveau

Si on veut faire des recherches en mode déconnectéOu si on veut faire de l'édition en mode déconnectéJ'ai choisi d'utiliser CoreData au-dessus de SQLitepour mon app d'exemple.Selon les besoins, stocker le document JSON "brut"dans un store clé/valeur peut suffir.

Qu'est-ce qu'on garde du caching HTTP ?Par exemple, je ne veux pas télécharger la même versiond'un document JSON si elle est déjà dans mon cacheHTTP.C'est possible avec les headers HTTP suivants :

Cache-ControlEtag et If-None-Matchou Last-Modified et If-Modified-Since

Le cache HTTP, enpratique, ça donne quoi ?

Cache HTTP GET avec ETAG

Article de blog sur NSURLCache, les politiques de cacheHTTP et les ETAG

2. Créer des notes enmode déconnecté

Photo by Ilham Rahmansyah

Créer des notes en mode déconnectéStocker le document JSON qui doit être posté (parexemple dans SQLite)

1.

Essayer de poster le document JSON vers le serveren tâche de fond

2.

Marquer le document JSON comme posté avecsuccès seulement si le POST retourne OK

3.

En cas d'échec du POST, essayer à nouveau deposter le document JSON à la prochainesynchronization avec le serveur

4.

3. Résoudre des conflitslors de l'édition de notes

Photo by Ilham Rahmansyah

Résoudre des conflits lors de l'éditionSi vous laissez la possibilité à l'utilisateur d'éditer enmode déconnecté, des conflits vont se produire (mêmes'il n'y a pas d'édition multi-utilisateur).

La détection de conflitdevrait être intégrée à

l'API REST !

La *détection*, pas la*résolution*

Ça donne quoi dansl'API REST ?

Et la synchronisation dansl'application ?

Deux mots sur le back-end et l'API REST

REST APIGET /notes-uuidsGET /notesGET /notes/{uuid}POST /notesPUT /notes/{uuid}DELETE /notes/{uuid}

Django REST frameworkAjouter un UUID et une révision dans les objets NoteRejeter les requêtes PUT ou DELETE si la révisionn'est pas spécifiée (400 Bad request)Rejeter les requêtes PUT ou DELETE si la révisionn'est pas la révision courante (409 Conflict)Ajouter le header ETAGTout le reste est déjà fourni !https://github.com/creynaud/notes-server

RésuméAjouter un UUID et une révision dans tous lesdocuments JSONLecture hors connexion: stocker les documents JSONen local côté clientCréation hors connexion: poster vers le serveur enbackground et re-essayer en cas d'échecMise à jour hors connexion: gérer les conflitsEssayer de tirer profit du cache HTTP (headersCache-Control, Etag et If-None-Match)

Merci ! Questions ?