CloudKit dans Xamarin.iOS

Le framework CloudKit simplifie le développement d’applications qui accèdent à iCloud. Cela inclut la récupération des données d’application et des droits de ressource, ainsi que la possibilité de stocker en toute sécurité les informations d’application. Ce kit offre aux utilisateurs une couche d’anonymat en autorisant l’accès aux applications avec leurs ID iCloud sans partager d’informations personnelles.

Les développeurs peuvent se concentrer sur leurs applications côté client et laisser iCloud éliminer la nécessité d’écrire une logique d’application côté serveur. CloudKit fournit des bases de données d’authentification, privées et publiques, ainsi que des services de stockage de données et de ressources structurés.

Important

Apple fournit des outils pour aider les développeurs à gérer correctement le Règlement général sur la protection des données (RGPD) de l’Union européenne.

Spécifications

Voici les étapes décrites dans cet article :

  • Xcode et le SDK iOS : les API Xcode et iOS 8 d’Apple doivent être installées et configurées sur l’ordinateur du développeur.
  • Visual Studio pour Mac : la dernière version de Visual Studio pour Mac doit être installée et configurée sur l’appareil utilisateur.
  • Appareil iOS 8 : appareil iOS exécutant la dernière version d’iOS 8 à des fins de test.

Qu’est-ce que CloudKit ?

CloudKit est un moyen de donner au développeur l’accès aux serveurs iCloud. Il fournit la base de iCloud Drive et de la bibliothèque de photos iCloud. CloudKit est pris en charge sur les appareils macOS et iOS.

Prise en charge de CloudKit sur les appareils macOS et iOS

CloudKit utilise l’infrastructure de compte iCloud. S’il existe un utilisateur connecté à un compte iCloud sur l’appareil, CloudKit utilise son ID pour identifier l’utilisateur. Si aucun compte n’est disponible, un accès en lecture seule limité est fourni.

CloudKit prend en charge le concept de bases de données publiques et privées. Les bases de données publiques fournissent une « soupe » de toutes les données auxquelles l’utilisateur a accès. Les bases de données privées sont destinées à stocker les données privées liées à un utilisateur spécifique.

CloudKit prend en charge les données structurées et en bloc. Il est capable de gérer les transferts de fichiers volumineux en toute transparence. CloudKit s’occupe efficacement du transfert efficace de fichiers volumineux vers et à partir des serveurs iCloud en arrière-plan, ce qui permet au développeur de se concentrer sur d’autres tâches.

Remarque

Il est important de noter que CloudKit est une technologie de transport. Elle ne fournit aucune persistance ; elle permet uniquement à une application d’envoyer et de recevoir efficacement des informations des serveurs.

À partir de cette écriture, Apple fournit initialement CloudKit gratuitement avec une limite élevée sur la bande passante et la capacité de stockage. Pour les projets ou applications plus volumineux avec une grande base d’utilisateurs, Apple a indiqué qu’une échelle tarifaire abordable sera fournie.

Activation de CloudKit dans une application Xamarin

Avant qu’une application Xamarin puisse utiliser l’infrastructure CloudKit, l’application doit être correctement approvisionnée comme indiqué dans les guides Utilisation des fonctionnalités et Utilisation des droits d’utilisation.

Pour accéder au fichier Entitlements.plist de CloudKit, vous devez inclure l’activation d’iCloud, le stockage clé-valeur et les autorisations CloudKit .

Exemple d’application

L’exemple d’application montre comment utiliser CloudKit avec Xamarin. Les étapes ci-dessous montrent comment configurer l’exemple : il nécessite des paramètres supplémentaires au-delà de ce qui est nécessaire pour CloudKit seul :

  1. Ouvrez le projet dans Visual Studio pour Mac ou Visual Studio.
  2. Dans le Explorateur de solutions, ouvrez le fichier Info.plist et vérifiez que l’identificateurde bundle correspond à celui qui a été défini dans l’ID d’application créé dans le cadre de la configuration du provisionnement.
  3. Faites défiler vers le bas du fichier Info.plist, puis sélectionnez Modes d’arrière-plan activés, Emplacement Mises à jour et Notifications à distance.
  4. Cliquez avec le bouton droit sur le projet iOS dans la solution, puis sélectionnez Options.
  5. Sélectionnez La signature de bundle iOS, sélectionnez l’identité du développeur et le profil d’approvisionnement créés ci-dessus.
  6. Vérifiez que les droits.plist incluent Activer iCloud, le stockage clé-valeur et CloudKit.
  7. Vérifiez que le conteneur Ubiquity existe pour l’application. Exemple : iCloud.com.your-company.CloudKitAtlas
  8. Enregistrez les modifications du fichier.

Avec ces paramètres en place, l’exemple d’application est maintenant prêt à accéder aux API CloudKit Framework ainsi qu’aux services d’arrière-plan, d’emplacement et de notification.

Vue d’ensemble de l’API CloudKit

Avant d’implémenter CloudKit dans une application iOS Xamarin, cet article aborde les principes fondamentaux du CloudKit Framework, qui comprend les rubriques suivantes :

  1. Conteneurs : silos isolés de communications iCloud.
  2. Bases de données : public et privé sont disponibles pour l’application.
  3. Enregistrements : mécanisme dans lequel les données structurées sont déplacées vers et depuis CloudKit.
  4. Zones d’enregistrement : sont des groupes d’enregistrements.
  5. Identificateurs d’enregistrement : sont entièrement normalisés et représentent l’emplacement spécifique de l’enregistrement.
  6. Référence : fournissez des relations parent-enfant entre les enregistrements associés dans une base de données donnée.
  7. Ressources : autorisez le chargement de fichiers de données volumineuses et non structurées vers iCloud et associés à un enregistrement donné.

conteneurs

Une application donnée s’exécutant sur un appareil iOS est toujours en cours d’exécution côte à côte avec d’autres applications et services sur cet appareil. Sur l’appareil client, l’application va être en silo ou en bac à sable d’une certaine façon. Dans certains cas, il s’agit d’un bac à sable littéral, et dans d’autres, l’application s’exécute simplement dans son propre espace mémoire.

