Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. CloudKit
Code

Création d'une application de liste d'achats avec CloudKit: ajout de relations

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Building a Shopping List Application With CloudKit.
Building a Shopping List Application With CloudKit: Adding Records
Building a Shopping List Application With CloudKit: Sharing Shopping Items

French (Français) translation by Soleil (you can also view the original English article)

Dans le tutoriel précédent de cette série, nous avons ajouté la possibilité d’ajouter, de mettre à jour et de supprimer des listes de courses. Une liste de courses sans aucun élément n'est pas très utile. Dans ce tutoriel, nous ajouterons la possibilité d'ajouter, de mettre à jour et de supprimer des éléments d'une liste d'achats. Cela signifie que nous allons travailler avec des références et la classe CKReference.

Nous allons également examiner de plus près le modèle de données de l'application de liste d'achats. Est-il facile d'apporter des modifications au modèle de données et comment l'application répond-elle aux modifications apportées dans le CloudKit Dashboard?

Conditions préalables

Rappelez-vous que je vais utiliser Xcode 7 et Swift 2. Si vous utilisez une ancienne version de Xcode, gardez à l'esprit que vous utilisez une version différente du langage de programmation Swift.

Dans ce tutoriel, nous continuerons là où nous l'avions laissé dans le deuxième tutoriel de cette série. Vous pouvez télécharger ou cloner le projet depuis GitHub.

1. Détails de la liste d'achats

Actuellement, l'utilisateur peut modifier le nom d'une liste de courses en appuyant sur l'indicateur de divulgation détaillée, mais l'utilisateur doit également pouvoir voir le contenu d'une liste de courses en tapant sur une dans le contrôleur de vue des listes. Pour que cela fonctionne, nous avons d'abord besoin d'une nouvelle sous-classe UIViewController.

Étape 1: Création de ListViewController

La classe ListViewController affiche le contenu d'une liste d'achats dans une vue de table. L'interface de la classe ListViewController ressemble à celle de la classe ListsViewController. Nous importons les frameworks CloudKit et SVProgressHUD et conformons la classe aux protocoles UITableViewDataSource et UITableViewDelegate. Comme nous utiliserons une vue de table, nous déclarons une constante, ItemCell, qui servira d'identificateur de réutilisation de cellule.

Nous déclarons trois sorties, messageLabel de type UILabel !, tableView de type UITableView !, et activityIndicatorView de type UIActivityIndicatorView !. Le contrôleur de vue liste conserve une référence à la liste d'achats qu'il affiche dans la propriété de list, qui est de type CKRecord !. Les éléments de la liste d'achats sont stockés dans la propriété items, qui est de type [CKRecord]. Enfin, nous utilisons une variable d’aide, la selection, pour savoir quel élément de la liste de courses a été sélectionné par l’utilisateur. Cela apparaîtra plus tard dans ce tutoriel.

Étape 2: Création de l'interface utilisateur

Ouvrez Main.storyboard, ajoutez un contrôleur de vue et définissez sa classe sur ListViewController dans Identity Inspector. Sélectionnez la cellule prototype du contrôleur de vue de liste, appuyez sur la touche de contrôle et faites glisser la cellule prototype vers le contrôleur de vue de liste. Choisissez Show dans le menu qui apparaît et définissez l'identifiant sur List dans Attributes Inspector.

Ajoutez une vue de table, une étiquette et une vue d'indicateur d'activité à la vue du contrôleur de vue. N'oubliez pas de câbler les prises du contrôleur de vue ainsi que celles de la vue tableau.

Sélectionnez la vue de table et définissez Prototype Cells sur 1 dans Attributes Inspector. Sélectionnez la cellule prototype, définissez Style sur RightDetail, Identifier sur ItemCell et Accessory to Disclosure Indicator. C'est ce à quoi devrait ressembler le contrôleur de vue lorsque vous avez terminé.

List View Controller

Étape 3: Configuration de View Controller

Avant de revoir le framework CloudKit, nous devons préparer le contrôleur de vue pour les données qu'il va recevoir. Commencez par mettre à jour l'implémentation de viewDidLoad. Nous définissons le titre du contrôleur de vue sur le nom de la liste d'achats et appelons deux méthodes d'assistance, setupView et fetchItems.

La méthode setupView est identique à celle implémentée dans la classe ListsViewController.

Pendant que nous y sommes, implémentons également une autre méthode d'assistance familière, updateView. Dans updateView, nous mettons à jour l'interface utilisateur du contrôleur de vue en fonction des éléments stockés dans la propriété items.

Je vais laisser fetchItems vide pour le moment. Nous reviendrons sur cette méthode une fois que nous aurons fini de configurer le contrôleur de vue liste.

Étape 4: Méthodes de source de données de vue de table

Nous sommes presque prêts à prendre l'application pour un autre test. Avant cela, nous devons implémenter le protocole UITableViewDataSource. Si vous avez lu les versions précédentes de cette série, l'implémentation vous sera familière.

Étape 5: Gestion de la sélection

Pour tout lier, nous devons revoir la classe ListsViewController. Commencez par implémenter la méthode tableView(_:didSelectRowAtIndexPath:) du protocole UITableViewDelegate.

Nous devons également mettre à jour prepareForSegue (segue:sender:) pour gérer le seguer que nous avons créé il y a quelques instants. Cela signifie que nous devons ajouter un nouveau case à l'instruction switch.

Pour satisfaire le compilateur, nous devons également déclarer la constante SegueList en haut de ListsViewController.swift.

Générez et exécutez l'application pour voir si tout est correctement connecté. Comme nous n'avons pas encore implémenté la méthode fetchItems, aucun élément ne sera affiché. C'est quelque chose que nous devons corriger.

2. Récupération d'articles

Étape 1: Créer un type d'enregistrement

Avant de pouvoir récupérer des éléments du backend CloudKit, nous devons créer un nouveau type d'enregistrement dans le CloudKit Dashboard. Accédez au tableau de bord CloudKit, créez un nouveau type d'enregistrement et nommez-le Items. Chaque élément doit avoir un nom, créez un nouveau champ, définissez le nom du champ sur name et définissez le type de champ sur String.

Chaque article doit également savoir à quelle liste de courses il appartient. Cela signifie que chaque article nécessite une référence à sa liste d'achats. Créez un nouveau champ, définissez le nom du champ sur list et définissez le type de champ sur Reference. Le type de champ Reference a été conçu à cette fin, en gérant les relations.

Item Record Type

Revenez à Xcode, ouvrez ListsViewController.swift et déclarez une nouvelle constante en haut pour le type d'enregistrement Items.

Étape 2: Récupération d'éléments

Ouvrez ListViewController.swift et accédez à la méthode fetchItems. L'implémentation est similaire à la méthode fetchLists de la classe ListsViewController. Il y a cependant une différence importante.

La différence entre fetchItems et fetchLists est le prédicat que nous transmettons à l'initialiseur CKQuery. Nous ne sommes pas intéressés par chaque élément de la base de données privée de l'utilisateur. Nous nous intéressons uniquement aux éléments associés à une liste de courses particulière. Cela se reflète dans le prédicat de l'instance CKQuery.

Nous créons le prédicat en transmettant une instance de CKReference, que nous créons en invoquant init(recordID:action:). Cette méthode accepte deux arguments, une instance CKRecordID qui référence l'enregistrement de liste d'achats et une instance CKReferenceAction qui détermine ce qui se produit lorsque la liste d'achats est supprimée.

