How to store custom objects in NSUserDefaults
On your Player class, implement the following two methods (substituting calls to encodeObject with something relevant to your own object):
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.question forKey:@"question"];
[encoder encodeObject:self.categoryName forKey:@"category"];
[encoder encodeObject:self.subCategoryName forKey:@"subcategory"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.question = [decoder decodeObjectForKey:@"question"];
self.categoryName = [decoder decodeObjectForKey:@"category"];
self.subCategoryName = [decoder decodeObjectForKey:@"subcategory"];
}
return self;
}
Reading and writing from NSUserDefaults
:
- (void)saveCustomObject:(MyObject *)object key:(NSString *)key {
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:encodedObject forKey:key];
[defaults synchronize];
}
- (MyObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *encodedObject = [defaults objectForKey:key];
MyObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
return object;
}
Code shamelessly borrowed from: saving class in nsuserdefaults
how can store custom objects in NSUserDefaults
First you create custom class Like below.
CustomObject.h
#import <Foundation/Foundation.h>
@interface CustomObject : NSObject<NSCoding>
@property(strong,nonatomic)NSString *name;
@end
CustomObject.m
#import "CustomObject.h"
@implementation CustomObject
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.name forKey:@"name"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.name = [decoder decodeObjectForKey:@"name"];
}
return self;
}
Then create CustomObject class object and store in NSUserDefaults
Stored your object like this
CustomObject *object =[CustomObject new];
object.name = @"test";
NSMutableArray *arr = [[NSMutableArray alloc]init];
[arr addObject:object];
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:arr];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:encodedObject forKey:@"storeObject"];
[defaults synchronize];
get custom object from NSUserDefaults like this
NSData *storedEncodedObject = [defaults objectForKey:@"storeObject"];
NSArray *arrStoreObject = [NSKeyedUnarchiver unarchiveObjectWithData:storedEncodedObject];
for (int i=0; i<arrStoreObject.count; i++)
{
CustomObject *storedObject = [arrStoreObject objectAtIndex:i];
NSLog(@"%@",storedObject.name);
}
Store Custom Objects in NSUserDefaults
You unarchive incorrect object. You store NSArray to NSUserDefaults
NSArray * archiveArray = [userData objectForKey:@"personDataArray"];
for (NSData *personEncodedObject in archiveArray) {
id personObject = [NSKeyedUnarchiver unarchiveObjectWithData:personEncodedObject];
}
How to use NSUserDefaults to store an array of custom classes in Swift?
Your Person class should look like this:
Swift 3:
class Person : NSObject, NSCoding{
// Person dictionary variable
var name: String?
var age: String?
var html_url: String?
init(json: NSDictionary) { // Dictionary object
self.name = json["name"] as? String
self.age = json["age"] as? String
self.html_url = json["html_url"] as? String // Location of the JSON file
}
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObjectForKey("name") as? String;
self.age = aDecoder.decodeObjectForKey("age") as? String;
self.html_url = aDecoder.decodeObjectForKey("html") as? String;
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.name, forKey: "name");
aCoder.encodeObject(self.age, forKey: "age");
aCoder.encodeObject(self.html_url, forKey: "html");
}
}
And here you have an example of saving and retrieving the array from NSUserDefaults:
let p = Person()
p.name = "person1"
p.age = "12"
p.html_url = "www.google.ro"
let p2 = Person()
p2.name = "person2"
p2.age = "11"
p2.html_url = "www.google.ro"
let array = [p, p2]
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(NSKeyedArchiver.archivedDataWithRootObject(array), forKey: "persons")
userDefaults.synchronize()
let array : [Person]
array = NSKeyedUnarchiver.unarchiveObjectWithData(userDefaults.objectForKey("persons") as! NSData) as! [Person]
print("\(array[0].name)\(array[1].name)")
Swift 4:
class Person : NSObject, NSCoding{
// Person dictionary variable
var name: String?
var age: String?
var html_url: String?
init(json: NSDictionary) { // Dictionary object
self.name = json["name"] as? String
self.age = json["age"] as? String
self.html_url = json["html_url"] as? String // Location of the JSON file
}
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as? String;
self.age = aDecoder.decodeObject(forKey: "age") as? String;
self.html_url = aDecoder.decodeObject(forKey: "html") as? String;
}
func encode(with aCoder: NSCoder) {
aCoder.encode(self.name, forKey: "name");
aCoder.encode(self.age, forKey: "age");
aCoder.encode(self.html_url, forKey: "html");
}
}
How to store array list of custom objects to NSUserDefaults?
You need to implement protocol NSCoding for your custom class. Please see this Swift example.
Save custom objects into NSUserDefaults
Actually, you will need to archive the custom object into NSData
then save it to user defaults and retrieve it from user defaults and unarchive it again.
You can archive it like this
let teams = [Team(id: 1, name: "team1", shortname: "t1"), Team(id: 2, name: "team2", shortname: "t2")]
var userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams)
userDefaults.set(encodedData, forKey: "teams")
and unarchive it like this
let decoded = userDefaults.data(forKey: "teams")
let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Team]
But if you just did that you will get
.Team encodeWithCoder:]: unrecognized selector sent to instance
You will have to make Team conform to NSCoding just like this
class Team: NSObject, NSCoding {
var id: Int
var name: String
var shortname: String
init(id: Int, name: String, shortname: String) {
self.id = id
self.name = name
self.shortname = shortname
}
required convenience init(coder aDecoder: NSCoder) {
let id = aDecoder.decodeInteger(forKey: "id")
let name = aDecoder.decodeObject(forKey: "name") as! String
let shortname = aDecoder.decodeObject(forKey: "shortname") as! String
self.init(id: id, name: name, shortname: shortname)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: "id")
aCoder.encode(name, forKey: "name")
aCoder.encode(shortname, forKey: "shortname")
}
}
Related Topics
How to Clear the Entered Textfield When the User Taps on the Button
How to Create Custom Calendar in React Native
How to Debug 'Unrecognized Selector Sent to Instance' Error
Upload Image With Parameters in Swift
Ios 9 Xcode 7 - Application Appears With Black Bars on Top and Bottom
How to Check When a Uitextfield Changes
How to Make a Simple Collection View With Swift
Swiftui Update Navigation Bar Title Color
Left Align Cells in Uicollectionview
Force View Controller to Reload to Refresh Uiappearance Changes
Best Way to Check If Object Is Out of Bounds in Array
How to Store Custom Objects in Nsuserdefaults
Adjust Uilabel Height Depending on the Text
What Is the Ibeacon Bluetooth Profile
Can You Build Dynamic Libraries For iOS and Load Them At Runtime
Setting Action For Back Button in Navigation Controller
How to Trigger a Block After a Delay, Like -Performselector:Withobject:Afterdelay: