Travailler avec iCloud Stockage de valeurs clés

Garder les données des applications synchronisées sur tous les appareils est une tâche complexe et ardue. Heureusement, c’est précisément pourquoi Apple a construit iCloud. Dans cette série Tuts + Premium, vous apprendrez le fonctionnement de iCloud et comment vos applications peuvent partager des données en toute transparence sur plusieurs appareils..


Aussi disponible dans cette série:

  1. Travailler avec iCloud: Introduction
  2. Travailler avec iCloud: Stockage de valeurs clés
  3. Travailler avec iCloud: Stockage de documents
  4. Travailler avec iCloud: Intégration des données de base

Dans le premier volet de cette série, j'ai présenté une introduction à iCloud et plus particulièrement au stockage iCloud. Deux types de stockage iCloud sont disponibles pour les développeurs, Stockage clé-valeur et Stockage de documents. Le stockage clé-valeur sera au centre de ce tutoriel.

Nous allons commencer ce tutoriel en examinant de plus près le processus de configuration d’une application à utiliser avec iCloud. Avec notre application correctement configurée, nous utiliserons le stockage clé-valeur de iCloud pour maintenir les données de notre application synchronisées sur plusieurs périphériques..


Avant que nous commencions

Nous ne pouvons pas tester la synchronisation des données avec un seul appareil. Pour compléter ce didacticiel, vous devez avoir au moins deux appareils iOS exécutant iOS 5 ou une version ultérieure. Malheureusement, le simulateur iOS ne peut pas être utilisé pour tester iCloud Storage.

L'application que nous sommes sur le point de créer sera une application iOS simple, ce qui signifie que vous pourrez l'exécuter sur n'importe quel iPhone, iPod Touch ou iPad sous iOS 5 ou supérieur. La lecture de ce didacticiel sera toujours utile même si vous n'avez pas deux périphériques iOS distincts à utiliser pour les tests. Il vous apprendra comment iCloud est configuré et comment vous pouvez utiliser le stockage clé-valeur de iCloud pour améliorer vos propres applications..


Étape 1: Configuration du projet

Je commencerai par vous expliquer le processus de configuration de notre application pour utiliser iCloud Storage. Cependant, nous devons d’abord configurer notre projet Xcode.

Créez un nouveau projet dans Xcode en sélectionnant le Application à vue unique modèle. Nommez votre application Nuageux, entrer un identifiant d'entreprise, ensemble iPhone pour la famille d'appareils, et vérifiez Utiliser le comptage automatique des références. Les cases à cocher restantes doivent être décochées. Indiquez à Xcode où vous souhaitez enregistrer votre projet et appuyez sur Créer.



Il est essentiel que vous choisissiez soigneusement le nom du produit et identifiant d'entreprise pour ce projet. La combinaison de ces deux éléments forme la identifiant de paquet (avec l'identifiant de la grappe) de votre application, qu'iCloud utilisera pour identifier votre application de manière unique. Vérifiez soigneusement votre orthographe, car l'identificateur de paquet est sensible à la casse.


Étape 2: Configuration d'iCloud

Comme je l'ai mentionné dans le premier article de cette série Tuts + Premium, la configuration d'une application pour utiliser iCloud est simple et ne nécessite que deux étapes. Laissez-moi vous guider pas à pas dans le processus.

Étape 2A: Portail d'approvisionnement

Ouvrez votre navigateur préféré et rendez-vous sur le centre de développement iOS d'Apple. Connectez-vous à votre compte de développeur iOS et cliquez sur le bouton Portail d'approvisionnement iOS lien à droite.


Premièrement, nous devons créer un ID de l'application pour notre application. Ouvrez le Identifiants d'application onglet à gauche et cliquez sur le Nouvel identifiant d'application bouton en haut à droite. Donnez à votre identifiant d'application un nom descriptif pour l'identifier facilement par la suite. Ensuite, entrez l'identifiant de paquet dont j'ai parlé il y a quelques instants. L'identificateur de paquet est la combinaison de l'identifiant de votre entreprise., com.mobiletuts dans notre exemple, et le nom du produit, Nuageux dans notre exemple. Vous pouvez laisser l’identifiant de grappe défini sur Utiliser l'ID de l'équipe, ce qui convient à notre application.

