Dans cette partie, nous allons couvrir:
- Qu’est-ce que Realm
- RealmSwift
- Création d’un Modèle de Domaine Complexe
- Pourquoi nous utilisons @objc et dynamic dans la Propriété
- Relation À Un et À Plusieurs dans Realm
- Comment stocker l’énumération personnalisée dans Realm
- Qu’est-ce que RealmOptional et Comment Stocker la Propriété Atomique Optionnelle Swift
- Comment La Propriété Calculée fonctionne comme une Propriété Transitoire dans Realm
- Comment faire l’indexation pour le gain de performance
- Qu’est-ce que l’objet de liaison dans le Domaine
- Requêtes de Prédicat complexes
- Opération CRUD
- Qu’est-ce que les résultats en direct dans le Domaine
- Choses évitées lorsque Modifier les objets Realm
>
Realm est une base de données d’objets mobiles multiplateformes. Il est très rapide, performant et facile à utiliser par rapport à Core Data et Sqlite. Il utilise son mécanisme de stockage pour stocker l’objet en tant que JSON sur le disque par rapport aux données de base qui utilisent Sqlite comme backend. Il est écrit en C ++ multiplateforme, il fonctionne donc exactement de la même manière sur Android, iOS, macOS ou toute autre plate-forme.
RealmSwift
La majeure partie de Realm est open-source, mais la sauce secrète derrière la plate-forme de Realm est le moteur de base de données de base écrit à partir de zéro en C++. RealmSwift est un wrapper autour du framework Realm Objective-C et le framework Realm Objective-C est un wrapper autour du moteur de base de données Realm Core.
Mise en route
Dans ce tutoriel, nous allons travailler sur ces modèles comme le montre la figure 1
Utilisateur →C’est un modèle qui contient des informations utilisateur dans lesquelles userId
c’est primaire. Il a également une relation à un avec le modèle de passeport et à de nombreuses relations avec les tâches à accomplir. (L’utilisateur ne peut avoir que un passeport et avoir de nombreuses tâches à accomplir)
Passport →C’est un modèle qui contient les informations de passeport d’un utilisateur et a également un lien inverse de l’objet User
.
Todo → C’est un modèle qui contient des tâches d’un utilisateur et qui a également un lien arrière inversé de l’objet User
.
Modèle utilisateur
Comme le montre la figure 2, nous avons créé le modèle utilisateur et ajouté quelques propriétés:
- Nous héritons d’abord de
User
classe deObject
ce qui le rendRealm Object
. Les objets Realm sont essentiellement un modèle de données standard, tout comme tout autre modèle de données standard que vous avez défini dans vos applications. La seule différence est qu’ils sont soutenus par la persistance et les capacités du royaume. En examinant tous les domaines de classeObject
, vous pouvez déduire votre schéma. Chaque modèle que vous souhaitez conserver, vous devez hériter de la classe Object. -
firstName
stocke le prénom de l’utilisateur sous la formeString
. PuisqueRealmSwift
est un wrapper autour des types de framework de domaine Objective-C comme String, Date et Data sont des sous-classes de NSObject dans Objective-C, vous pouvez donc les considérer comme des types d’objets dans Swift. En plus de cela, @objc signifie que vous voulez votre code Swift (classe, méthode, propriété, etc.) pour être visible depuis Objective-C alors que dynamic signifie que vous souhaitez utiliser la répartition dynamique Objective-C. Pour créer de simples magasins d’objets swift dans le domaine de la base de données, utilisez la fonction de répartition dynamique Objective-C pour travailler sous le capot -
userId
stocke l’ID utilisateur qui agit comme une clé primaire. Vous pouvez définir l’une des propriétés de votre objet comme clé primaire. Habituellement, une propriété qui s’identifie de manière unique, c’est-à-dire un candidat principal pour une clé primaire. Il vous aide à rechercher ou à modifier rapidement un objet dans une base de données. Comme le montre la figure 2, nous créons une clé primaireuserId
en remplaçant la fonction statiqueprimarykey
. L’implémentation par défaut de cette méthode renvoie nil. RemarqueuserId
agit comme un type Int primitif Objective C car il s’agit d’un wrapper autour du domaine Objectif C -
passport
la propriété stocke les informations de passeport utilisateur qui sont un autre objet de domaine. Nous avons créé une relation avec le modèle de passeport. To – un lien relation/objet, dans lequel un objet de domaine pointe vers un autre objet de domaine. Lorsque vous créez une relation avec un autre objet Realm, sa propriété doit être de type facultatif. Dans la référence du pointeur de variable passport dePassport
l’objet stockera -
privateUserType
est la propriété wrapper deUserType
puisque UserType est une énumération swift, nous ne pouvons pas stocker directement sur Realm. Toutes ses valeurs de casse auraient une valeur brute implicitement attribuée correspondant au nom de la casse. Vous utiliserez cette valeur brute pour conserver les options d’énumération en tant queInt
dans Realm. Mais le client accède à la propriété enum calculée et sous le capot, la valeur brute / la valeur atomique enum est stockée dans une base de données qui n’est pas visible par le client. - Les propriétés String, NSDate et NSData peuvent être déclarées comme facultatives ou non facultatives à l’aide de la syntaxe Swift standard.Les types numériques facultatifs sont déclarés à l’aide de RealmOptional. Étant donné que RealmSwift enveloppe le domaine de l’objectif C et qu’il n’y a pas d’Int facultatif dans l’objectif C, c’est pourquoi Realm a créé son type RealmOptional pour ces scénarios. Tout le type primitif Objective C nécessite Swift avec Facultatif, vous devez utiliser RealmOptional. Remarque : Les propriétés RealmOptional ne peuvent pas être déclarées en tant que mot-clé dynamic et @objc car les propriétés génériques ne peuvent pas être représentées dans le runtime Objective C, qui est utilisé pour la répartition dynamique des propriétés dynamiques, et doivent toujours être déclarées avec let. Comme il s’agit de la classe Realm, elle possède toutes les fonctionnalités de l’objet Realm persist. Comme le montre la figure 2
isEmailSubscriptionEnable
nous déclarons commeRealmOptional
Bool signifie qu’il peut être nul que nous avons utilisé avec let car c’est un type de référence et nous ne voulons pas que son adresse change à l’avenir. - Comme le montre la figure 2, l’utilisateur peut avoir de nombreux todos qui sont une collection d’objets Realm Todo. Liste en tant que classe de domaine pour contenir la collection des instances d’objet de domaine. Nous avons créé une relation à plusieurs avec le modèle Todo. Relation To-many, dans laquelle un objet de domaine pointe vers une collection d’objet de domaine. Si vous utilisez un tableau Swift normal pour stocker la collection de domaines d’objets, vous obtiendrez une exception. Remarque: Comme la liste RealmOptional ne peut pas être déclarée comme mot-clé dynamique et @objc car c’est une classe Realm avec toutes les fonctionnalités intégrées. List est très similaire à Array pour les méthodes intégrées et l’accès aux objets à l’aide d’un abonnement indexé. La liste comme vous le voyez est tapée et tous les objets doivent être du même type
-
isUserHasTodos
est une propriété swift calculée et ne sera pas stockée dans la base de données realm qui renvoie si l’utilisateur a des tâches à faire ou non. - Enfin, nous faisons
userId
etfirstName
comme propriétés indexées. En remplaçant la méthode statiqueindexedProperties
, nous fournissons un tableau de propriétés sous forme de chaîne. Nous indexons les propriétés pour améliorer les temps d’accès lors du filtrage ou de l’interrogation de la base de données
Modèle de passeport
Comme le montre la figure 3, nous avons créé un modèle de passeport avec les quelques propriétés
-
passportNumber
stocke les informations de passeport etexpiryDate
stocke la date d’expiration du passeport que nous voulons que ces propriétés stockent c’est pourquoi nous utilisez le mot-clé@objc
avec le mot-clédynamic
pour dire au royaume de faire votre magie sous le capot - Nous avons créé la propriété
passport
sur le modèleUser
qui signifieUser
objet ont leurpassport
référence d’objet que faire si nous voulons que l’objet passeport sache également quel utilisateur a ce passeport / avoir une référence à l’utilisateur associé à ce passeport. Nous avons créé les backlinks à l’aide de LinkingObjects, ce qui signifie que nous avons créé la propriétéofUser
dans Passport qui contient une référence de tous les objets utilisateur qui attribuent l’objet Passport dans sa propriétépassport
. Dans les données de base, on l’appelle relation inverse. C’est une collection dynamique qui vous indique qui est lié à l’objet actuel.
As shown in Figure 4 we created Todo
Realm model with has a backlink to the all the users pointing to particular task .
Nous avons terminé avec la création de modèle / schéma et maintenant il est temps de faire l’opération CRUD réelle
Ajouter un objet au domaine
Nous avons d’abord effacé un concept, puis nous pourrons facilement ajouter un objet dans le domaine
Comme le montre la figure 5, nous commençons par obtenir une instance de la valeur par défaut Realm
en l’initialisant sans aucun argument. La seule façon d’accéder à la base de données via une instance de domaine. Une instance Realm
(également appelée « un domaine ») représente une base de données de domaine.Les royaumes peuvent être stockés sur disque (voir init(path:)
) ou en mémoire (voir Configuration
) nous verrons dans les parties à venir. les instances Realm
ne sont pas sûres pour les threads et ne peuvent pas être partagées entre les threads ou les files d’attente de répartition. Vous devez construire une nouvelle instance pour chaque thread dans lequel un domaine sera accessible.
Comme le montre la figure 5, car il s’agit d’une nouvelle application et qu’aucun objet n’a été stocké dans la base de données realm.isEmpty
renvoie true signifie que la base de données est vide telle qu’imprimée sur la console
Comme le montre la figure 6, nous avons effectué un nombre de tâches
- Nous obtenons l’instance de
Realm
base de données - Créée
Passport
et trois tâches en tant quetodos
- Créé
User
objet et lui attribuer un passeport et des tâches. En plus de cette propriété facultative de domaine initialisée qui estisEmailSubscriptionEnable
etUsertype
énumération avec appartenance gold
Comme le montre la figure 6, la base de données de domaine est toujours vide et l’objet relation / Liaison inverse ne fonctionne pas non plus car nous n’avons pas ajouté ces objets au domaine. Les objets de domaine (User, Passport, Todo) peuvent être instanciés et utilisés comme objets non gérés (c’est-à-dire non encore ajoutés à un domaine) tout comme les objets Swift réguliers. Pour que ces objets soient gérés par Realm, vous devez les ajouter dans Realm
Comme le montre la figure 7, nous insérons enfin l’objet dans la base de données du royaume. Nous avons effectué une insertion en cascade dans la base de données.
Remarque : Toutes les modifications apportées à un objet (ajout, modification et suppression) doivent être effectuées dans le cadre d’une transaction d’écriture.Les opérations d’écriture de domaine sont synchrones et bloquantes, et non asynchrones. Si le thread A démarre une opération d’écriture, le thread B démarre une opération d’écriture sur le même domaine avant que le thread A ne soit terminé, le thread A doit terminer et valider sa transaction avant que l’opération d’écriture du thread B ait lieu. Les opérations d’écriture sont toujours actualisées automatiquement afin qu’aucune condition de concurrence ne soit créée. L’opération d’écriture peut générer des erreurs comme manquer d’espace disque
- Nous avons ajouté User à votre royaume, et comme il fait référence à passport et todos, ces objets sont également ajoutés au Royaume.
- En ajoutant un objet non géré à realm, nous avons géré ces objets maintenant comme indiqué dans la console, nos backlinks fonctionnent. Maintenant, passport peut également accéder à l’objet utilisateur. Maintenant, notre base de données n’est plus vide
- Nous insérons enfin un objet dans la base de données puisque nous insérons un objet que nous devons ajouter dans le bloc de transaction d’écriture et que nous ajoutons dans le domaine en utilisant la méthode add sur l’instance de domaine. Maintenant, si un autre objet séparé avec la même clé primaire de l’utilisateur avec
userId = 1
est tenté d’être ajouté en tant qu’objet séparé au Royaume, une exception sera déclenchée
Vérifiez le stockage physique de l’objet
En exécutant cette commande sur la sortie du débogueur, vous obtenez l’adresse du fichier de domaine où vos données sont stockées
Open
default.realm
dans Realm Studio
Realm Studio est notre premier outil de développement, conçu pour que vous puissiez facilement gérer la base de données et la plate-forme de Realm. Avec Realm Studio, vous pouvez ouvrir et modifier des domaines locaux et synchronisés, et administrer n’importe quelle instance de serveur d’objets Realm. Téléchargez-le maintenant pour Mac, Windows ou Linux.
Comme le montre la figure 10 données réellement stockées. Vous pouvez vous demander la classe Article
et Person
également là car dans certaines de mes classes de projet, créez des modèles Personne et article. Lorsque l’application s’exécute, Realm introspecte toutes les classes de votre application et de vos frameworks et trouve les classes qui sous-classent la classe Objet de Realm. Il considère la liste de ces classes comme votre schéma de données qui sera persisté sur le disque ou en mémoire.
Récupérer l’objet du domaine
Le processus de récupération de tous les enregistrements utilisateur du domaine a les tâches suivantes
- Nous obtenons l’instance de la base de données du domaine et elle peut lancer: Un
NSError
si le domaine n’a pas pu être initialisé. Le domaine par défaut est créé lorsque nous appelonsinit()
sans paramètre - Méthode d’objets appelés sur la base de données du domaine qui retournera tous les objets du type donné stockés dans le Domaine et retournera un Résultat avec tous les objets comme indiqué sur la figure 11
- Objet imprimé sur la console pour valider que les données sont là et que la liaison des objets fonctionne correctement
Nous avons récupéré l’utilisateur enregistrer à partir de sa clé primaire qui est également une propriété indexée afin que nous obtenions l’objet utilisateur facultatif car l’objet avec cette clé primaire pourrait ne pas exister. La clé primaire peut être Int
ou String
La recommandation est d’utiliser String.
Elle identifie de manière unique des objets spécifiques dans une base de données de royaume.Une fois qu’une valeur de clé primaire a été définie sur un objet spécifique, elle ne peut jamais être modifiée.
Comme indiqué, nous avons filtré en utilisant un prédicat Voici la liste des opérateurs que nous avons utilisés
- filter → correspond à des valeurs égales à
- filtre insensible à la casse → correspond à des valeurs égales à ignorer la casse
- DANS {1,2,3} filter → correspond à la valeur d’une liste de valeurs.
- filter → correspond si la valeur FirstName commence par a.
- filter → correspond si la valeur FirstName conatine avec li.
- Prédicat avec l’objet Passport nous voulons filtrer l’utilisateur qui a un numéro de passeport == ‘pass1’
- Prédicat avec l’objet Todos nous voulons filtrer l’utilisateur qui a un tdodo contient des détails == ‘Besoin de créer un blog RxSwift’
Pour les requêtes avancées, Il est fortement recommandé de voir https://academy.realm.io/posts/nspredicate-cheatsheet/
Pour les requêtes avancées, Il est fortement recommandé de voir https://academy.realm.io/posts/nspredicate-cheatsheet/
Remarque: Ce que vous appelez des « propriétés transitoires (calculées) », Realm se réfère à des « propriétés ignorées ». Ce sont des propriétés qui sont pour la plupart ignorées par Realm, elles ne seront donc pas stockées dans le fichier db, peuvent être mutées en dehors des transactions d’écriture, etc.Cependant, cela signifie également qu’ils ne bénéficient pas de nombreuses fonctionnalités des propriétés non ignorées, telles que les requêtes. (querying for Realm objects can only be done with non-computed, Realm-persisted properties)
As shown in Figure 14 we sorted results with the firstName
property on User model
Résultats en direct
Dernier sujet lors de la récupération à partir de la section de domaine
Les ensembles de résultats de domaine renvoient toujours les dernières données à jour. Les données dans les résultats ne sont jamais obsolètes. Cela signifie que vous n’avez jamais à recharger les résultats du disque ou à actualiser manuellement les données en mémoire.
Comme le montre la figure 15, nous avons obtenu le nouvel utilisateur et nous n’avons pas récupéré en utilisant la méthode realm.objects
à la place, les objets nouvellement ajoutés sont présentés sur la variable users. Si vous venez de l’arrière-plan des données de base, vous devez à nouveau récupérer l’objet de la pile
La lecture et l’écriture peuvent se produire à différents endroits du projet, sur différents threads, à partir de différents processus ou, lors de l’utilisation de la plate-forme Realm, de n’importe où dans le monde. Chaque classe de l’application peut se concentrer sur la logique métier et oublier la notion de données obsolètes ou mises en cache, car les objets Realm sont toujours à jour.
Modifier l’objet Sur le domaine
Comme le montre la figure 16, nous modifions la clé primaire et nous obtenons « La clé primaire ne peut pas être modifiée après l’insertion d’un objet. »exception car nous ne pouvons pas mettre à jour la clé primaire. À partir des documents de domaine, la clé primaire est ajoutée à un domaine, la clé primaire ne peut pas être modifiée. Solution de contournement → Supprimez et réinsérez l’objet ou consultez cette question dans stackoverflow
Comme le montre la figure 17, vous ne pouvez pas modifier l’objet récupéré à partir du domaine en dehors du bloc de transaction d’écriture si vous essayez de modifier en dehors de cela, vous obtiendrez une exception « ‘ Essayant de modifier l’objet en dehors d’une transaction d’écriture — appelez beginWriteTransaction sur une instance RLMRealm en premier. »
As shown in Figure 18 as we modify object in write
transaction block it will persist that object into the disk as well as shown in Figure 19 default.realm
file now has a updated firstName
value of User
Le dernier exemple est très intéressant nous avons effectué les tâches suivantes pour mettre à jour l’utilisateur avec le nouvel utilisateur
- Nous obtenons l’utilisateur avec sa clé primaire
userId
qui est 1 - Créé un nouveau
User
avec la même clé primaire - Sur une transaction d’écriture que nous appelons add batch méthode de mise à jour avec update=true elle mettra à jour l’utilisateur ayant la clé primaire = 1. If update = false it will throw an exception since two objects can’t have same primary key as shown in Figure 20 and 21
Delete Object From Realm
Any objects currently les liens vers les liens supprimés définiront leur propriété de liaison sur nil. Si ces objets sont liés à partir de propriétés de liste, ils sont supprimés des listes en question.
As shown in Figure 22 and 23 we deleted User object having firstName == ‘ali new User’
As shown in Figure 24 we empty Realm database using deleteAll()
method in objet realm. Comme le montre la figure realm.isEmpty
renvoie true
Parfois, vous devez créer une sorte de hiérarchie entre les objets de royaume, comme vous avez l’habitude de le faire avec les classes Swift. Malheureusement, Realm ne prend actuellement pas en charge l’héritage d’objets prêt à l’emploi. contournement: https://forum.realm.io/t/inheritance-with-realm-confusion/153
Useful Links
https://www.raywenderlich.com/9220-realm-tutorial-getting-started
https://www.appcoda.com/realm-database-swift/
https://realm.io/docs/swift/latest/#to-many-relationships
https://realm.io/docs/swift/latest/#optional-properties
https://academy.realm.io/posts/nspredicate-cheatsheet/
https://academy.realm.io/posts/nspredicate-cheatsheet/