Les actions de référence sont très similaires aux règles de suppression des données de base. Si l'objet référencé, la liste d'achats de cet exemple, est supprimé, l'infrastructure CloudKit inspecte l'action de référence pour déterminer ce qui doit arriver aux enregistrements contenant une référence à l'enregistrement supprimé. L'énumération CKReferenceAction a deux valeurs de membre:

  • None: Si la référence est supprimée, rien ne se produit dans les enregistrements faisant référence à l'enregistrement supprimé.
  • DeleteSelf: Si la référence est supprimée, chaque enregistrement faisant référence à l'enregistrement supprimé est également supprimé.

Comme aucun élément ne doit exister sans une liste d'achats, nous définissons l'action de référence sur DeleteSelf.

La méthode processResponseForQuery(records: error:) ne contient rien de nouveau. Nous traitons la réponse de la requête et mettons à jour l'interface utilisateur en conséquence.

Créez et exécutez l'application. Vous ne verrez aucun élément pour le moment, mais l'interface utilisateur devrait mettre à jour que la liste d'achats est vide.

3. Ajouter des articles

Étape 1: Création de AddItemViewControler

Il est temps d'implémenter la possibilité d'ajouter des éléments à une liste d'achats. Commencez par créer une nouvelle sous-classe UIViewController, AddItemViewController. L'interface du contrôleur de vue est similaire à celle de la classe AddListViewController.

En haut, nous importons les frameworks CloudKit et SVProgressHUD. Nous déclarons le protocole AddItemViewControllerDelegate, qui servira le même objectif que le protocole AddListViewControllerDelegate. Le protocole définit deux méthodes, l'une pour l'ajout d'éléments et l'autre pour la mise à jour des éléments.

Nous déclarons deux points de vente, un champ de texte et un élément de bouton de barre. Nous déclarons également une propriété pour le délégué et une variable d'assistance, newItem, qui nous aide à déterminer si nous créons un nouvel élément ou mettons à jour un élément existant. Enfin, nous déclarons une propriété list pour référencer la liste d'achats à laquelle l'élément sera ajouté et un élément de propriété pour l'item que nous créons ou mettons à jour.

Avant de créer l'interface utilisateur, implémentons deux actions dont nous aurons besoin dans le storyboard, cancel(_:) etsave(_:). Nous mettrons à jour l'implémentation de l'action save(_:) plus tard dans ce tutoriel.

Étape 2: Création de l'interface utilisateur

Ouvrez Main.storyboard, ajoutez un élément de bouton de barre à la barre de navigation du contrôleur de vue de liste et définissez System Item sur Add dans Attributes Inspector. Faites glisser un contrôleur de vue depuis Object Library et définissez sa classe sur AddItemViewController. Créez un point entre l'élément de bouton de la barre que nous venons de créer et le contrôleur de vue d'élément ajouté. Choisissez Show dans le menu qui apparaît et définissez l'identificateur du lieu sur ItemDetail.

Ajoutez deux éléments de bouton de barre à la barre de navigation du contrôleur de vue d'ajout d'élément, un bouton d'annulation à gauche et un bouton de sauvegarde à droite. Connectez chaque élément du bouton de barre à l'action correspondante. Ajoutez un champ de texte à la vue du contrôleur de vue et n'oubliez pas de connecter les prises du contrôleur de vue. Voici à quoi devrait ressembler le contrôleur d'affichage des éléments lorsque vous avez terminé.

Add Item View Controller

Étape 3: Configuration de View Controller

L'implémentation du contrôleur de vue d'élément ajouté ne contient rien que nous n'avons pas encore couvert. Il y a une exception, cependant, dont nous discuterons dans un instant. Commençons par configurer le contrôleur de vue dans viewDidLoad.

Nous appelons setupView, une méthode d'assistance, et mettons à jour la valeur de newItem. Si la propriété item est égale à nil, newItem est égal à true. Cela nous aide à déterminer si nous créons ou mettons à jour un élément de liste d'achats.

Nous ajoutons également le contrôleur de vue en tant qu'observateur pour les notifications de type UITextFieldTextDidChangeNotification. Cela signifie que le contrôleur de vue est averti lorsque le contenu de nameTextField change.

