Mises à jour d'application et ajout de contenu

Bonjour tout le monde,
Je me posais une petite question par rapport aux mises à jour d’une application, et l’ajout de contenu dans celle-ci.

Je m’explique:
Si je possède une application tel qu’un jeu (imaginons CandyCrush pour que tout le monde visualise), et que les différents niveux de jeu sont stockés en base de donnée, mon jeu est en version 1.0 et possède 20 niveaux (par exemple), ensuite j’aimerai sortir une version 1.1 et ajouter 20 niveaux supplémentaires, comment est-ce que je peux le faire?
Je les ajoutes manuellement en base de données (puisque des niveaux sont justes des paramètres dans la base de donnée) et ensuite dans ma version mise à jour, je charge ces données au premier lancement de l’application?
Existe-t’il un moyen plus simple/pratique, et peut être plus propre pour effectuer des mises à jour de contenu?

Merci d’avance,

Alexandre

Tu te compliques la vie inutilement. Crée une version 1.1 de ton application, avec les nouveaux niveaux dans la base de données et place-la sur le Store. Quand l’utilisateur verra une pastille rouge sur l’application et téléchargera la nouvelle version, iOS vas récupérer tous les fichiers de la mise à jour en effaçant les anciens, remplaçant automatiquement la base de données 1.0 par la version 1.1.

Bonjour @Draken,

Oui, mais si, dans la base de données, il y a des entrées par l’utilisateur, je ne peux pas juste effacer la base de donnée et la remplacer par la nouvelle… sinon je perds les informations utilisateurs…
Non?

Merci,

Alexandre

Ça, c’est une très mauvaise idée… Il faut toujours stocker les données utilisateurs indépendamment des données systèmes des applications, dans des fichiers séparés. Et ce pour des tas de bonnes raisons, dont l’effacement des données utilisateurs en cas de mise à jour n’est qu’un aspect.

Normalement, ce n’est pas possible. On ne peut pas modifier le contenu d’un fichier contenu dans le bundle d’une application. Le bundle c’est l’ensemble des fichiers (données, images, sons, textes, etc…) fournis avec une application. Le bac à sable de chaque application iOS étant sécurisé, on ne peut écrire des données que dans un répertoire spécial réservé aux données utilisateurs.

Enfin en théorie. Si les données systèmes du jeu ne sont pas fournies avec l’application, mais téléchargés plus tard à partir d’un serveur, ils seront écrits dans le répertoire utilisateur et donc modifiables. Mais je maintient que c’est une mauvaise idée.

Quelques exemples de problèmes potentiels :


Tu fais une erreur dans la création du niveau 19, un petit bug dans un recoin obscur que le joueur n’atteint qu’une fois sur 100. Tellement rare que tes testeurs ne l’ont pas rencontrés mais qui fait planter le jeu quand cela se produit. Une personne (ils sont sacrément vicieux ces joueurs !) vas forcément tomber dessus, hurlant à la mort sur l’AppStore. Tu places un correctif sur l’AppStore et là, paf … plus de bugs mais TOUTES les sauvegardes joueurs sont mortes. Là c’est l’émeute et tu n’ose plus sortir dans les rues qu’après 23 heures en te cachant le visage pour faire tes courses.


iOS sauve automatiquement les données de tes applications sur iCloud, quand le Wifi est actif et que le device se recharge. Les données des jeux ne prennent généralement pas beaucoup de place, quelques centaines d’octets ici et là (liste des scores). Si les données systèmes et les données utilisateurs sont présentes dans un seul fichier, iOS devra sauver l’ENSEMBLE sur le cloud, ce qui peut prendre BEAUCOUP de place mémoire, un sérieux gaspillage, surtout que l’on n’a que 5 Go de données gratuites. Après il faut dégainer la carte bleu …

Vu comme tu l’exposes, tu as tout à fait raison!