Vérifiez que votre identifiant de paquet est correctement orthographié. Comme je l'ai mentionné précédemment, l'identifiant bunder est sensible à la casse. Cliquez sur le bouton d'envoi pour créer votre identifiant d'application..


Votre identifiant d'application nouvellement créé doit maintenant figurer dans la liste des identifiants d'application. Vous remarquerez qu'iCloud est désactivé par défaut pour chaque ID d'application nouvellement créé. Changeons cela. Sur la droite de votre identifiant d'application, cliquez sur le bouton Configurer bouton. Au bas de la page, vous devriez voir une case à cocher qui dit Activer pour iCloud. Cochez la case et cliquez Terminé. Notre ID d'application est maintenant configuré pour fonctionner avec iCloud. Il y a encore une chose dont nous devons nous occuper pendant que nous sommes dans la Portail d'approvisionnement.



Pour que notre application puisse s'exécuter sur nos périphériques, nous devons créer un profil d'approvisionnement. Toujours dans le portail de provisioning iOS, ouvrez le Provisioning onglet à gauche et sélectionnez le Développement onglet en haut. Clique le Nouveau profile bouton en haut à droite et entrez un nom descriptif pour votre nouveau profil. Ensuite, sélectionnez le certificat de développement auquel vous souhaitez associer le profil et choisissez le bon identifiant d'application dans la liste déroulante. Enfin, sélectionnez les appareils que vous utiliserez pour les tests dans la liste tout en bas de la page..


Après avoir cliqué sur le bouton d'envoi en bas à droite, vous remarquerez que votre profil d'approvisionnement a le statut en attendant. Après avoir rechargé la page, le statut du profil devrait avoir été mis à jour pour actif. Cliquez sur le bouton de téléchargement en regard de votre profil d'approvisionnement et double-cliquez sur le profil. Xcode installera automatiquement le profil pour vous.



Étape 2B: Droits

De nombreux développeurs rechignent lorsqu'ils entendent le mot droits. Les droits ne sont pas effrayants une fois que vous comprenez à quoi ils servent. Les droits accordent des fonctionnalités spécifiques ou des autorisations de sécurité à une application. C'est tout ce qu'il y a à faire. Il s'agit d'une simple liste de paires clé-valeur indiquant au système d'exploitation ce que votre application peut ou ne peut pas faire, et quelles applications ont accès aux données de votre application. Ce dernier est particulièrement important lorsque vous travaillez avec iCloud.

Dans notre exemple, les droits d'accès iCloud nous permettent d'activer iCloud Storage pour notre application. Pour configurer les droits de notre application, nous allons dans l'éditeur de cible de Xcode.

Cliquez notre projet dans le Navigateur de projet et sélectionnez notre cible dans la liste des cibles. Avec le Résumé onglet sélectionné, vous devriez voir une section nommée Les droits au fond. Cochez la première case pour activer les droits pour notre application. Cette option créera un fichier de droits pour notre application. Le champ de texte situé sous la case à cocher doit être pré-rempli pour vous. Nous avons maintenant la possibilité d'activer le stockage clé-valeur iCloud et le stockage de documents iCloud.


Dans ce tutoriel, je ne parlerai que de iCloud Key-Value Storage. Cochez la case en regard de iCloud Key-Value Store. Encore une fois, Xcode pré-remplit le champ de texte situé en regard de la case à cocher avec l'identifiant de l'ensemble d'applications (sans l'identifiant d'origine de l'ensemble). Vérifiez que cet identifiant de bundle correspond à celui que vous avez entré dans le portail de provisioning lors de la création de votre ID d'application. Je parlerai des conteneurs iCloud dans le prochain tutoriel en ce qui concerne iCloud Document Storage.

Au bas de la section Droits, vous voyez Groupes d’accès au trousseau. Cette liste spécifie quelles applications ont accès aux éléments de votre trousseau d'applications. Vous pouvez laisser cette section intacte pour l'instant.

