user2976267 user2976267 - 1 year ago 77
iOS Question

NSUserDefaults returns empty array

I have a class Person, which is a model

import Foundation

public class Person : NSObject , NSCoding{
public var name:String="";
public var gender:Int = 0;
public var status:Int = 0

override init (){

public init (name:String, gender:Int){;
required public init(coder aDecoder: NSCoder) { }
public func encodeWithCoder(_aCoder: NSCoder) { }


Now when I try to retreive [Person] array I use method
getPersons(arr : String!)
. If there is no data in NSUserDefaults , I create it, put 1 element into it and store using

The problem is that on retrieving I get an array with correct count (1), but the object is not filled, having "" in String and 0 in Int variables.

private func archivePeople (people : [Person]) -> NSData{
return NSKeyedArchiver.archivedDataWithRootObject(people as NSArray)

public func getPersons(arr : String!) -> [Person]{
var array : [Person] = []
if let unarchivedObject = NSUserDefaults.standardUserDefaults().objectForKey(arr) as? NSData {
array = (NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject) as? [Person])!

if array.count == 0 {
array.append(Person(name: A.DEFAULT_THEIR_NAMES,gender: 0))
setPersons(arr, people: array)
return array

public func setPersons(key: String, people : [Person]){
let archivedObject = archivePeople(people)
userDefaults.setObject(archivedObject, forKey: key)

What is wrong? Do I set or retrieve this in a wrong way?

Answer Source

You need to override properly the NSCoding functions. It should look like something the code below:

 required public convenience init(coder aDecoder: NSCoder) {
        let name: String = aDecoder.decodeObject(forKey: "name") as! String
        let gender = aDecoder.decodeInt64(forKey: "gender")
        let status = aDecoder.decodeInt64(forKey: "status")
        self.init(name: name, gender: Int(gender))
        self.status = Int(status)

    public func encodeWithCoder(_aCoder: NSCoder) {   
        _aCoder.encode(, forKey: "name")
        _aCoder.encode(Int64(self.gender), forKey: "gender")
        _aCoder.encode(Int64(self.status), forKey: "status")
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download