Le concept de prise d’une application cliente et son exécution séparée par d’autres clients est très puissant et offre les avantages suivants :

  1. Sécurité : une application ne peut pas interférer avec d’autres applications clientes ou le système d’exploitation lui-même.
  2. Stabilité : si l’application cliente se bloque, elle ne peut pas extraire d’autres applications du système d’exploitation.
  3. Confidentialité : chaque application cliente a un accès limité aux informations personnelles stockées dans l’appareil.

CloudKit a été conçu pour offrir les mêmes avantages que ceux répertoriés ci-dessus et les appliquer à l’utilisation d’informations basées sur le cloud :

Les applications CloudKit communiquent à l’aide de conteneurs

Tout comme l’application en cours d’exécution sur l’appareil, il s’agit donc des communications de l’application avec iCloud un-de-plusieurs. Chacun de ces différents silos de communication est appelé Conteneurs.

Les conteneurs sont exposés dans CloudKit Framework via la CKContainer classe. Par défaut, une application parle à un conteneur et ce conteneur sépare les données de cette application. Cela signifie que plusieurs applications peuvent stocker des informations sur le même compte iCloud, mais ces informations ne seront jamais entremêlées.

La conteneurisation des données iCloud permet également à CloudKit d’encapsuler les informations utilisateur. De cette façon, l’application aura un accès limité au compte iCloud et aux informations utilisateur stockées, tout en protégeant la confidentialité et la sécurité de l’utilisateur.

Les conteneurs sont entièrement gérés par le développeur de l’application via le portail WWDR. L’espace de noms du conteneur est global pour tous les développeurs Apple. Le conteneur doit donc non seulement être unique aux applications d’un développeur donné, mais à tous les développeurs et applications Apple.

Apple suggère d’utiliser la notation DNS inversée lors de la création de l’espace de noms pour les conteneurs d’applications. Exemple : iCloud.com.company-name.application-name

Bien que les conteneurs soient, par défaut, liés un-à-un à une application donnée, ils peuvent être partagés entre les applications. Ainsi, plusieurs applications peuvent coordonner sur un seul conteneur. Une seule application peut également communiquer avec plusieurs conteneurs.

Bases de données

L’une des principales fonctions de CloudKit consiste à prendre le modèle de données et la réplication d’une application jusqu’aux serveurs iCloud. Certaines informations sont destinées à l’utilisateur qui l’a créée, d’autres informations sont des données publiques qui peuvent être créées par un utilisateur pour une utilisation publique (par exemple, une révision de restaurant), ou il peut s’agir d’informations que le développeur a publiées pour l’application. Dans les deux cas, le public n’est pas seulement un seul utilisateur, mais est une communauté de personnes.

Diagramme de conteneur CloudKit

À l’intérieur d’un conteneur, tout d’abord est la base de données publique. C’est là que tous les renseignements publics vivent et se mêlent. En outre, il existe plusieurs bases de données privées individuelles pour chaque utilisateur de l’application.

Lors de l’exécution sur un appareil iOS, l’application n’a accès qu’aux informations de l’utilisateur iCloud actuellement connecté. Par conséquent, la vue de l’application du conteneur sera la suivante :

Affichage des applications du conteneur

Elle ne peut voir que la base de données publique et la base de données privée associée à l’utilisateur iCloud actuellement connecté.

Les bases de données sont exposées dans CloudKit Framework via la CKDatabase classe. Chaque application a accès à deux bases de données : la base de données publique et la base de données privée.

Le conteneur est le point d’entrée initial dans CloudKit. Le code suivant peut être utilisé pour accéder à la base de données publique et privée à partir du conteneur par défaut de l’application :

using CloudKit;
//...

public CKDatabase PublicDatabase { get; set; }
public CKDatabase PrivateDatabase { get; set; }
//...

// Get the default public and private databases for
// the application
PublicDatabase = CKContainer.DefaultContainer.PublicCloudDatabase;
PrivateDatabase = CKContainer.DefaultContainer.PrivateCloudDatabase;

Voici les différences entre les types de base de données :

Base de données publique Base de données privée
Type de données Données partagées Données de l’utilisateur actuel
Quota Pris en compte dans le quota du développeur Comptabilisé dans le quota de l’utilisateur
Autorisations par défaut World Readable Lisible par l’utilisateur
Modification des autorisations Rôles de tableau de bord iCloud via un niveau de classe d’enregistrement S/O

Enregistrements

Les conteneurs contiennent des bases de données et à l’intérieur des bases de données sont des enregistrements. Les enregistrements sont le mécanisme dans lequel les données structurées sont déplacées vers et depuis CloudKit :

Les conteneurs contiennent des bases de données et à l’intérieur des bases de données sont des enregistrements

Les enregistrements sont exposés dans CloudKit Framework via la CKRecord classe, qui encapsule les paires clé-valeur. Une instance d’un objet dans une application équivaut à une CKRecord instance dans CloudKit. En outre, chacun CKRecord possède un type d’enregistrement, qui équivaut à la classe d’un objet.

Les enregistrements ont un schéma juste-à-temps. Les données sont donc décrites dans CloudKit avant d’être transférées pour traitement. À partir de ce stade, CloudKit interprète les informations et gère la logistique du stockage et de la récupération de l’enregistrement.

La CKRecord classe prend également en charge un large éventail de métadonnées. Par exemple, un enregistrement contient des informations sur le moment où il a été créé et l’utilisateur qui l’a créé. Un enregistrement contient également des informations sur le moment où il a été modifié pour la dernière fois et l’utilisateur qui l’a modifié.

Les enregistrements contiennent la notion d’une balise de modification. Il s’agit d’une version précédente d’une révision d’un enregistrement donné. La balise de modification est utilisée comme moyen léger de déterminer si le client et le serveur ont la même version d’un enregistrement donné.

Comme indiqué ci-dessus, CKRecords habillage des paires clé-valeur et, par conséquent, les types de données suivants peuvent être stockés dans un enregistrement :

  1. NSString
  2. NSNumber
  3. NSData
  4. NSDate
  5. CLLocation
  6. CKReferences
  7. CKAssets