Avant de nous salir les mains avec les API iCloud, nous devons configurer nos paramètres de construction. Toujours dans l'éditeur de cible de Xcode, sélectionnez le Paramètres de construction onglet et faites défiler jusqu'à la Code de signature section. Définir l’identité de signature de code pour le Déboguer et Libération configurations pour correspondre au profil que nous venons de créer dans le Portail d'approvisionnement iOS.



Étape 3: Interface utilisateur

Ce tutoriel est quelque peu avancé et je suppose donc que vous connaissez les concepts de base du développement iOS. Cela signifie que je vais avancer un peu plus vite que d'habitude, car nous avons beaucoup de terrain à parcourir..

L'application que nous sommes sur le point de créer sera un simple gestionnaire de marque-pages. Nous pouvons ajouter et supprimer des favoris, et ceux-ci seront synchronisés sur tous nos appareils. À quel point cela est cool? Commençons.

Ouvrez le fichier d'en-tête de notre contrôleur de vue et créez une variable d'instance (ivar) de type NSMutableArray avec un nom de signets. L'ivar stockera nos marque-pages. Les signets seront affichés dans un tableau. Créez une sortie pour la vue table dans le fichier d'en-tête de notre contrôleur de vue et assurez-vous de la conformité de notre contrôleur de vue avec la source de données de la vue et les protocoles de délégation. De plus, n'oubliez pas de synthétiser des accesseurs pour les deux propriétés dans le fichier d'implémentation de notre contrôleur de vue. Ensuite, ajoutez deux actions à ViewController.h, editBookmarks: et ajouter un marque-page:. Prêt? Dirigez-vous vers le ViewController.xib fichier pour tout câbler.

 #importation  @interface ViewController: UIViewController  NSMutableArray * _bookmarks; __weak UITableView * _tableView;  @property (nonatomic, strong) signets NSMutableArray *; @property (nonatomic, faible) IBOutlet UITableView * tableView; - (IBAction) editBookmarks: expéditeur (id); - (IBAction) addBookmark: expéditeur (id); @fin

Commencez par faire glisser une barre de navigation sur la vue de notre contrôleur de vue et positionnez-la tout en haut. Faites glisser une instance de UIBarButtonItem à gauche de la barre de navigation et définir son identifiant dans le Inspecteur d'attributs à modifier. Contrôle glisser du bouton d'édition à notre Propriétaire du fichier et sélectionnez le editBookmarks: méthode. Faites glisser un deuxième bouton à la droite de la barre de navigation et attribuez-lui un identifiant de Ajouter. Contrôle glisser depuis le bouton Ajouter à notre Propriétaire du fichier et sélectionnez le ajouter un marque-page: méthode. Enfin, faites glisser une instance de UITableView à la vue de notre contrôleur et connectez sa source de données et déléguer des points de vente à la Propriétaire du fichier objet. Terminé.


La mise en œuvre des protocoles de source de données et de délégation de notre vue table est simple et directe. dans le numberOfSectionsInTableView: méthode, nous vérifions si notre source de données, c’est-à-dire nos signets, n’est pas nulle. S'il est nul, nous retournons 1. Si ce n'est pas le cas, nous retournons 0. Le tableView: numberOfRowsInSection: méthode est presque identique. Au lieu de cela, si notre source de données n'est pas nulle, nous renvoyons le nombre d'éléments qu'elle contient. Si notre source de données est nulle, nous retournons 0.

 - (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView if (self.bookmarks) return 1;  else retour 0;  - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section if (! Self.bookmarks) return 0;  else return self.bookmarks.count; 

dans le tableView: cellForRowAtIndexPath: méthode, nous commençons par déclarer un identifiant de cellule statique dans le but de le réutiliser, puis nous demandons à la vue tableau une cellule réutilisable avec l'identifiant de cellule que nous venons de déclarer. Si une cellule réutilisable n'a pas été renvoyée, nous initialisons une nouvelle cellule avec un style de UITableViewCellStyleSubtitle et nous passons notre identifiant de cellule pour la réutilisation des cellules. Ensuite, nous allons chercher le bon signet dans la source de données. Chaque signet sera un dictionnaire avec deux paires clé-valeur, un prénom et un URL. Nous configurons la cellule en définissant son étiquette et son étiquette de détail avec le nom et l'url du signet, respectivement..

 - (UITableViewCell *) tableView: (UITableView *) aTableView cellForRowAtIndexPath: (NSIndexPath *) indexPath statique NSString * CellIdentifier = @ "Identificateur de cellule"; UITableViewCell * cell = [aTableView dequeueReusableCellWithIdentifier: CellIdentifier]; if (cell == nil) cell = [[UITableViewCell alloc]] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: CellIdentifier];  // Récupérer le signet NSDictionary * bookmark = [self.bookmarks objectAtIndex: indexPath.row]; // Configurer la cellule cell.textLabel.text = [bookmark objectForKey: @ "name"]; cell.detailTextLabel.text = [bookmark objectForKey: @ "url"]; cellule de retour; 

