Swift 3 d'économie et de récupération de l'objet personnalisé de userDefaults
J'ai cela en Aire de jeu à l'aide de Swift 3, Xcode 8.0:
import Foundation
class Person: NSObject, NSCoding {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
required convenience init(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: "name") as! String
let age = aDecoder.decodeObject(forKey: "age") as! Int
self.init(
name: name,
age: age
)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(age, forKey: "age")
}
}
créer la matrice de la Personne
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
encoder le tableau
let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)
print("encodedData: \(encodedData))")
enregistrer pour userDefaults
let userDefaults: UserDefaults = UserDefaults.standard()
userDefaults.set(encodedData, forKey: "people")
userDefaults.synchronize()
vérifier
print("saved object: \(userDefaults.object(forKey: "people"))")
récupérer à partir de userDefaults
if let data = userDefaults.object(forKey: "people") {
let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data as! Data)
print("myPeopleList: \(myPeopleList)")
}else{
print("There is an issue")
}
il suffit de consulter les données archivées
if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){
print("myPeopleList: \(myPeopleList)")
}else{
print("There is an issue")
}
Je ne suis pas en mesure d'enregistrer correctement les données de l'objet à userDefaults, et en plus, la case en bas crée l'erreur "fatal error: de façon inattendue trouvé nulle, tandis que d'ôter une valeur Facultative". Le "check" de la ligne de montre également enregistrées objet est nul. Est-ce une erreur dans mon objet NSCoder?
if let data = userDefaults.data(forKey: "people"), let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Person] {
- J'ai mis cela dans une seule page de test de l'app et même résultat, avec votre suggestion de changement. Il ressemble, il peut être un problème avec l'objet du codeur. L'erreur que j'obtiens est: erreur fatale: de façon inattendue trouvé nulle, tandis que d'ôter une valeur Facultative et son à la ligne "si nous permettre de données = userDefaults.de données(forKey: "les gens") { laisser myPeopleList = NSKeyedUnarchiver.unarchiveObject(avec données )"
Vous devez vous connecter pour publier un commentaire.
Swift 4 Note
À nouveau, vous pouvez enregistrer et tester vos valeurs dans une aire de Jeux
Swift 3
UserDefaults doivent être testés dans un projet réel. Note: Pas besoin de forcer la synchronisation. Si vous voulez tester le codage/décodage d'une aire de jeux, vous pouvez enregistrer les données dans un fichier plist dans le répertoire du document à l'aide de la borne d'archivage. Vous avez besoin de résoudre certains problèmes dans votre classe:
Test:
NSKeyedUnarchiver.unarchiveObject(withFile:
lorsqu'ils sont corrompus/ le fichier n'existe pas. Ou peut-on appliquer des contrôles ? DepuisNSKeyedUnarchiver.unarchiveObject
pas de jette, on ne peut donc pas ajoutertry catch
. Aucune solution de contournement?Cela a été modifié pour la Swift 3; cela ne fonctionne plus pour les types de valeur. La syntaxe correcte est maintenant:
Y sont associés décoder...() les fonctions de différents types:
Edit: La liste complète de tous les possibles decodeXXX fonctions Swift 3
Edit:
Une autre remarque importante: Si vous avez précédemment enregistré les données qui ont été codées avec une ancienne version de Swift, ces valeurs doit être décodé à l'aide de decodeObject(), cependant une fois que vous ré-encoder les données à l'aide de coder (...), il ne peut plus être décodé avec decodeObject() si c'est un type de valeur. Par conséquent, Markus Wyss la réponse va vous permettre de gérer le cas où les données ont été codées en utilisant soit Swift version:
String
est une valeur de type rapide, mais il n'y a pas dedecodeString
fonction ... de sorte que la vieille méthode s'applique toujours pour unString
. Je ne sais pas pourquoi, mais.decodeBoolean()
fonction en combinaison avec la ?? l'opérateur, tout comme les Int exemple.self.age = aDecoder.decodeObject(forKey: "myBoolean") as? Bool ?? aDecoder.decodeBoolean(forKey: "myBoolean")
Ne sais pas pourquoi la Chaîne n'est pas inclus; tout ce qui n'a pas de fonction dédiée semble toujours travailler avecdecodeObject()
NSKeyedUnarchiver.unarchiveObject()
vs les différentsdecodeXXX
méthodes surNSKeyedUnarchiver
? Si oui, pouvez-vous nous donner un exemple?Essayez ceci:
Dans Swift 4:
Vous pouvez utiliser Codable pour enregistrer et récupérer des objet personnalisé de la Userdefaults. Si vous le faites souvent, alors vous pouvez ajouter que l'extension et l'utiliser comme ci-dessous.
Votre Classe doit suivre Codable. C'est juste un typealias pour les deux Encodable & Décodable Protocole.
Utilisation:
Pour plus d'Encodage et de Décodage des types Personnalisés, s'il vous Plaît aller à travers la La documentation d'Apple.