Dans la pratique par contre, j’ai plus de mal à voir comment faire: j’utilise une base de donnée pour stocker les données de l’utilisateur, mais comment est-ce que je peux séparer les données utilisateurs des données systèmes? Surtout si je dois faire des liens entre les deux? (Scores de l’utilisateur et les niveaux sur lesquels celui-ci a fait les scores par exemple)

Merci pour toutes ces explications! :slight_smile:

Alexandre

En regardant un peu, j’ai vu que les .plist étaient une solution?
Mais dans ce cas, imaginons que je mets les informations des niveaux dans un fichier .plist, comment faire ensuite pour lier les niveaux (.plist) dans la DB avec les scores utilisateurs par exemple?

Euh … je ne suis pas un grand spécialiste en base de données, mais avec CoreData on peut avoir plusieurs bases de données dans la même application. Je ne sais quelle base de données tu utilises, mais tu devrais pouvoir en utiliser deux : une « inamovible » fournie avec l’application contenant les données du jeu et une autre, créé localement pour les scores.

Il n’est pas utile d’avoir un lien entre les deux bases, puisque les niveaux sont identifiés par leurs numéros.

Dans la base système, il suffit de pouvoir accéder aux données du niveau N.

Et dans la base des scores tu as juste besoin de lire/écrire le score du niveau N. Et enregistrer une liste (un tableau) des meilleurs scores. Si je devais coder ça, j’écrirais les données dans un tableau ou un dictionnaire que je stockerais dans un fichier binaire, ou dans le NSUserDefaults de l’application.

Oups, désolé je n’avais pas vu ta question. Nous avons dus poster quasiment en même temps.

Pour accéder aux niveaux du .plist, il suffit de définir celui-ci comme un dictionnaire, utilisant les numéros des niveaux comme clé d’identification.

Merci pour toutes ces réponses! :slight_smile:

Je vais creuser encore un peu, voir les possibilités que j’ai, en fonction de ce que j’ai besoin, mais dans tous les cas, comme tu as dis: bien séparer les informations systèmes des informations utilisateurs.

Merci encore,

Alexandre.

Tu peux par exemple utiliser des plist pour définir tes niveaux et une base de données (SQLite, realm, etc.) pour tes données utilisateur.
Tes plist seront en lecture seule et ta base sera spécifique à chaque utilisateur.

Bonjour @mbritto et @Draken,

Je pense partir sur des fichiers .plist pour les données systèmes et une base de donnée (Realm ou CoreData, je ne sais pas encore) pour les données utilisateurs.

Cependant, il me reste une question:

Imaginons que j’ai besoin d’une base de donnée comme celle suivante (schéma de base de donnée comme si il n’y avait que une seule DB, en MySQL par exemple):

Donc en résumé:
J’ai 4 tables dans ma base de donnée: une table pour les niveaux (du jeu), une table pour les sons (qui sont joué dans mes niveaux, un niveau pouvant avoir plusieurs sons, et un même son pouvant être dans plusieurs niveaux), une table pour les parties (jouées par le joueur) et une table joueur (dans le cas où un joueur peut avoir plusieurs comptes par exemple).

Si j’ai bien compris, les données systèmes seraient les tables: niveaux, sons, et niveaux_sons.
Et les données utilisateurs: parties et joueurs.

Les données systèmes étant les données qui ne change pas lorsque le joueur joue, et les données joueurs étant les données que le joueur fait évoluer au fur et à mesure qu’il joue.

Si je sépare donc ces bases de données dans un fichier .plist et le reste dans une base de donnée, pour faire le lien entre mon fichier niveaux.plist et ma table parties, je devrais alors utiliser l’ID du niveau (contenu dans mon fichier .plist) pour le stocker dans ma table parties, juste?
Ce qui revient, si nous étions dans le cas d’une seule base de donnée, à deux tables sans relations définie directement dans la base de donnée.
Donc, si j’ai 20 niveaux par exemple, la base de donnée acceptera un id_niveau « 21 » même si le niveau n’existe pas. Je dois alors faire les vérifications dans mon code directement au lieu de laisser la base de donnée gérer tout ça (comme en Web avec MySQL par exemple)?