Dans viewDidAppear (animé :), nous affichons le clavier en appelant la méthode becomeFirstResponder sur nameTextField.

La méthode setupView appelle deux méthodes d'assistance, updateNameTextField et updateSaveButton. La mise en œuvre de ces méthodes d'assistance est simple. Dans updateNameTextField, nous remplissons le champ de texte. Dans updateSaveButton, nous activons ou désactivons le bouton Enregistrer en fonction du contenu du champ de texte.

Avant de regarder l'implémentation mise à jour de la méthode save(_:), nous devons implémenter la méthode textFieldDidChange(_:). Tout ce que nous faisons est d'appeler updateSaveButton pour activer ou désactiver le bouton Enregistrer.

Étape 4: Enregistrement d'éléments

La méthode save(_:)est la méthode la plus intéressante de la classe AddItemViewController, car elle nous montre comment utiliser les références CloudKit. Jetez un oeil à l'implémentation de la méthode save(_:) ci-dessous.

La plupart de son implémentation devrait sembler familière puisque nous avons couvert l'enregistrement des enregistrements dans la classe AddListViewController. Ce qui nous intéresse le plus, c'est la façon dont l'article garde une référence à sa liste de courses. Nous créons d'abord une instance de CKReference en appelant l'initialiseur désigné, init(recordID:action :). Nous avons couvert les détails de la création d'une instance de CKReferenceil y a quelques minutes lorsque nous avons créé la requête pour récupérer des éléments de liste d'achats.

Dire l'objet de cette référence est facile. Nous appelons setObjec(_:forKey:) sur la propriété item, en passant l'instance CKReference comme valeur et "list" comme clé. La clé correspond au nom du champ que nous avons attribué dans le tableau de bord CloudKit. L'enregistrement de l'élément sur iCloud est identique à ce que nous avons déjà couvert. C'est facile de travailler avec des références CloudKit.

L'implémentation de processResponse(record:error:) ne contient rien de nouveau. Nous vérifions si des erreurs sont apparues et, si aucune erreur n'a été commise, nous en avisons le délégué.

Étape 5: mise à jour de ListViewController

Nous avons encore du travail à faire dans la classe ListViewController. Commencez par conformer la classe ListViewController au protocole AddItemViewControllerDelegate. C'est aussi un bon moment pour déclarer une constante pour le segue avec l'identifiant ItemDetail.

Implémenter le protocole AddItemViewControllerDelegateest trivial. Dans controller(_:didAddItem:), nous ajoutons le nouvel item à items, trions les éléments, rechargez la vue de la table et appelons updateView.

L'implémentation du controller(_:didUpdateItem:) est encore plus facile. Nous trions les itemset rechargeons la vue tableau.

Dans sortItems, nous trions le tableau des instances de CKRecordpar nom en utilisant la fonction sortInPlace, une méthode du protocole MutableCollectionType.

Il y a deux autres fonctionnalités dont nous avons besoin pour implémenter, mettre à jour et supprimer des éléments de liste d'achats.

Étape 6: Suppression d'éléments

Pour supprimer des éléments, nous devons implémenter tableView(_:commitEditingStyle:forRowAtIndexPath:) du protocole UITableViewDataSource. Nous récupérons l'élément de la liste de courses à supprimer et le passons à la méthode deleteRecord(_:).

L'implémentation de deleteRecord(_ :) ne contient rien de nouveau. Nous appelons deleteRecordWithID(_:completionHandler:) sur la base de données privée et traitons la réponse dans le gestionnaire d'achèvement.

DansprocessResponseForDeleteRequest(enregistrement:recordID:erreur:), nous mettons à jour la propriété items et l'interface utilisateur. Si quelque chose ne va pas, nous avertissons l'utilisateur en affichant une alerte.

Étape 7: mise à jour des éléments

