I have been trying to save locally (through NSUserDefaults) a NSMutableArray
of PFGeoPoints that a user creates. After much reading and research, I now know that simply saving an array with custom data is quite frankly impossible. I have tried the following in several different ways:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *testArray = [[NSMutableArray alloc] init];
NSArray *checkArray = [[NSArray alloc] init];
testArray = locationList;
PFGeoPoint *test = [locationList objectAtIndex:0];
NSString *latString = [NSString stringWithFormat:@"%f",test.latitude];
[testArray insertObject:latString atIndex:0];
checkArray = testArray;
[defaults setValue:checkArray forKey:@"Locations"];
[defaults synchronize];
where locationList is a NSMutableArray
that has been created and set to PFGeoPoints from Parse.
I had also tried converting the NSMutableArray
to NSData
via
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
, but this still did not work. Each time I kept receiving the error telling me the following:
Property list invalid for format: 200
(property lists cannot contain objects of type 'CFType')
The NSMutableArray
that I am saving is a list that contains multiple PFGeoPoint
s. All I am trying to do is save this array to the device, so that the user does not have to recreate (render) the entire list each time the user loads the application (I am using cloud data...not trying to spend too much for data).
If someone could help me out with either a suggestion/solution on how to save this data as an array (rather than breaking up each line into integers for lat and long), OR if someone can suggest a helpful alternative to NSUserDefaults
(like perhaps Core Data or some other local storage) I would be most appreciative. Thanks
simply you need to implement NSCoding protocol
Write array:
Obj-C
-(void)writeArrayWithCustomObjToUserDefaults:(NSString *)keyName withArray:(NSMutableArray *)myArray {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myArray];
[defaults setObject:data forKey:keyName];
[defaults synchronize];
}
Swift 2.3
func writeArrayWithCustomObjToUserDefaults(keyName: String, withArray myArray: [AnyObject]) {
var defaults = NSUserDefaults.standardUserDefaults()
var data = NSKeyedArchiver.archivedDataWithRootObject(myArray)
defaults.setObject(data, forKey: keyName)
defaults.synchronize()
}
Swift 3.1
func writeArrayWithCustomObj(toUserDefaults keyName: String, withArray myArray: [Any]) {
let defaults = UserDefaults.standard
let data = NSKeyedArchiver.archivedData(withRootObject: myArray)
defaults.set(data, forKey: keyName)
defaults.synchronize()
}
Read Array:
Obj-C
-(NSArray *)readArrayWithCustomObjFromUserDefaults:(NSString*)keyName {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:keyName];
NSArray *myArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[defaults synchronize];
return myArray;
}
Swift 2.3
func readArrayWithCustomObjFromUserDefaults(keyName: String) -> [AnyObject] {
var defaults = NSUserDefaults.standardUserDefaults()
var data = defaults.objectForKey(keyName)!
var myArray = NSKeyedUnarchiver.unarchiveObjectWithData(data)!
defaults.synchronize()
return myArray
}
Swift 3.1
func readArrayWithCustomObj(fromUserDefaults keyName: String) -> [Any] {
let defaults = UserDefaults.standard
let data: Data? = defaults.object(forKey: keyName)
let myArray: [Any]? = NSKeyedUnarchiver.unarchiveObject(with: data!)
defaults.synchronize()
return myArray!
}