NSUserDefaults persiste-t-il lors d'une mise à jour vers une application dans l'Appstore?

106

Est-ce le cas? NSUserDefaults est-il réinitialisé lorsque vous soumettez une mise à jour à une application sur l'App Store, ou sont-ils réinitialisés?

Mon application plante lorsqu'elle est mise à jour mais ne plante pas lorsqu'elle est téléchargée complètement - j'essaie donc de déterminer ce qui pourrait éventuellement être différent dans la session mise à jour de la session fraîchement téléchargée.

Bravo, Nick.

Nick Cartwright
la source
Les fichiers dans Documents et Library seront conservés comme le prétend la documentation: developer.apple.com/library/ios/#DOCUMENTATION/iPhone/…
Geri Borbás

Réponses:

116

Ils ne sont généralement pas réinitialisés à moins que l'utilisateur ne supprime l'application. Pour les données de base, NSUserDefaults est le meilleur moyen de sauvegarder des données telles que les préférences, les dates, les chaînes, etc. Si vous cherchez à sauvegarder des images et des fichiers, le système de fichiers est un meilleur choix.

Coneybeare
la source
5
Est-ce que cela est mentionné quelque part dans la documentation Apple?
Nick Cartwright
1
Désolé - j'ai oublié de vous remercier pour votre réponse rapide! - Si quelqu'un peut trouver un lien vers n'importe quelle forme de documentation Apple qui le dit, ce serait excellent .... Dans la documentation de NSUserDefaults, cela ne dit rien à ce sujet, donc je pense que j'avais (à tort) supposé que les valeurs par défaut étaient effacées. Cela semble être le moyen le plus sûr pour Apple de mettre à jour les applications!
Nick Cartwright
C'est peut-être le moyen le plus sûr, mais il serait extrêmement ennuyeux pour les utilisateurs de redéfinir toutes leurs préférences chaque fois qu'une application est mise à jour. J'ai généralement trois ou quatre mises à jour d'applications par jour; Je suis sûr que d'autres utilisateurs d'iPhone en ont encore plus. Effacer les préférences pour chaque mise à jour rendrait mon iPhone inutilisable.
Kristopher Johnson
1
Les données du dossier des documents peuvent disparaître aussi facilement que NSUserDefaults. Ce sont deux occasions rares, cependant, et n'ont absolument rien à voir avec le processus de mise à niveau normal
coneybeare
1
Merci Kristopher - et oui je suis d'accord. Mon problème était que j'avais utilisé NSUserDefaults pour stocker des événements programmatiques et que j'avais compté sur leur réinitialisation lors de l'installation de l'application. Tous mes tests sur l'appareil iPhone (et les tests Apple) ont testé l'application en tant que nouvelle installation. Sans aucune documentation ni moyen de tester en tant que mise à jour, je n'ai pas pu répéter le crash de la mise à jour que tous nos clients connaissent actuellement. Pour résumer - probablement une leçon apprise à la dure !!
Nick Cartwright
7

Je crois que la réponse est OUI, elle persistera. Ceci est également entièrement documenté dans le chapitre Répertoire des applications du Guide de programmation Apple iPhone OS.

Léon
la source
4
  1. Réponse directe à la question posée: OUI.
  2. Votre problème: votre application plante en raison de problèmes de logique. Supposons que vous stockiez un objet dans les valeurs par défaut et que l'application vérifie sa valeur au lancement (ou ailleurs). Dans votre mise à jour, vous pouvez changer la façon dont il est vérifié ou utilisé, par exemple vous attendez une valeur, mais l'objet est nul, ou vice versa. Cela peut provoquer un SIGABRT ou EXC_BAD_ACCESS.
John Smith
la source
2

Si vous aviez le modèle CoreData et que vous avez changé quelque chose dans votre modèle et votre mise à jour, sans gérer la migration, c'est probablement la raison pour laquelle votre application se bloque lors de la mise à jour ...

Bojan Bozovic
la source
Je m'attendrais à ce que ce soit un cas :) pas un NSUserdefault
Julian Król
1