En plus des types valeur uniques, un enregistrement peut contenir un tableau homogène d’un des types répertoriés ci-dessus.

Le code suivant peut être utilisé pour créer un enregistrement et le stocker dans une base de données :

using CloudKit;
//...

private const string ReferenceItemRecordName = "ReferenceItems";
//...

var newRecord = new CKRecord (ReferenceItemRecordName);
newRecord ["name"] = (NSString)nameTextField.Text;
await CloudManager.SaveAsync (newRecord);

Zones d’enregistrement

Les enregistrements n’existent pas par eux-mêmes dans une base de données donnée : les groupes d’enregistrements existent ensemble dans une zone d’enregistrement. Les zones d’enregistrement peuvent être considérées comme des tables dans des bases de données relationnelles traditionnelles :

Les groupes d’enregistrements existent ensemble à l’intérieur d’une zone d’enregistrement

Il peut y avoir plusieurs enregistrements dans une zone d’enregistrement donnée et plusieurs zones d’enregistrement dans une base de données donnée. Chaque base de données contient une zone d’enregistrement par défaut :

Chaque base de données contient une zone d’enregistrement par défaut et une zone personnalisée

C’est là que les enregistrements sont stockés par défaut. En outre, des zones d’enregistrement personnalisées peuvent être créées. Les zones d’enregistrement représentent la granularité de base à laquelle les validations atomiques et le suivi des modifications sont effectués.

Identificateurs d’enregistrement

Les identificateurs d’enregistrement sont représentés sous forme de tuple, contenant à la fois un nom d’enregistrement fourni par le client et la zone dans laquelle l’enregistrement existe. Les identificateurs d’enregistrement présentent les caractéristiques suivantes :

  • Elles sont créées par l’application cliente.
  • Ils sont entièrement normalisés et représentent l’emplacement spécifique de l’enregistrement.
  • En affectant l’ID unique d’un enregistrement dans une base de données étrangère au nom de l’enregistrement, ils peuvent être utilisés pour ponter les bases de données locales qui ne sont pas stockées dans CloudKit.

Lorsque les développeurs créent de nouveaux enregistrements, ils peuvent choisir de passer un identificateur d’enregistrement. Si aucun identificateur d’enregistrement n’est spécifié, un UUID est automatiquement créé et affecté à l’enregistrement.

Lorsque les développeurs créent de nouveaux identificateurs d’enregistrement, ils peuvent choisir de spécifier la zone d’enregistrement à laquelle chaque enregistrement appartiendra. Si aucun n’est spécifié, la zone d’enregistrement par défaut est utilisée.

Les identificateurs d’enregistrement sont exposés dans CloudKit Framework via la CKRecordID classe. Le code suivant peut être utilisé pour créer un identificateur d’enregistrement :

var recordID =  new CKRecordID("My Record");

Références

Les références fournissent des relations entre les enregistrements associés dans une base de données donnée :

Les références fournissent des relations entre les enregistrements associés dans une base de données donnée

Dans l’exemple ci-dessus, parents possèdent des enfants afin que l’enfant soit un enregistrement enfant de l’enregistrement parent. La relation passe de l’enregistrement enfant à l’enregistrement parent et est appelée référence back.

Les références sont exposées dans CloudKit Framework via la CKReference classe. Ils permettent au serveur iCloud de comprendre la relation entre les enregistrements.

Les références fournissent le mécanisme derrière les suppressions en cascade. Si un enregistrement parent est supprimé de la base de données, tous les enregistrements enfants (tels que spécifiés dans une relation) sont automatiquement supprimés de la base de données.

Remarque

Les pointeurs d’angling sont une possibilité lors de l’utilisation de CloudKit. Par exemple, au moment où l’application a extrait une liste de pointeurs d’enregistrement, sélectionné un enregistrement, puis demandé l’enregistrement, l’enregistrement n’existe peut-être plus dans la base de données. Une application doit être codée pour gérer cette situation correctement.

Bien qu’elles ne soient pas obligatoires, les références back sont préférées lors de l’utilisation du CloudKit Framework. Apple a affiné le système pour rendre ce type de référence le plus efficace.

Lors de la création d’une référence, le développeur peut fournir un enregistrement déjà en mémoire ou créer une référence à un identificateur d’enregistrement. Si vous utilisez un identificateur d’enregistrement et que la référence spécifiée n’existe pas dans la base de données, un pointeur d’angling est créé.

Voici un exemple de création d’une référence sur un enregistrement connu :

var reference = new CKReference(newRecord, new CKReferenceAction());

Actifs

Les ressources permettent à un fichier de données volumineuses et non structurées d’être chargées sur iCloud et associées à un enregistrement donné :

Les ressources permettent à un fichier de données volumineuses et non structurées d’être chargées sur iCloud et associées à un enregistrement donné

Sur le client, un CKRecord fichier décrit le fichier qui sera chargé sur le serveur iCloud. A CKAsset est créé pour contenir le fichier et est lié à l’enregistrement qui le décrit.

Lorsque le fichier est chargé sur le serveur, l’enregistrement est placé dans la base de données et le fichier est copié dans une base de données de Stockage en bloc spéciale. Un lien est créé entre le pointeur d’enregistrement et le fichier chargé.

Les ressources sont exposées dans CloudKit Framework via la CKAsset classe et sont utilisées pour stocker des données volumineuses et non structurées. Étant donné que le développeur ne souhaite jamais avoir de données volumineuses et non structurées en mémoire, les ressources sont implémentées à l’aide de fichiers sur le disque.

Les ressources sont détenues par des enregistrements, ce qui permet aux ressources d’être récupérées à partir d’iCloud à l’aide de l’enregistrement en tant que pointeur. De cette façon, le serveur peut garbage collect assets lorsque l’enregistrement propriétaire de la ressource est supprimé.

Étant donné que CKAssets sont destinés à gérer des fichiers de données volumineux, Apple a conçu CloudKit pour charger et télécharger efficacement les ressources.

Le code suivant peut être utilisé pour créer une ressource et l’associer à l’enregistrement :

var fileUrl = new NSUrl("LargeFile.mov");
var asset = new CKAsset(fileUrl);
newRecord ["name"] = asset;

