Création d'une base de donnée non modifiable ?

Bonjour à tous et à toutes,
Petite question de novice : j’ai un petit projet d’app qui nécessite de manipuler une base de données.
Maxime nous apprend à utiliser Realm, qui parait très séduisant.

Dans mon cas, l’utilisateur doit utiliser cette base de donnée afin d’afficher des éléments graphiques dans une vue du storyboard.
Cette base de donnée préétablie est donc consultée par l’utilisateur mais celui-ci ne pourra pas la modifier.
Est ce que Realm est adapté ?

Le corolaire est qu’il faut que je remplisse moi-même cette base de donnée. Comment faire ?

  • éditer le fichier Realm dans RealmBrowser ? pas forcément très pratique
  • me créer une seconde app B rien que pour moi afin que je remplisse la base de donnée de l’app A (celle de l’utilisateur) ? mais peut-on alors transférer cette base de donnée d’une app B vers l’app A ?
  • une autre idée ?

Merci bcp pour votre aide

Bonjour,
Peut-être regarder du côté des fichiers pList (property list).
Ce sont des fichiers qui sont en lecture seule (si je ne me trompe pas), donc accessible par l’utilisateur sans modification possible de sa part, et que tu auras très facile à modifier si tu en as besoin.

Quand une application s’installe sur un device à partir du Store, elle est placée dans son propre espace mémoire, totalement autonome. On appelle cela un « bac à sable ». Une application ne peut voir que son propre bac à sable, sans pouvoir lire ou écrire dans ceux de ces petits camarades. C’est une mesure de sécurité évitant qu’une application "malicieuse » ne puisse voler les données des autres bacs à sable.

Un bac à sable est composé de deux parties : le bundle et l’espace utilisateur.