J'ai une expérience similaire. Notre application stocke un numéro de version dans Settings.Bundle / Root.Plist. Cela s'affiche via l'application Paramètres de l'iPhone. Ce que nous constatons, c'est que sur une installation, le numéro de version est chargé à partir du bundle d'applications - donc le numéro de version est correct. Lors d'une mise à jour, le numéro de version ne change pas. Cela donne l'impression que l'utilisateur exécute une version précédente de l'application. Nous n'avons pas de logique liée au numéro de version, c'est juste pour l'affichage (il pourrait être utilisé par le personnel du centre de contact lors du diagnostic des pannes).

Notre expérience est que NSUserDefaults n'est pas effacé lorsqu'un utilisateur met à jour notre application, mais l'affichage des paramètres n'est pas non plus mis à jour.

Derek Knight
la source
0

Soyez conscient de ce cas, lorsque votre application s'exécute en arrière-plan et que vous ne pouvez pas accéder à vos valeurs stockées dans NSUserDefaults:

Eric:

Il y a eu beaucoup de threads et de bogues à ce sujet, mais cela m'arrive à nouveau dans iOS 9. J'ai une application qui se lance en arrière-plan en réponse aux tâches NSURLSession et aux poussées disponibles sur le contenu. De manière reproductible, si je redémarre mon téléphone et attend qu'un lancement en arrière-plan de mon application se produise, lorsque j'ouvre l'application, je trouve que [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] contient toutes les valeurs système, par exemple AppleITunesStoreItemKinds, etc. mais ne contient pas l'une des valeurs que j'ai définies. Si je quitte et relance l'application de force, toutes mes valeurs reviennent. Existe-t-il un moyen d'éviter de mettre en cache le standardUserDefaults "vide" avant que le téléphone ne soit déverrouillé, ou du moins de déterminer quand ils sont en panne et de les réparer sans avoir à quitter l'application de force?

Eskimo ([email protected]):

Le problème ici est que NSUserDefaults est finalement sauvegardé par un fichier dans le conteneur de votre application et que le conteneur de votre application est soumis à la protection des données. Si vous ne faites rien de spécial, sur iOS 7 et versions ultérieures, votre conteneur utilise NSFileProtectionCompleteUntilFirstUserAuthentication, une valeur héritée par le magasin de sauvegarde NSUserDefaults, et vous ne pouvez donc pas y accéder avant le premier déverrouillage.

IMO, le meilleur moyen de contourner ce problème est d'éviter NSUserDefaults pour les éléments sur lesquels vous comptez dans les chemins de code qui peuvent s'exécuter en arrière-plan. À la place, stockez ces paramètres dans votre propre fichier de préférences, dont vous pouvez gérer explicitement la protection des données (dans ce cas, cela signifie «défini sur NSFileProtectionNone»).

Il existe deux problèmes avec NSUserDefaults dans un contexte de protection des données:

C'est une API entièrement abstraite: la présence et l'emplacement de son magasin de support ne sont pas considérés comme faisant partie de cette API, vous ne pouvez donc pas gérer explicitement sa protection des données.

Remarque Sur les versions récentes d'OS X, NSUserDefaults est géré par un démon et les personnes qui tentent de manipuler directement son magasin de sauvegarde ont rencontré des problèmes. Il est facile d'imaginer le même genre de chose arriver sur iOS à un moment donné.

Même si la modification de la protection des données était possible, NSUserDefaults ne dispose d'aucun mécanisme pour classer les données en fonction du contexte dans lequel vous l'utilisez; c'est une API «tout ou rien». Dans votre cas, vous ne souhaitez pas supprimer la protection de tous vos paramètres utilisateur par défaut, mais uniquement de ceux auxquels vous devez accéder en arrière-plan avant le premier déverrouillage.

Enfin, si l'une de ces données est vraiment sensible, vous devez la mettre dans le trousseau. Notamment, le trousseau a la capacité de définir la protection des données article par article.

Source: https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685

Grand M
la source