Nous avons maintenant abordé tous les objets fondamentaux dans CloudKit. Les conteneurs sont associés aux applications et contiennent des bases de données. Les bases de données contiennent des enregistrements regroupés dans des zones d’enregistrement et pointés par des identificateurs d’enregistrement. Les relations parent-enfant sont définies entre les enregistrements à l’aide de références. Enfin, les fichiers volumineux peuvent être chargés et associés aux enregistrements à l’aide de ressources.

API De commodité CloudKit

Apple propose deux ensembles d’API différents pour l’utilisation de CloudKit :

  • API opérationnelle : offre toutes les fonctionnalités de CloudKit. Pour les applications plus complexes, cette API fournit un contrôle précis sur CloudKit.
  • API pratique : offre un sous-ensemble commun préconfiguré de fonctionnalités CloudKit. Il fournit une solution d’accès facile et pratique pour inclure des fonctionnalités CloudKit dans une application iOS.

L’API Commodité est généralement le meilleur choix pour la plupart des applications iOS et Apple suggère de commencer avec elle. Le reste de cette section traite des rubriques d’API pratique suivantes :

  • Enregistrement d’un enregistrement.
  • Extraction d’un enregistrement.
  • Mise à jour d’un enregistrement.

Code d’installation commun

Avant de commencer avec l’API De commodité CloudKit, il existe un code de configuration standard requis. Commencez par modifier le fichier de l’application AppDelegate.cs et faites-le ressembler à ce qui suit :

using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using CloudKit;

namespace CloudKitAtlas
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    {
        public override UIWindow Window { get; set;}
        public CKDatabase PublicDatabase { get; set; }
        public CKDatabase PrivateDatabase { get; set; }

        public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
        {
            application.RegisterForRemoteNotifications ();

            // Get the default public and private databases for
            // the application
            PublicDatabase = CKContainer.DefaultContainer.PublicCloudDatabase;
            PrivateDatabase = CKContainer.DefaultContainer.PrivateCloudDatabase;

            return true;
        }

        public override void RegisteredForRemoteNotifications (UIApplication application, NSData deviceToken)
        {
            Console.WriteLine ("Registered for Push notifications with token: {0}", deviceToken);
        }

        public override void FailedToRegisterForRemoteNotifications (UIApplication application, NSError error)
        {
            Console.WriteLine ("Push subscription failed");
        }

        public override void ReceivedRemoteNotification (UIApplication application, NSDictionary userInfo)
        {
            Console.WriteLine ("Push received");
        }
    }
}

Le code ci-dessus expose les bases de données CloudKit publiques et privées en tant que raccourcis pour faciliter leur utilisation dans le reste de l’application.

Ensuite, ajoutez le code suivant à n’importe quel conteneur d’affichage ou d’affichage qui utilisera CloudKit :

using CloudKit;
//...

public AppDelegate ThisApp {
    get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
}

Cela ajoute un raccourci pour accéder aux AppDelegate raccourcis de base de données public et privé créés ci-dessus.

Avec ce code en place, examinons l’implémentation de l’API De commodité CloudKit dans une application Xamarin iOS 8.

Enregistrement d’un enregistrement

À l’aide du modèle présenté ci-dessus lors de la discussion des enregistrements, le code suivant crée un enregistrement et utilise l’API Commodité pour l’enregistrer dans la base de données publique :

private const string ReferenceItemRecordName = "ReferenceItems";
...

// Create a new record
var newRecord = new CKRecord (ReferenceItemRecordName);
newRecord ["name"] = (NSString)nameTextField.Text;

// Save it to the database
ThisApp.PublicDatabase.SaveRecord(newRecord, (record, err) => {
    // Was there an error?
    if (err != null) {
        ...
    }
});

Trois points à noter sur le code ci-dessus :

  1. En appelant la SaveRecord méthode du PublicDatabasedéveloppeur, il n’est pas obligé de spécifier la façon dont les données sont envoyées, la zone dans laquelle elle est écrite, etc. L’API Commodité s’occupe de tous ces détails lui-même.
  2. L’appel est asynchrone et fournit une routine de rappel une fois l’appel terminé, avec succès ou échec. Si l’appel échoue, un message d’erreur est fourni.
  3. CloudKit ne fournit pas de stockage/persistance local ; il s’agit d’un support de transfert uniquement. Par conséquent, lorsqu’une demande est effectuée pour enregistrer un enregistrement, elle est immédiatement envoyée aux serveurs iCloud.

Remarque

En raison de la nature « perte » des communications réseau mobiles, où les connexions sont constamment supprimées ou interrompues, l’un des premiers points à prendre en compte par le développeur lors de l’utilisation de CloudKit est la gestion des erreurs.

Extraction d’un enregistrement

Avec un enregistrement créé et correctement stocké sur le serveur iCloud, utilisez le code suivant pour récupérer l’enregistrement :

// Create a record ID and fetch the record from the database
var recordID = new CKRecordID("MyRecordName");
ThisApp.PublicDatabase.FetchRecord(recordID, (record, err) => {
    // Was there an error?
    if (err != null) {
        ...
    }
});

Tout comme dans l’enregistrement de l’enregistrement, le code ci-dessus est asynchrone, simple et nécessite une grande gestion des erreurs.

Mise à jour d'un enregistrement

Une fois qu’un enregistrement a été récupéré à partir des serveurs iCloud, le code suivant peut être utilisé pour modifier l’enregistrement et enregistrer les modifications dans la base de données :

// Create a record ID and fetch the record from the database
var recordID = new CKRecordID("MyRecordName");
ThisApp.PublicDatabase.FetchRecord(recordID, (record, err) => {
    // Was there an error?
    if (err != null) {

    } else {
        // Modify the record
        record["name"] = (NSString)"New Name";

        // Save changes to database
        ThisApp.PublicDatabase.SaveRecord(record, (r, e) => {
            // Was there an error?
            if (e != null) {
                 ...
            }
        });
    }
});

Méthode FetchRecord du PublicDatabase retour si CKRecord l’appel a réussi. L’application modifie ensuite l’enregistrement et appelle SaveRecord à nouveau pour réécrire les modifications dans la base de données.