L'utilisateur a également la possibilité de modifier ses favoris. dans le tableView: canEditRowAtIndexPath: méthode on retourne OUI. le tableView: commitEditingStyle: forRowAtIndexPath: est légèrement plus complexe. Commençons par vérifier que le style d'édition de la cellule est égal à UITableViewCellEditingStyleDelete, c'est-à-dire qu'un signet a été supprimé. Tout d'abord, nous mettons à jour notre source de données en supprimant le signet du tableau de signets. Nous sauvegardons ensuite la source de données en envoyant à notre contrôleur de vue une saveBookmarks message et nous mettons enfin à jour la vue de table pour refléter les modifications apportées à la source de données.

 - (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath return YES;  - (void) tableView: (UITableView *) aTableView commitEditingStyle: (UITHViewViewCellEditingStyle) // Enregistrer les favoris [self saveBookmarks]; // Mise à jour de la vue de table [aTableView deleteRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationFade]; 

Jetons un coup d'oeil à nos actions maintenant. le editBookmarks: la méthode ne pourrait pas être plus facile. Nous basculons l'état d'édition de la vue table de manière animée.

 - (IBAction) editBookmarks: (id) expéditeur [self.tableView setEditing:! Self.tableView.editing animé: YES]; 

le ajouter un marque-page: Cette méthode nécessite un peu plus de travail. Nous initialisons une nouvelle instance de AddBookmarkViewController, un contrôleur de vue que nous allons créer prochainement, et nous définissons sa propriété de contrôleur de vue sur soi. Nous présentons ensuite le contrôleur de vue nouvellement créé sous forme modale. Comme son nom l'indique, AddBookmarkViewController est en charge de la création de nouveaux marque-pages. Regardons de plus près AddBookmarkViewController.

 - (IBAction) addBookmark: (id) expéditeur // Initialise Add Bookmark View Controller. Contrôleur AddBookmarkViewController * vc = [[AddBookmarkViewController alloc] initWithNibName: @, ensemble "AddBookmarkViewController": [NSBundle mainBundle]]; vc.viewController = self; // Present View Controller Modally [auto presentViewController: vc animé: YES complétion: nil]; 

Étape 4: Ajout de signets

L'implémentation de AddBookmarkViewController est très simple, donc je n’entrerai pas dans les détails. Le contrôleur de vue a une référence faible à notre contrôleur de vue principal. Cela lui permet de notifier notre contrôleur de vue principal lorsqu'un nouveau signet a été créé. Il a aussi deux sorties de type UITextField, qui permet à l'utilisateur d'entrer un nom et une URL pour chaque signet.

 #importation  @class ViewController; @interface AddBookmarkViewController: UIViewController __weak ViewController * _viewController; __weak UITextField * _nameField; __weak UITextField * _urlField;  @property (nonatomic, faible) ViewController * viewController; @property (nonatomic, faible) IBOutlet UITextField * nameField; @property (nonatomic, faible) IBOutlet UITextField * urlField; @fin

Le fichier XIB contient une barre de navigation en haut avec un Annuler et un enregistrer bouton. La vue elle-même contient les champs Nom et URL que je viens de mentionner. Les boutons annuler et enregistrer sont connectés à un Annuler: et un enregistrer: action, respectivement. le Annuler: action rejette simplement notre contrôleur de vue modale. le enregistrer: l'action est tout aussi simple. Nous créons un nouveau signet (c’est-à-dire une instance de NSDictionary) avec les données que l'utilisateur a entrées dans les champs de texte et informez notre contrôleur de la vue principale du nouveau signet. Il est important de noter que ce n’est pas la meilleure solution pour informer notre contrôleur de vue principal quand un nouveau signet a été créé par notre AddBookmarkViewController. Cette approche introduit un couplage étroit, ce qui devrait être évité autant que possible. Une meilleure approche serait d’adopter le modèle de délégation.


 - (IBAction) annuler: (id) expéditeur [auto-licenciement ViewControllerAnimated: YES complétion: nil];  - (IBAction) save: (id) expéditeur NSString * name = self.nameField.text; NSString * url = self.urlField.text; NSDictionary * bookmark = [[NSDictionary alloc] initWithObjectsAndKeys: nom, @ "nom", url, @ "url", nil]; [self.viewController saveBookmark: signet]; [auto-licenciement ViewControllerAnimated: YES complétion: nil]; 

Nous sommes presque prêts, mais nous avons encore besoin de mettre en œuvre cela saveBookmark: méthode dans notre contrôleur de vue principale. Commencez par déclarer cette méthode dans le fichier d'en-tête de notre contrôleur de vue, puis passez à son fichier d'implémentation. La mise en œuvre est minimale. Nous ajoutons le signet nouvellement créé à notre source de données, nous enregistrons la source de données, puis nous rechargeons la vue tabulaire pour afficher le signet que nous venons d'ajouter..

 - (void) saveBookmark: (NSDictionary *) bookmark // Ajouter un signet à un signet [self.bookmarks addObject: bookmark]; // Enregistrer les favoris [self saveBookmarks]; // Reload Table View [self.tableView reloadData]; 

Étape 5: Chargement et enregistrement

Notre application n'est pas très utile si les signets de l'utilisateur ne sont pas enregistrés sur le disque. L'utilisateur perdrait ses signets chaque fois que l'application se ferme. Mauvaise expérience utilisateur. Corrigeons cela.

Dans notre viewDidLoad: méthode, nous envoyons à notre contrôleur de vue un loadBookmarks message. Jetons un coup d'oeil au loadBookmarks méthode. Nous allons stocker les signets de l'utilisateur dans la base de données utilisateur par défaut. Nous vérifions d’abord s'il y a déjà une entrée dans la base de données par défaut de l'utilisateur avec la clé signets. Si tel est le cas, nous initialisons nos signets avec le contenu de l'objet stocké. Si ce n'est pas le cas, nous initialisons nos signets avec un tableau mutable vide et stockons ce tableau dans la base de données par défaut de l'utilisateur. Simple. Droite?

 - (void) viewDidLoad [super viewDidLoad]; // Charger les marque-pages [self loadBookmarks]; 
 - (void) loadBookmarks NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; if ([ud objectForKey: @ "bookmarks"]! = nil) // Charger la copie locale self.bookmarks = [NSMutableArray arrayWithArray: [ud objectForKey: @ "bookmarks"]];  else // Initialiser les signets self.bookmarks = [[NSMutableArray alloc] init]; // Enregistrer la copie locale [ud setObject: self.bookmarks forKey: @ "bookmarks"]; 

L'enregistrement des signets est encore plus simple. Nous stockons notre objet de marque-pages dans la base de données par défaut de l'utilisateur à l'aide de la clé signets. C'est tout ce qu'on peut en dire.

 - (void) saveBookmarks NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; 

C'était un peu de travail. Vous pouvez maintenant construire et exécuter votre application. Vous devriez pouvoir ajouter des signets et en supprimer. Les signets sont enregistrés sur le disque afin que vous ne perdiez aucune donnée lorsque vous quittez l'application..


Étape 6: Synchroniser les signets

Pour rendre notre application vraiment brillante, nous utiliserons iCloud pour garder nos signets synchronisés sur nos appareils. Cela va vous surprendre à quel point c'est facile. Comme je l’ai mentionné dans le didacticiel précédent de cette série, le stockage clé-valeur de iCloud fonctionne comme NSUserDefaults, c'est-à-dire qu'il stocke les paires clé-valeur. Dans la terminologie iCloud, le magasin est nommé NSUbiquitousKeyValueStore. Commençons par enregistrer nos signets non seulement localement, mais également sur iCloud.

Rendez-vous sur notre saveBookmarks: méthode et modifier notre méthode pour ressembler à celle ci-dessous. Nous commençons par chercher une référence au magasin par défaut en appelant defaultStore sur le NSUbiquitousKeyValueStore classe. Encore une fois, cela ressemble beaucoup à NSUserDefaults. Si notre référence au magasin n'est pas nulle, nous stockons notre objet de signets dans le magasin avec la même clé que nous avons utilisée pour stocker nos signets dans la base de données par défaut de l'utilisateur. Enfin, nous synchronisons le magasin.

 - (void) saveBookmarks // Sauvegarder une copie locale NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; // Enregistrer dans iCloud NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; if (store! = nil) [store setObject: self.bookmarks forKey: @ "bookmarks"]; [magasin synchroniser]; 

Appel synchroniser sur l'instance de magasin synchronise les clés et les valeurs en mémoire avec celles enregistrées sur le disque. Vous pensez peut-être que cette méthode force l'envoi de nouvelles paires clé-valeur à iCloud, mais ce n'est pas le cas. En enregistrant les clés en mémoire sur le disque, iCloud est informé que de nouvelles paires clé-valeur sont disponibles pour la synchronisation. Cependant, c'est le système d'exploitation qui décide en dernier ressort quand il convient de synchroniser les paires clé-valeur récemment ajoutées avec iCloud. Ceci est important à garder à l'esprit et c'est aussi la raison pour laquelle les modifications apportées sur un périphérique ne seront pas immédiatement visibles sur un autre périphérique.

En outre, même si nous avons appelé le synchronisé méthode sur l'instance de magasin, ce n'est pas nécessaire dans la plupart des situations. Le système d'exploitation le fait pour vous aux moments appropriés. Saviez-vous que NSUserDefaults a un synchroniser méthode aussi bien qui fonctionne presque à l'identique?

Vous vous demandez peut-être comment notre application sait quand un autre appareil a mis à jour le magasin Key-Value dans iCloud et comment il peut intégrer ces modifications. C'est une très bonne question et c'est la dernière pièce du puzzle..

Chaque fois que le magasin de valeurs de clé a été modifié, une notification est envoyée et notre application peut s'inscrire en tant qu'obeserver pour ces notifications. Il est important de vous inscrire à ces notifications le plus tôt possible dans le cycle de vie de votre application..

Voyons comment cela fonctionne. Dans notre viewDidLoad méthode nous faisons quatre choses. Premièrement, nous obtenons une référence au magasin Key-Value. Deuxièmement, nous ajoutons notre contrôleur de vue en tant qu’observateur de toute notification portant le nom NSUbiquitousKeyValueStoreDidChangeExternallyNotification envoyé par le magasin Key-Value. Lorsque nous recevrons une telle notification, nous la traiterons dans notre updateKeyValuePairs: méthode (que nous écrirons dans un instant). Ensuite, nous envoyons au magasin un message de synchroniser. Enfin, nous chargeons nos marque-pages comme avant..

 - (void) viewDidLoad [super viewDidLoad]; NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; [[NSNotificationCenter defaultCenter] addObserver: sélecteur automatique: @selector (updateKeyValuePairs :) nom: NSUbiquitousKeyValueStoreDidChangeExternallyNotification objet: store]; // Synchronize Store [store synchronize]; // Charger les marque-pages [self loadBookmarks]; 

Tout ce qui nous reste à faire est de mettre en œuvre le updateKeyValuePairs: méthode. Faisons-le maintenant. La notification informations utilisateur dictionnaire contient deux paires clé-valeur importantes, (1) le raison pourquoi la notification a été envoyée et (2) la clés dans le magasin de valeurs-clés dont les valeurs ont été changées. Nous commençons par examiner de plus près la raison de la notification. Nous nous assurons d'abord qu'une raison a été spécifiée et retournons si aucune n'a été spécifiée. Si une raison a bien été spécifiée, nous ne poursuivrons que si la raison était soit un changement sur le serveur (NSUbiquitousKeyValueStoreServerChange) ou des modifications locales ont été ignorées en raison d’une première synchronisation avec le serveur (NSUbiquitousKeyValueStoreInitialSyncChange). Si l'un ou l'autre de ces critères est rempli, nous extrayons le tableau des clés qui ont été modifiées et nous parcourons les clés pour voir si notre clé de marque-pages figure parmi elles. Si tel est le cas, nous prenons la valeur associée à la clé et mettons à jour notre source de données ainsi que la base de données par défaut de l'utilisateur avec cette valeur. Enfin, nous rechargeons la vue tableau pour refléter les changements.

 - (void) updateKeyValuePairs: (NSNotification *) notification NSDictionary * userInfo = [notification userInfo]; NSNumber * changeReason = [userInfo objectForKey: NSUbiquitousKeyValueStoreChangeReasonKey]; NSInteger raison = -1; // Une raison est-elle spécifiée? if (! changeReason) return;  else reason = [changeReason integerValue];  // Procéder si la raison était (1) Changements sur le serveur ou (2) Sync initiale si ((raison == NSUbiquitousKeyValueStoreServerChange) || (raison == NSUbiquitousKeyValueStitialSyncChange)) NSUbiquitousKeyValueStore * store = [NSUbiquitousKeyValueStore defaultStore]; // Clés de recherche pour les "signets" Clé pour (clé NSString * dans les clés modifiées) if ([clé estEqualToString: @ "signets"]) // Mettre à jour la source de données self.bookmarks = [NSMutableArray arrayWithArray: [store objectForKey: key] ]; // Enregistrer la copie locale NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; [ud setObject: self.bookmarks forKey: @ "bookmarks"]; // Reload Table View [self.tableView reloadData]; 

Deux points nécessitent une attention particulière. Tout d'abord, comme nous l'avons vu lors de la mise en œuvre de updateKeyValuePairs:, nous recevons un tableau contenant toutes les clés du magasin de valeurs clés avec les valeurs modifiées. Il s'agit d'une optimisation pour éviter à iCloud d'avoir à envoyer une notification pour chaque paire clé-valeur modifiée. Deuxièmement, il est vivement recommandé de stocker localement les données du magasin Key-Value Store. La base de données par défaut des utilisateurs est bien adaptée à cet usage, mais vous êtes libre de choisir la solution qui correspond à vos besoins. La raison pour stocker une copie locale est de ne pas compter sur iCloud pour le stockage des données. Tous les utilisateurs ne disposeront pas d'un compte iCloud ou l'activation d'iCloud sur leur appareil..

Avec cette dernière pièce de code en place, notre application est maintenant compatible avec iCloud. Générez et exécutez votre application sur deux périphériques et testez-la vous-même. Notez que les modifications ne sont pas instantanées. Les modifications doivent être synchronisées avec les serveurs iCloud, puis envoyées aux périphériques appropriés nécessitant une mise à jour..

Même si ce tutoriel est long, la mise en œuvre de iCloud Key-Value Storage ne nécessitait pas beaucoup de code supplémentaire. Comme je l'ai écrit dans le précédent tutoriel, l'adoption de Key-Value Storage est simple, elle nécessite très peu de temps système..


Conclusion

Avant de terminer ce didacticiel, je tiens à rappeler les avantages et les inconvénients d’iCloud Key-Value Storage, car il est important de les garder à l’esprit. Les avantages sont évidents maintenant, il est facile à adopter, rapide à mettre en œuvre, et cela ressemble beaucoup à la façon dont NSUserDefaults travaux. Cependant, il est également important de garder les inconvénients à l'esprit. Les paires clé-valeur sont ce qu'elles sont. C’est-à-dire des paires simples sans aucune forme de traitement des conflits, sauf si vous implémentez votre propre logique de traitement des conflits. Ce dernier n'est pas recommandé car Key-Value Storage n'a pas été construit dans cet esprit. Le stockage de documents fournit une prise en charge intégrée des conflits et constitue donc une b