L'utilisateur peut mettre à jour un élément en appuyant sur l'indicateur de divulgation détaillée. Cela signifie que nous devons implémenter la méthode déléguée tableView(_:accessoireButtonTappedForRowWithIndexPath:). Dans cette méthode, nous stockons la sélection de l'utilisateur et effectuons manuellement la recherche ListDetail. Notez que rien ne se produit dans la méthode tableView(_:didSelectRowAtIndexPath:). Tout ce que nous faisons est de désélectionner la ligne sur laquelle l'utilisateur a appuyé.

Dans prepareForSegue(_:sender:), nous récupérons l'élément de la liste d'achats en utilisant la valeur de la propriété selection et configurons le contrôleur de vue de destination, une instance de la classe AddItemViewController.

C'est tout ce que nous devons faire pour supprimer et mettre à jour les éléments de la liste d'achats. Dans la section suivante, nous explorons la facilité de mise à jour du modèle de données dans le tableau de bord CloudKit.

4. Mise à jour du modèle de données

Si vous avez déjà travaillé avec Core Data, vous savez que la mise à jour du modèle de données doit être effectuée avec prudence. Vous devez vous assurer de ne rien casser ou de ne corrompre aucun des magasins persistants de l'application. CloudKit est un peu plus flexible.

Le type d'enregistrement Items comporte actuellement deux champs, name et list. Je veux vous montrer ce que cela implique de mettre à jour le modèle de données en ajoutant un nouveau champ. Ouvrez le tableau de bord CloudKit et ajoutez un nouveau champ à l'enregistrement Items. Définissez le nom du champ sur number et définissez le type de champ sur Int (64). N'oubliez pas de sauvegarder vos modifications.

Update Item Record Type

Ajoutons maintenant la possibilité de modifier le numéro d'un article. Ouvrez AddItemViewController.swift et déclarez deux sorties, une étiquette et un stepper.

Nous devons également ajouter une action déclenchée lorsque la valeur du stepper change. Dans numberDidChange(_:), nous mettons à jour le contenu de numberLabel.

Ouvrez Main.storyboard et ajoutez une étiquette et un stepper au contrôleur de vue d'élément ajouté. Connectez les prises du contrôleur de vue aux éléments d'interface utilisateur correspondants et connectez l'action numberDidChange(_:)au moteur pas à pas pour l'événement Value Changed.

Update Add Item View Controller

L'action save(_:) de la classe AddItemViewController change également légèrement. Voyons ce que cela ressemble.

Il suffit d'ajouter deux lignes de code. En haut, nous stockons la valeur du stepper dans une constante, number. Lorsque nous configurons item, nous définissons number comme valeur pour la clé "number" et c'est tout.

Nous devons également implémenter une méthode d'assistance pour mettre à jour l'interface utilisateur du contrôleur de vue d'élément ajouté. La méthode updateNumberStepper vérifie si l'enregistrement contient un champ nommé number et met à jour le stepper si c'est le cas.

Nous appelons updateNumberStepper dans la méthode setupView de la classe AddItemViewController.

Pour visualiser le nombre de chaque élément, nous devons apporter une modification au ListViewController. Dans tableView(_:cellForRowAtIndexPath:), nous définissons le contenu de l'étiquette de droite de la cellule sur la valeur du champ de numéro de l'élément.

C'est tout ce que nous devons faire pour mettre en œuvre les modifications apportées au modèle de données. Il n'y a pas besoin d'effectuer une migration ou quelque chose comme ça. CloudKit prend soin des détails les plus concrets.

Conclusion

Vous devriez maintenant avoir une base appropriée du framework CloudKit. J'espère que vous êtes d'accord que Apple a fait un excellent travail avec le framework et le CloudKit Dashboard. Il y a beaucoup de choses que nous n'avons pas couvertes dans cette série, mais cela devrait vous donner assez pour démarrer avec CloudKit dans vos propres projets.

Si vous avez des questions ou des commentaires, n'hésitez pas à les laisser dans les commentaires ci-dessous ou à me contacter sur Twitter.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.