Cette section montre le cycle classique qu’une application utilisera lors de l’utilisation de l’API De commodité CloudKit. L’application enregistre les enregistrements dans iCloud, récupère ces enregistrements à partir d’iCloud, modifie les enregistrements et enregistre ces modifications dans iCloud.

Conception pour l’extensibilité

Jusqu’à présent, cet article a examiné le stockage et la récupération de l’ensemble du modèle objet d’une application à partir des serveurs iCloud, chaque fois qu’il sera utilisé. Bien que cette approche fonctionne correctement avec une petite quantité de données et une base d’utilisateurs très petite, elle ne s’adapte pas bien lorsque la quantité d’informations et/ou de base utilisateur augmente.

Big Data, appareil minuscule

Plus une application est populaire, plus les données de la base de données sont plus courantes et moins il est possible d’avoir un cache de ces données entières sur l’appareil. Les techniques suivantes peuvent être utilisées pour résoudre ce problème :

  • Conservez les données volumineuses dans le cloud : CloudKit a été conçu pour gérer efficacement les données volumineuses.
  • Le client ne doit afficher qu’une tranche de ces données : réduire le minimum de données nécessaire pour gérer une tâche à un moment donné.
  • Les vues clientes peuvent changer : étant donné que chaque utilisateur a des préférences différentes, la tranche de données affichées peut changer de l’utilisateur à l’utilisateur et l’affichage individuel de chaque tranche donnée peut être différent.
  • Le client utilise des requêtes pour concentrer le point de vue : les requêtes permettent à l’utilisateur d’afficher un petit sous-ensemble d’un jeu de données plus volumineux qui existe dans le cloud.

Requêtes

Comme indiqué ci-dessus, les requêtes permettent au développeur de sélectionner un petit sous-ensemble du jeu de données plus volumineux qui existe dans le cloud. Les requêtes sont exposées dans CloudKit Framework via la CKQuery classe.

Une requête combine trois éléments différents : un type d’enregistrement ( ), RecordTypeun prédicat ( NSPredicate) et, éventuellement, un descripteur de tri ( NSSortDescriptors). CloudKit prend en charge la plupart des NSPredicate.

Prédicats pris en charge

CloudKit prend en charge les types suivants lors de l’utilisation des NSPredicates requêtes :

  1. Enregistrements correspondants où le nom est égal à une valeur stockée dans une variable :

    NSPredicate.FromFormat(string.Format("name = '{0}'", recordName))
    
  2. Permet la mise en correspondance en fonction d’une valeur de clé dynamique, de sorte que la clé n’ait pas besoin d’être connu au moment de la compilation :

    NSPredicate.FromFormat(string.Format("{0} = '{1}'", key, value))
    
  3. Enregistrements correspondants où la valeur de l’enregistrement est supérieure à la valeur donnée :

    NSPredicate.FromFormat(string.Format("start > {0}", (NSDate)date))
    
  4. Enregistrements correspondants où l’emplacement de l’enregistrement se trouve à moins de 100 mètres de l’emplacement donné :

    var location = new CLLocation(37.783,-122.404);
    var predicate = NSPredicate.FromFormat(string.Format("distanceToLocation:fromLocation(Location,{0}) < 100", location));
    
  5. CloudKit prend en charge une recherche par jetons. Cet appel crée deux jetons, un pour after et un autre pour session. Il retourne un enregistrement qui contient ces deux jetons :

    NSPredicate.FromFormat(string.Format("ALL tokenize({0}, 'Cdl') IN allTokens", "after session"))
    
  6. CloudKit prend en charge les prédicats composés joints à l’aide de l’opérateur AND .

    NSPredicate.FromFormat(string.Format("start > {0} AND name = '{1}'", (NSDate)date, recordName))
    

Création de requêtes

Le code suivant peut être utilisé pour créer une CKQuery application Xamarin iOS 8 :

var recordName = "MyRec";
var predicate = NSPredicate.FromFormat(string.Format("name = '{0}'", recordName));
var query = new CKQuery("CloudRecords", predicate);

Tout d’abord, il crée un prédicat pour sélectionner uniquement les enregistrements qui correspondent à un nom donné. Ensuite, il crée une requête qui sélectionne les enregistrements du type d’enregistrement donné qui correspondent au prédicat.

Exécution d’une requête

Une fois qu’une requête a été créée, utilisez le code suivant pour effectuer la requête et traiter les enregistrements retournés :

var recordName = "MyRec";
var predicate = NSPredicate.FromFormat(string.Format("name = {0}", recordName));
var query = new CKQuery("CloudRecords", predicate);

ThisApp.PublicDatabase.PerformQuery(query, CKRecordZone.DefaultRecordZone().ZoneId, (NSArray results, NSError err) => {
    // Was there an error?
    if (err != null) {
       ...
    } else {
        // Process the returned records
        for(nint i = 0; i < results.Count; ++i) {
            var record = (CKRecord)results[i];
        }
    }
});

Le code ci-dessus prend la requête créée ci-dessus et l’exécute sur la base de données publique. Étant donné qu’aucune zone d’enregistrement n’est spécifiée, toutes les zones sont recherchées. Si aucune erreur ne s’est produite, un tableau de CKRecords données est retourné correspondant aux paramètres de la requête.

La façon de réfléchir aux requêtes est qu’elles sont des sondages et qu’elles sont idéales pour découper des jeux de données volumineux. Toutefois, les requêtes ne conviennent pas bien aux jeux de données volumineux, principalement statiques pour les raisons suivantes :

  • Ils sont mauvais pour la durée de vie de la batterie de l’appareil.
  • Elles sont mauvaises pour le trafic réseau.
  • Ils sont incorrects pour l’expérience utilisateur, car les informations qu’ils voient sont limitées par la fréquence à laquelle l’application interroge la base de données. Les utilisateurs attendent aujourd’hui des notifications Push quand quelque chose change.

Abonnements

Lorsque vous traitez de jeux de données volumineux, principalement statiques, la requête ne doit pas être effectuée sur l’appareil client, elle doit s’exécuter sur le serveur au nom du client. La requête doit s’exécuter en arrière-plan et doit être exécutée après chaque enregistrement unique, qu’il s’agisse de l’appareil actuel ou d’un autre appareil touchant la même base de données.