Le bundle c’est l’ensemble des fichiers fournis avec l’application (le code exécutable, les icônes, les images, les données créés par le développeur, les fichiers de localisation (Français, Anglais, Zoulou, Klingon , etc…). Ces fichiers ne sont pas modifiables !

iOS ne permet que la lecture du bundle, pas sa modification. Quelque soit la façon de ta base de données a été construite, elle ne sera pas modifiable par l’application. Impossible de la modifier, impossible d’y rajouter des informations, impossible d’en supprimer une partie.

Si les exemples de Maxime fonctionnent, c’est parce que Realm (ou CoreData, UserDefault, ou autre type de fichiers) stockent leurs données dans l’espace utilisateur, la seconde partie du Bac à Sable.

Ce qu’il est possible de faire c’est générer une base de données avec une application, de lui donner un nom significatif, et copier le fichier dans le bundle de ta première application.

Je ne connais pas Realm, donc je vais t’expliquer ça de manière théorique.

Tu veux créer une application Maison3D comprenant une bibliothèque d’objets (chaise, table, frigo, tv, lit, etc…). Pour cela :

  • Tu commences par créer une application Editeur3D pour créer des objets et les stocker dans une base de données InfosObjets.
  • Tu récupères le fichier InfosObjets.quelqueChose sur le disque, pour le copier dans le bundle de Maison3D
  • Tu écris des fonctions permettant de lire le contenu de la base de données InfosObjets pour les insérer dans Maison3D
  • Tu compiles, Xcode fabrique alors un bundle contenant InfosObjets. Si tu distribue l’application sur le Store, InfosObjets sera présent à l’intérieur, avec les autres fichiers.

Si tu as besoin de gérer des informations persistantes, l’application devras créer une NOUVELLE base de données dans l’espace utilisateur. Il faudra faire attention à ne pas se tromper de base en lisant les informations. Je ne sais pas si Maxime a expliqué comment utiliser plusieurs bases de données dans la même application, l’une dans le Bundle et l’autre dans l’espace utilisateur.

Le terme « base de données » est un peu flou, sachant qu’on peut stocker les informations dans différents fichiers. Cela peut être du XML, du JSON, des Plists, des fichiers textes, du CoreData, du Realm ou encore des fichiers binaires. Tout dépend de la nature des données et des besoins spécifiques de l’application.

Ils sont en lecture seuls quand ils sont dans le Bundle. Si c’est l’application qui les crée dans l’espace utilisateur, ils sont en lecture/écriture. D’ailleurs le UserDefault est un plist !

Intéressant :slight_smile:

Je rectifie ce que j’ai dis alors: s’il crée un fichier pList lui même (que ce n’est pas son application qui la génère), alors le fichier sera en lecture seule, juste?

Quand tu dis que ça ne doit pas être modifiable par l’utilisateur, tu veux dire “dans l’app uniquement” ou tu veux même empêcher quelqu’un qui aurait un accès aux fichiers de le modifier ?
Si c’est juste dans l’app, alors prend le format le plus pratique pour toi (plist, SQLite, xml, json, realm, etc) et inutile de se préoccuper de lecture/écriture. Il te suffit de n’utiliser cette base qu’en lecture dans ton code.
Par contre si tu veux éviter que les bidouilleurs n’y accèdent, alors il te faut utiliser une ressources du bundle et non un document crée à l’exécution.
Tu peux aussi passer pas un webservice rest qui t’envoie des données en json. L’avantage c’est que tu peux changer ces données à distance sans passer par une maj AppStore

De base les pList sont en lecture/écriture. On peut les lire et les écrire à volonté. Mais comme iOS bloque en écriture tout ce qui se trouve dans le Bundle, les pList fournis avec une application sont en lecture seule.

On peut les re-transformer en lecture/écriture en les recopiant dans l’espace utilisateur, au premier lancement de l’application.

Merci bcp pour vos réponses rapides.
À Draken : ton exemple avec maison3D est EXACTEMENT ce que je souhaite réaliser
J’aurais besoin de me créer une interface d’édition pour créer cette base de données et l’améliorer au fil du temps.
Le fichier créé sera ensuite inséré dans l’app.

Cette base de donnée sera en lecture seule pour l’utilisateur.
L’app ne permettra pas à l’utilisateur de l’éditer.
Dans l’idéal un bidouilleur ne doit pas pouvoir récupérer ce fichier mais c’est pas un impératif si ça complique les choses.

J’envisageait d’utiliser les mises à jour de l’appstore pour répercuter mes modifs aux utilisateurs
Passer par un webservice comme suggère Maxime serait une solution très élégante. Peut être un peu compliqué pour un novice comme moi !

C’est dans l’air du temps. IKEA sort la semaine prochaine son application ARKit !

Draken : Je me suis mal fait comprendre, désolé
Je n’ai pas du tout l’intention de faire une appli de modélisation d’intérieur :grin:
C’est bien ton concept qui correspond à ce que je souhaite faire :thinking: : une appli “user” pour l’appstore et une appli “éditeur” pour moi.

D’accord.
Ce n’est pas « mon" concept, mais une architecture logicielle archi-classique, utilisé depuis la préhistoire de l’informatique.

Bonjour, juste une remarque, Maxime dans son cours de l’an dernier préconise et utilise Realm. J’ai suivi scrupuleusement le cours et mis en pratique l’exemple. Mais j’ai trouvé realm un peu compliqué. En outre, j’ai constaté qu’il était très mouvant et demandait de fréquentes mises à jour, alors, j’ai essayé core data. Et j’ai été émerveillé par sa simplicité… Tout va tout seul y compris la réalisation des bases de données…

Heu… tu as trouvé CoreData plus simple que Realm ? Faut que je revoie ma pédagogie sur ce coup là :frowning:

1 « J'aime »

Oui, on définit sa base graphiquement, puis on utilise ses objets directement en les sauvegardant par une fonction ajoutée directement par Xcode à AppDelegate, save context. Après, on dispose aussi d’un fetch, bref, c’est comme si on manipulait des données ordinaires… Je pense que c’est arrivé sur les versions de Xcode de 2017…

Realm reste beaucoup plus simple à utiliser que CoreData, à part l’outil graphique pour générer tes classes qui n’existe pas dans Realm, tout le reste existe et demande moins d’étapes pour chaque action :slight_smile:

D’accord avec maxime ! Même si une fois que l’on a creusé CoreData on peut faire des choses magnifique avec une grande simplicité. J’entend par la afficher une TableView remplis avec le contenu de CoreData juste en utilisant un controller spécifique (NSFetchedResultsController) ou encore l’intégration spotlight native (je l’ai testé dans un cadre pro et ça envoi un max ^^).

Cependant même cette intégration avancée au téléphone pour ma part ne contre balance pas la facilité d’utilisation de Realm pour la vie de tous les jours je pense à la serialization en JSON par exemple, après tous dépend de ton cas d’utilisation, si tu ne fait que consommer de la donnée saisie par l’utilisateur CoreData peut avoir sont charme par contre (d’expérience) Realm est plus simple à utiliser quand tu “caches” des données qui viennent de WebService.

Pourquoi pas enrichir le cours avec les “Capabilities” type App Groups, Data Protection… pour rebondir sur les questions de partage de données cross-application ?

1 « J'aime »

Mon petit projet personnel semble impliquer des bases de données et du coup, je me suis aussi posé cette question de la méthode. Je croyais m’être laissé convaincre par Maxime à propos de realm quand j’ai réalisé que j’étais dans une impasse à cause de l’organisation des données que je souhaiterais utiliser avec des relations entre bases.
Dans la doc de realm, on lit qu’une personne peut posséder plusieurs chiens (to-many, si j’ai bien compris) et on utilise la syntaxe List<>().
Mais si le chien a plusieurs colliers qui lui sont personnels, n’est-on pas coincé par le fait que List n’accepte pas de List ?

Bonjour @nathalex

Si ton chien a plusieurs collier, tu peux faire une liste de collier (ou de String) pour ton chien, pas besoin d’une liste de liste je pense.

Par exemple:

class Chien: Object {
    var colliers:List<String> = List<String>()
    @objc dynamic var maitre:Personne?
} 

class Personne: Object {
    @objc dynamic var prenom:String = ""
    var chiens:List<Chien> = List<Chien>()
}

Ainsi, tu as des personnes qui peuvent avoir plusieurs chiens, et un chien peut avoir plusieurs colliers qui lui sont propres.

Merci pour la réponse. Je vais devoir maintenant réfléchir si ça rentre bien dans mes cases :wink:
Parce que je n’ai pas dit mais les colliers ont en plus leur tissu :smiley:

Si les colliers ont des caractéristiques différentes en fonction d’un type de collier ou d’un autre, il serait intéressant d’en faire une classe je pense, ainsi tu peux mettre les différents types de tissu, leur couleurs, etc etc. :slight_smile: