GoalLife sauvegarde dans UserDefaults _RawGoalList
J’ai :
let CLEF_USER = "azeroth"
var donnees = [Entre]()
class Entree {
var NB_ : Int
var ANNEE_ : String
var GARDE_ : String
var NOM_ : String
var DOMAINE_ : String
var TERROIR_ : String
var PHOTO_ : String
var COULEUR_ : String
}
En utilisant
UserDefaults.standard.set(donnees, forKey: CLEF_USER)
**** Crash [User Defaults] Attempt to set a non-property-list object (
(
“App.Entree”
)
) as an NSUserDefaults/CFPreferences value for key ClefUser
C’est tous a fait normal que cela ne fonctionne pas, en effet pour pouvoir stocker une class dans userDefault il faut que ta class puisse être encoder, pour sa tu doit rajouter quelque element.
Dans un premier temp il faut rendre ta class compatible avec l’encodage, et pour sa il faut la faire hériter de NSOBJECT tu doi également rajouté un méthode init, une foi effectuer tu doit rajouter 2 nouvelle méthodes comme ceci :
class Entree:NSObject {
var NB_ : Int
var ANNEE_ : String
var GARDE_ : String
var NOM_ : String
var DOMAINE_ : String
var TERROIR_ : String
var PHOTO_ : String
var COULEUR_ : String
}
init(nb:Int,anne:string…){
nb = NB
anne = ANNEE
…
}
// Cette fonction va encoder chaque variable de ta class
func encodeWithCoder(_ aCoder: NSCoder) {
aCoder.encode(NB, forKey: « nb »)
aCoder.encode(ANNE, forKey: « anne »)
…
}
//Decodage
required init(coder aDecoder: NSCoder) {
NB = aDecoder.decodeObject(forKey: « nb ») as! Int
ANNE = aDecoder.decodeObject(forKey: « anne ») as! String
…
}
Fait bien attention que les clé des fonctions coder et decoder soit bien les mêmes pour chaque variable.
Voilà notre class est prête, mais c’est pas terminer, pour pouvoir l’enregistrer (un foi initialiser bien sûr) il faut l’encoder
let myClass = ENTREE(nb:2,ANNE:2070,…)
let dataOject = NSKeyedArchiver.archivedData(withRootObject: myCLass)
UserDefault.standard.set(dataOject, forKey:« azeroth »)
Pour la récuprer c’est très simple
let decodeData = UserDefault.standard.object(forKey: « azeroth ») as? Data
//Comme tu voi ici le résultat est un optionel donc je t’invite a utiliser if let pour le tester
let myClass = NSKeyedUnarchiver.unarchiveObject(with: decodeData!) as! ENTREE
Je dirais de quelques centaines d’octets à 1 ou 2 Ko au maximum. Il est fait pour enregistrer quelques informations, pas des ensembles de données structurés, comme des tableaux de bestioles. Sa petite taille garantit un accès rapide aux données.
Il est préférable de créer des fichiers de données pour stocker des informations sur le disque, plutôt que de surcharger UserDefaults.
C’est surtout que UserDefaults n’est pas une base de données, donc pour chaque accès, même à une seule des données c’est l’intégralité du fichier qui va être chargée.
C’est conçu pour lire et écrire des réglages utilisateur, le mieux est de ne jamais s’en servir pour stocker des listes sauf si on est certain qu’il n’y aura que quelques éléments dedans.
En règle générale toutes les bases de données n’ont pas vraiment de limite de taille, CoreData utilisant SQLite tu peux stocker la quantité de lignes que tu veux. Idem si tu utilises SQLite en direct ou Realm comme dans le cours (sur le cours iOS 11, le chapitre BDD est en cours d’enregistrement).
Par contre il ne faut pas stocker de fichiers brut en base de données (images, blobs, etc.). Il vaut mieux stocker les fichiers individuels sur disque (jpg, png, etc.) et sauvegarder le chemin en texte dans la base de données.