Enfin, une notification Push doit être envoyée à chaque appareil attaché à la base de données lorsque la requête côté serveur est exécutée.

Les abonnements sont exposés dans CloudKit Framework via la CKSubscription classe. Ils combinent un type d’enregistrement ( RecordType), un prédicat ( NSPredicate) et une notification Push Apple ( Push).

Remarque

Les push CloudKit sont légèrement augmentés, car ils contiennent une charge utile contenant des informations spécifiques à CloudKit, telles que ce qui a provoqué l’envoi (push).

Fonctionnement des abonnements

Avant d’implémenter l’abonnement en code C#, examinons rapidement le fonctionnement des abonnements :

Vue d’ensemble du fonctionnement des abonnements

Le graphique ci-dessus montre le processus d’abonnement classique comme suit :

  1. L’appareil client crée un abonnement contenant l’ensemble de conditions qui déclenchent l’abonnement et une notification Push qui sera envoyée lorsque le déclencheur se produit.
  2. L’abonnement est envoyé à la base de données où il est ajouté à la collection d’abonnements existants.
  3. Un deuxième appareil crée un enregistrement et enregistre cet enregistrement dans la base de données.
  4. La base de données recherche dans sa liste d’abonnements pour voir si le nouvel enregistrement correspond à l’une de ses conditions.
  5. Si une correspondance est trouvée, la notification Push est envoyée à l’appareil qui a inscrit l’abonnement avec des informations sur l’enregistrement qui a provoqué son déclenchement.

Avec cette connaissance en place, examinons la création d’abonnements dans une application Xamarin iOS 8.

Création d’abonnements

Le code suivant peut être utilisé pour créer un abonnement :

// Create a new subscription
DateTime date;
var predicate = NSPredicate.FromFormat(string.Format("start > {0}", (NSDate)date));
var subscription = new CKSubscription("RecordType", predicate, CKSubscriptionOptions.FiresOnRecordCreation);

// Describe the type of notification
var notificationInfo = new CKNotificationInfo();
notificationInfo.AlertLocalizationKey = "LOCAL_NOTIFICATION_KEY";
notificationInfo.SoundName = "ping.aiff";
notificationInfo.ShouldBadge = true;

// Attach the notification info to the subscription
subscription.NotificationInfo = notificationInfo;

Tout d’abord, il crée un prédicat qui fournit la condition pour déclencher l’abonnement. Ensuite, il crée l’abonnement par rapport à un type d’enregistrement spécifique et définit l’option de test du déclencheur. Enfin, il définit le type de notification qui se produit lorsque l’abonnement est déclenché et l’attache à l’abonnement.

Enregistrement d’abonnements

Une fois l’abonnement créé, le code suivant l’enregistrera dans la base de données :

// Save the subscription to the database
ThisApp.PublicDatabase.SaveSubscription(subscription, (s, err) => {
    // Was there an error?
    if (err != null) {

    }
});

À l’aide de l’API Commodité, l’appel est asynchrone, simple et offre une gestion facile des erreurs.

Gestion des notifications Push

Si le développeur a déjà utilisé les notifications Push Apple (APS), le processus de traitement des notifications générées par CloudKit doit être familier.

Dans le AppDelegate.cs, remplacez la ReceivedRemoteNotification classe comme suit :

public override void ReceivedRemoteNotification (UIApplication application, NSDictionary userInfo)
{
    // Parse the notification into a CloudKit Notification
    var notification = CKNotification.FromRemoteNotificationDictionary (userInfo);

    // Get the body of the message
    var alertBody = notification.AlertBody;

    // Was this a query?
    if (notification.NotificationType == CKNotificationType.Query) {
        // Yes, convert to a query notification and get the record ID
        var query = notification as CKQueryNotification;
        var recordID = query.RecordId;
    }
}

Le code ci-dessus demande à CloudKit d’analyser l’userInfo dans une notification CloudKit. Ensuite, les informations sont extraites de l’alerte. Enfin, le type de notification est testé et la notification est gérée en conséquence.

Cette section montre comment répondre au problème Big Data, Tiny Device présenté ci-dessus à l’aide de requêtes et d’abonnements. L’application laisse ses données volumineuses dans le cloud et utilise ces technologies pour fournir des vues dans ce jeu de données.

Comptes d’utilisateur CloudKit

Comme indiqué au début de cet article, CloudKit est basé sur l’infrastructure iCloud existante. La section suivante aborde en détail la façon dont les comptes sont exposés à un développeur à l’aide de l’API CloudKit.

Authentification

Lorsque vous traitez des comptes d’utilisateur, la première considération est l’authentification. CloudKit prend en charge l’authentification via l’utilisateur iCloud actuellement connecté sur l’appareil. L’authentification se déroule en arrière-plan et est gérée par iOS. De cette façon, les développeurs n’ont jamais à se soucier des détails de l’implémentation de l’authentification. Ils testent uniquement si un utilisateur est connecté.

Informations sur le compte d’utilisateur

CloudKit fournit les informations utilisateur suivantes au développeur :

  • Identité : un moyen d’identifier de manière unique l’utilisateur.
  • Métadonnées : possibilité d’enregistrer et de récupérer des informations sur les utilisateurs.
  • Confidentialité : toutes les informations sont gérées dans un manoir conscient de la vie privée. Rien n’est exposé, sauf si l’utilisateur l’a accepté.
  • Découverte : permet aux utilisateurs de découvrir leurs amis qui utilisent la même application.

Ensuite, nous allons examiner ces sujets en détail.

Identité

Comme indiqué ci-dessus, CloudKit permet à l’application d’identifier de manière unique un utilisateur donné :

Identifier de façon unique un utilisateur donné

Une application cliente s’exécute sur les appareils d’un utilisateur et toutes les bases de données privées utilisateur spécifiques à l’intérieur du conteneur CloudKit. L’application cliente va être liée à l’un de ces utilisateurs spécifiques. Cela est basé sur l’utilisateur connecté localement à iCloud sur l’appareil.