Ensuite, pour la table « niveaux_sons » qui est en fait la table d’une relation many to many dans une base de donnée traditionnelle, dans mes fichiers .plist, je devrai alors également créer un fichier niveaux_sons.plist, qui servirait de lien entre mon fichier niveaux.plist et sons.plist?

En séparant en deux ma base de donnée (fichier .plist et Realm ou CoreData), j’ai peur que ce ne soit pas maintenable dans le temps (je pense que c’est surtout dû au fait que je n’ai pas l’habitude de faire comme ça)… Mais comme l’a dit @Draken plus haut, séparer les données utilisateurs des données systèmes me parait vraiment bien, car alors, dans ce cas-ci, par exemple, lorsque je dois ajouter des niveaux, ou des sons, je les ajoutes dans mes fichiers .plist et je n’ai « plus qu’à » les pousser sur l’AppStore pour que les joueurs en profite, et je ne modifierai donc pas les données utilisateurs.

(Le schéma de la base de donnée n’est pas vraiment complet, je l’ai un peu simplifié, puisqu’il ne sert qu’à illustrer mon exemple)

Merci de m’avoir lu et merci pour vos commentaires :slight_smile:,

Alexandre.

La base de donnée (plist ou autre) doit contenir une clé indiquant le nombre de niveaux qu’elle contient, que le code devra lire, oui…

Euh … ne parlant pas le langage base de donnée, je ne comprend pas trop ce que tu dis (relation many to many ?). Les sons sont généralement enregistrés dans l’application sous la forme de fichiers .wav (bruitages numériques) et .mp3 (musique).
Exemple : music1.mp3, music2.mp3, hurlements.wav, intro.wav, gameover.wav, etc …

Tu as besoin d’y moyen de retrouver le nom du fichier à partir d’un identifiant. Un nom par exemple :

SON_MUSIC1 → music1.mp3
SON_MUSIC2 → music3.mp3
SON_INTRO → intro.wav
SON_GAMEOVER → gameover.wav

Moi je ferai cela avec un plist contenant un dictionnaire.

@Draken

Many to many, c’est une relation plusieurs à plusieurs, par exemple, si j’ai une table ANIMAUX et NOURRITURE, un animal peut manger plusieurs nourritures (patés, croquettes, …) et une nourriture peut être mangé par plusieurs animaux (un chat peut manger une pâtée, un chien aussi).

Donc une relation Many to Many (dans les base de donnée traditionnelles) permet d’avoir une table intermédiaire pour ne pas avoir une table ANIMAUX avec des champs comme: nom, nourriture1, nourriture2, nourriture3 par exemple. Parce que sinon, comment faire pour les animaux qui mangeraient plus que 3 nourriture? Et ceux qui ont que une nourriture, il y aurait 2 champ vide dans la base de donnée…

Je sais pas si c’est plus ou moins clair, un peu de mal à l’exprimer :thinking:

Pour les sons, oui, c’est ce que je pensais faire, “stocker” les sons sous forme de texte dans un fichier .plist, histoire de pouvoir les lier à d’autre tables (ou fichier .plist)

Mais donc, le fait d’avoir une partie en fichier .plist, et une partie en base de donnée ne posera pas de soucis si j’ai bien compris?

Merci,

Alexandre.

Aucun problème, tant que le code sait comment récupérer l’information dont il a besoin. Tu peux utiliser des .plist, des bases de données, des fichiers binaires, des fichiers textes et d’autres choses encore dans la même application.

Par exemple, tu peux définir les niveaux d’un jeu à la CandyCrush avec des fichiers textes, en associant chaque type de bonbon à un caractère, dans ce style (0 = case vide):

00000000000000
0000AA00BB000
00H0HKLT00000
0000GGGGGG0
0000AAAAAAA0
0BBBBBBBBB0

Merci, je vais regarder comment bien structurer tout ça alors :slight_smile: