pouvez pouvez stocker l'objet entier dans votre UserDefaults
ou un porte-clés, pas de problème. L'astuce consiste à le rendre conforme au protocole NSCoding
, puis utiliser NSKeyedArchiver
et NSKeyedUnarchiver
pour le convertir vers et depuis un objet Data
pouvant être stocké. Ne vous inquiétez pas, cela semble plus compliqué que ça ne l'est.
Conformes aux NSCoding
On peut supposer que votre BUYCustomerToken
classe est déjà un descendant de NSObject
, alors vous êtes à mi-chemin. Vous avez juste besoin d'ajouter quelques méthodes pour permettre à votre classe personnalisée d'être encodée (transformée en Data
) et décodée automatiquement à partir d'un NSCoder
. Plus précisément, ce sont: encode(with coder: NSCoder)
et init(coder aDecoder:NSCoder)
. Vous utilisez ensuite les différentes fonctions encoder() et decode() du codeur pour les faire fonctionner.Encode() et decode() fonctionnent sur n'importe quel objet qui prend en charge NSCoding
, qui comprend NSNumber
, String
et Date
, ce qui rend votre travail ici plutôt facile. Une classe codable terminée ressemblera à ceci:
class BUYCustomerToken : NSObject, NSCoding {
var customerID: NSNumber!
var accessToken: String!
var expiry: Date!
override init() {
}
convenience init(customerID: NSNumber, accessToken: String, expiry: Date) {
self.init()
self.customerID = customerID
self.accessToken = accessToken
self.expiry = expiry
}
required init(coder aDecoder: NSCoder) {
customerID = aDecoder.decodeObject(forKey: "customerID") as! NSNumber
accessToken = aDecoder.decodeObject(forKey: "accessToken") as! String
expiry = aDecoder.decodeObject(forKey: "expiry") as! Date
}
func encode(with aCoder: NSCoder) {
aCoder.encode(customerID, forKey: "customerID")
aCoder.encode(accessToken, forKey: "accessToken")
aCoder.encode(expiry, forKey: "expiry")
}
override var description: String {
return "ID: \(customerID!), Token: \"\(accessToken!)\", Expires: \(expiry!)"
}
}
Vous pouvez ajouter vos propres méthodes personnalisées, bien sûr. Le description
n'est pas strictement nécessaire, mais pratique pour les tests.
Stockage et récupération de UserDefaults
Maintenant que votre classe prend en charge NSCoding, vous pouvez archiver et de le stocker, puis récupérer.
Pour stocker, vous commencez par l'archivage il (le convertir en un objet Data
) en utilisant NSKeyedArchiver.archivedData(withRootObject)
. Cela fonctionne parce que votre classe est conforme à NSCoding
. Une fois que vous obtenez un objet Data
, vous pouvez le stocker dans UserDefaults
en utilisant set(value, forKey)
.
Lorsque vous voulez récupérer, vous le faites dans l'autre sens: tout d'abord chercher un objet Data
de UserDefaults
en utilisant data(forKey)
, puis remettez-le en un objet en utilisant NSKeyedUnarchiver.unarchiveObject(with)
, et enfin jeter à votre classe personnalisée.
Voici un peu de code qui tente de charger un BUYCustomerToken
de UserDefaults
. S'il réussit, il imprime la description; En cas d'échec, il crée un nouveau jeton et le stocke. Mettez ce code dans la viewDidLoad()
de votre première UIViewController
pour le voir en action:
if let customerTokenData = UserDefaults.standard.data(forKey: "myToken") {
let customerToken = NSKeyedUnarchiver.unarchiveObject(with: customerTokenData) as! BUYCustomerToken
print(customerToken)
} else {
print("No token stored. Launch again to see token.")
let customerToken = BUYCustomerToken(customerID: 999, accessToken: "some token", expiry: Date())
let tokenData = NSKeyedArchiver.archivedData(withRootObject: customerToken)
UserDefaults.standard.set(tokenData, forKey: "myToken")
}
La première fois que vous exécutez il n'y a aucun jeton stocké, de sorte que la sortie est:
Aucun jeton stocké. Lancez à nouveau pour voir le jeton.
La deuxième fois, il trouvera le jeton stocké et la sortie de sa description:
ID: 999, Token: "un gage", Expires: 31/05/2017 21:27:25 +0000
Merci beaucoup! Je l'ai deviné juste avant de voir ça et j'ai presque utilisé votre méthode! Merci pour la réponse claire! –