Étant donné que cela provient d’iCloud, il existe un magasin de stockage riche d’informations utilisateur. Et comme iCloud héberge réellement le conteneur, il peut mettre en corrélation les utilisateurs. Dans le graphique ci-dessus, l’utilisateur dont le compte user@icloud.com iCloud est lié au client actuel.

Sur une base conteneur par conteneur, un ID utilisateur unique généré de manière aléatoire est créé et associé au compte iCloud de l’utilisateur (adresse e-mail). Cet ID d’utilisateur est retourné à l’application et peut être utilisé de n’importe quelle façon que le développeur le voit.

Remarque

Différentes applications s’exécutant sur le même appareil pour le même utilisateur iCloud auront différents ID d’utilisateur, car elles sont connectées à différents conteneurs CloudKit.

Le code suivant obtient l’ID utilisateur CloudKit pour l’utilisateur iCloud actuellement connecté sur l’appareil :

public CKRecordID UserID { get; set; }
...

// Get the CloudKit User ID
CKContainer.DefaultContainer.FetchUserRecordId ((recordID, err) => {
    // Was there an error?
    if (err!=null) {
        Console.WriteLine("Error: {0}", err.LocalizedDescription);
    } else {
        // Save user ID
        UserID = recordID;
    }
});

Le code ci-dessus demande au conteneur CloudKit de fournir l’ID de l’utilisateur actuellement connecté. Étant donné que ces informations proviennent du serveur iCloud, l’appel est asynchrone et la gestion des erreurs est requise.

Métadonnées

Chaque utilisateur dans CloudKit a des métadonnées spécifiques qui les décrivent. Ces métadonnées sont représentées sous la forme d’un enregistrement CloudKit :

Chaque utilisateur dans CloudKit a des métadonnées spécifiques qui les décrivent

À l’intérieur de la base de données privée pour un utilisateur spécifique d’un conteneur, il existe un enregistrement qui définit cet utilisateur. Il existe de nombreux enregistrements utilisateur dans la base de données publique, un pour chaque utilisateur du conteneur. L’un d’eux aura un ID d’enregistrement qui correspond à l’ID d’enregistrement de l’utilisateur actuellement connecté.

Les enregistrements utilisateur dans la base de données publique sont lisibles dans le monde entier. Ils sont traités, pour la plupart, comme un enregistrement ordinaire et ont un type de CKRecordTypeUserRecord. Ces enregistrements sont réservés par le système et ne sont pas disponibles pour les requêtes.

Utilisez le code suivant pour accéder à un enregistrement utilisateur :

public CKRecord UserRecord { get; set; }
...

// Get the user's record
PublicDatabase.FetchRecord(UserID, (record ,er) => {
    //was there an error?
    if (er != null) {
        Console.WriteLine("Error: {0}", er.LocalizedDescription);
    } else {
        // Save the user record
        UserRecord = record;
    }
});

Le code ci-dessus demande à la base de données publique de retourner l’enregistrement utilisateur de l’utilisateur qui a accédé ci-dessus. Étant donné que ces informations proviennent du serveur iCloud, l’appel est asynchrone et la gestion des erreurs est requise.

Confidentialité

CloudKit a été conçu par défaut pour protéger la confidentialité de l’utilisateur actuellement connecté. Aucune information d’identification personnelle de l’utilisateur n’est exposée par défaut. Il existe certains cas où l’application nécessite des informations limitées sur l’utilisateur.

Dans ces cas, l’application peut demander à l’utilisateur de divulguer ces informations. Une boîte de dialogue sera présentée à l’utilisateur lui demandant de choisir d’exposer ses informations de compte.

Découverte

En supposant que l’utilisateur a choisi d’autoriser l’application à accéder limité à ses informations de compte d’utilisateur, il peut être détectable pour d’autres utilisateurs de l’application :

Un utilisateur peut être détectable pour d’autres utilisateurs de l’application

L’application cliente parle à un conteneur et le conteneur parle d’iCloud pour accéder aux informations utilisateur. L’utilisateur peut fournir une adresse e-mail et la découverte peut être utilisée pour récupérer des informations sur l’utilisateur. Si vous le souhaitez, l’ID d’utilisateur peut également être utilisé pour découvrir des informations sur l’utilisateur.

CloudKit fournit également un moyen de découvrir des informations sur tous les utilisateurs susceptibles d’être amis de l’utilisateur iCloud actuellement connecté en interrogeant l’ensemble du carnet d’adresses. Le processus CloudKit extrait le carnet de contacts de l’utilisateur et utilise les adresses e-mail pour voir s’il peut trouver les autres utilisateurs de l’application qui correspondent à ces adresses.

Cela permet à l’application de tirer parti du carnet de contacts de l’utilisateur sans lui fournir l’accès ou demander à l’utilisateur d’approuver l’accès aux contacts. À aucun moment les informations de contact mises à la disposition de l’application, seul le processus CloudKit a accès.

Pour récapituler, il existe trois types d’entrées différents disponibles pour la découverte d’utilisateurs :

  • ID d’enregistrement utilisateur : la découverte peut être effectuée par rapport à l’ID utilisateur de l’utilisateur actuellement connecté à CloudKit.
  • Adresse e-mail de l’utilisateur : l’utilisateur peut fournir une adresse e-mail et il peut être utilisé pour la découverte.
  • Carnet de contacts : le carnet d’adresses de l’utilisateur peut être utilisé pour découvrir les utilisateurs de l’application qui ont la même adresse e-mail que celles répertoriées dans leurs contacts.

La découverte de l’utilisateur retourne les informations suivantes :

  • ID d’enregistrement utilisateur : ID unique d’un utilisateur dans la base de données publique.
  • Prénom et nom : tel qu’il est stocké dans la base de données publique.

Ces informations ne seront retournées que pour les utilisateurs qui ont choisi la découverte.

Le code suivant découvre des informations sur l’utilisateur actuellement connecté à iCloud sur l’appareil :

public CKDiscoveredUserInfo UserInfo { get; set; }
//...

// Get the user's metadata
CKContainer.DefaultContainer.DiscoverUserInfo(UserID, (info, e) => {
    // Was there an error?
    if (e != null) {
        Console.WriteLine("Error: {0}", e.LocalizedDescription);
    } else {
        // Save the user info
        UserInfo = info;
    }
});

Utilisez le code suivant pour interroger tous les utilisateurs dans le carnet de contacts :

// Ask CloudKit for all of the user's friends information
CKContainer.DefaultContainer.DiscoverAllContactUserInfos((info, er) => {
    // Was there an error
    if (er != null) {
        Console.WriteLine("Error: {0}", er.LocalizedDescription);
    } else {
        // Process all returned records
        for(int i = 0; i < info.Count(); ++i) {
            // Grab a user
            var userInfo = info[i];
        }
    }
});

Dans cette section, nous avons abordé les quatre principaux domaines d’accès au compte d’un utilisateur que CloudKit peut fournir à une application. De l’obtention de l’identité et des métadonnées de l’utilisateur aux stratégies de confidentialité intégrées à CloudKit et enfin, la possibilité de découvrir d’autres utilisateurs de l’application.

Environnements de développement et de production

CloudKit fournit des environnements de développement et de production distincts pour les types d’enregistrements et les données d’une application. L’environnement de développement est un environnement plus flexible qui est disponible uniquement pour les membres d’une équipe de développement. Lorsqu’une application ajoute un nouveau champ à un enregistrement et enregistre cet enregistrement dans l’environnement de développement, le serveur met automatiquement à jour les informations de schéma.

Le développeur peut utiliser cette fonctionnalité pour apporter des modifications à un schéma pendant le développement, ce qui permet de gagner du temps. Une mise en garde est qu’une fois qu’un champ a été ajouté à un enregistrement, le type de données associé à ce champ ne peut pas être modifié par programmation. Pour modifier le type d’un champ, le développeur doit supprimer le champ dans le tableau de bord CloudKit et l’ajouter à nouveau avec le nouveau type.

Avant de déployer l’application, le développeur peut migrer son schéma et ses données vers l’environnement de production à l’aide du tableau de bord CloudKit. Lors de l’exécution sur l’environnement de production, le serveur empêche une application de modifier le schéma par programmation. Le développeur peut toujours apporter des modifications avec le tableau de bord CloudKit, mais tente d’ajouter des champs à un enregistrement dans l’environnement de production entraîne des erreurs.

Remarque

Le simulateur iOS fonctionne uniquement avec l’environnement de développement. Lorsque le développeur est prêt à tester une application dans un environnement de production, un appareil iOS physique est requis.

Expédition d’une application CloudKit activée

Avant d’envoyer une application qui utilise CloudKit, elle doit être configurée pour cibler l’environnement CloudKit de production ou l’application sera rejetée par Apple.

Effectuez les actions suivantes :

  1. Dans Visual Studio pour Ma, compilez l’application pour l’appareil iOS release>:

    Compiler l’application pour la version

  2. Dans le menu Générer , sélectionnez Archiver :

    Sélectionner Archiver

  3. L’archive est créée et affichée dans Visual Studio pour Mac :

    L’archive sera créée et affichée

  4. Démarrez Xcode.

  5. Dans le menu Fenêtre , sélectionnez Organisateur :

    Sélectionner l’organisateur

  6. Sélectionnez l’archive de l’application, puis cliquez sur le bouton Exporter... :

    Archive de l’application

  7. Sélectionnez une méthode pour l’exportation, puis cliquez sur le bouton Suivant :

    Sélectionner une méthode pour l’exportation

  8. Sélectionnez l’équipe de développement dans la liste déroulante, puis cliquez sur le bouton Choisir :

    Sélectionnez l’équipe de développement dans la liste déroulante

  9. Sélectionnez Production dans la liste déroulante, puis cliquez sur le bouton Suivant :

    Sélectionner Production dans la liste déroulante

  10. Passez en revue le paramètre, puis cliquez sur le bouton Exporter :

    Passer en revue le paramètre

  11. Choisissez un emplacement pour générer le fichier d’application .ipa résultant.

Le processus est similaire pour soumettre l’application directement à iTunes Connecter, cliquez simplement sur le bouton Envoyer... au lieu de l’exportation... après avoir sélectionné une archive dans la fenêtre Organisateur.

Quand utiliser CloudKit

Comme nous l’avons vu dans cet article, CloudKit offre un moyen simple pour une application de stocker et récupérer des informations à partir des serveurs iCloud. Cela dit, CloudKit n’est pas obsolète ni déprécié des outils ou infrastructures existants.

Cas d’utilisation

Les cas d’usage suivants doivent aider le développeur à décider quand utiliser une infrastructure ou une technologie iCloud spécifique :

  • Magasin clé-valeur iCloud : conserve de façon asynchrone une petite quantité de données à jour et est idéal pour travailler avec les préférences de l’application. Toutefois, il est limité pour une très petite quantité d’informations.
  • iCloud Drive : basé sur les API de documents iCloud existantes et fournit une API simple pour synchroniser des données non structurées à partir du système de fichiers. Il fournit un cache hors connexion complet sur Mac OS X et est idéal pour les applications centrées sur les documents.
  • Données iCloud Core : permet la réplication des données entre tous les appareils de l’utilisateur. Les données sont mono-utilisateur et sont idéales pour conserver des données privées et structurées synchronisées.
  • CloudKit : fournit des données publiques à la fois de structure et en bloc et est capable de gérer les fichiers volumineux et non structurés. Elle est liée au compte iCloud de l’utilisateur et fournit un transfert de données dirigé par le client.

En gardant ces cas d’usage à l’esprit, le développeur doit choisir la technologie iCloud appropriée pour fournir à la fois les fonctionnalités d’application requises actuelles et fournir une bonne scalabilité pour la croissance future.

Résumé

Cet article a abordé une présentation rapide de l’API CloudKit. Il a montré comment approvisionner et configurer une application iOS Xamarin pour utiliser CloudKit. Il a couvert les fonctionnalités de l’API De commodité CloudKit. Il a montré comment concevoir une application compatible CloudKit pour l’extensibilité à l’aide de requêtes et d’abonnements. Enfin, il a affiché les informations de compte d’utilisateur exposées à une application par CloudKit.