Saving array using NSUserDefaults crashes app
Looks like your code should work fine even with some really weird forced casting going on in your decoder method. Try like this:
class Task: NSObject, NSCoding {
var name = String()
var notes = String()
var date: NSDate
var taskCompleted: Bool
init(name: String, notes: String, date: NSDate, taskCompleted: Bool){
self.name = name
self.notes = notes
self.date = date
self.taskCompleted = taskCompleted
}
required init(coder decoder: NSCoder){
self.name = decoder.decodeObjectForKey("name") as! String
self.notes = decoder.decodeObjectForKey("notes") as! String
self.date = decoder.decodeObjectForKey("date") as! NSDate
self.taskCompleted = decoder.decodeBoolForKey("taskCompleted")
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(name, forKey: "name")
coder.encodeObject(notes, forKey: "notes")
coder.encodeObject(date, forKey: "date")
coder.encodeBool(taskCompleted, forKey: "taskCompleted")
}
}
Testing with plist files:
let task1 = Task(name: "task1", notes: "note a", date: NSDate(), taskCompleted: false)
let task2 = Task(name: "task2", notes: "note b", date: NSDate(), taskCompleted: true)
let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let fileURL = documentsDirectory.URLByAppendingPathComponent("data.plist")
if let filePath = fileURL.path {
NSKeyedArchiver.archiveRootObject([task1,task2], toFile: filePath)
if let loadedArray = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? [Task] {
print(loadedArray.count)
print(loadedArray.first?.name ?? "")
print(loadedArray.first?.notes ?? "")
print(loadedArray.first!.date )
print(loadedArray.first!.taskCompleted)
print(loadedArray.last?.name ?? "")
print(loadedArray.last?.notes ?? "")
print(loadedArray.last!.date )
print(loadedArray.last!.taskCompleted)
}
}
App crashes when storing NSArray in NSUserDefaults
Yes they can not be saved like this in NSUserDefaults.
I am writing a code below please have a look and for more study go look apple docs okay.
Code is here:
//For Saving
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:yourArrayToBeSave]];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:@"array"];
[[NSUserDefaults standardUserDefaults] synchronize]; // this will save you UserDefaults
//For retrieving
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
App crashes when storing NSArray in NSUserDefaults
Yes they can not be saved like this in NSUserDefaults.
I am writing a code below please have a look and for more study go look apple docs okay.
Code is here:
//For Saving
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:yourArrayToBeSave]];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:@"array"];
[[NSUserDefaults standardUserDefaults] synchronize]; // this will save you UserDefaults
//For retrieving
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSUserDefaults save two arrays leading to crash
NSUserDefaults
can store NSMutableArrays
, but will turn them into immutable arrays.
Same goes for NSDictionary
and NSMutableDictionary
.
That means if you want to add an object to an array that you just extracted from the NSUserDefaults
, you will have to first make it mutable first, using -mutableCopy
for example, or -initWithArray
.
NSArray *array = [userDefault objectForKey:@"movie"];
//This works
NSMutableArray *arr = [NSMutableArray alloc]initWithArray:array];
//This works too and is more commonly used.
NSMutableArray *arr = [array mutableCopy];
You can now modify the array arr
without any trouble, and you will be able to save it just like you did before. If you retrieve it afterwards, it will be the modified array. But be careful, arrays
and dictionaries
are always immutable when taken from NSUserDefaults
. You will have to do that "trick" everytime you want to modify an array or dictionary from the NSUserDefaults
.
EDIT : after testing your code, my only assumption is that your crash-free array is simply nil when you retrieve it. Debug with breakpoints to verify this but I'm close to 101% sure.
EDIT2 : trojanfoe got that faster than I did !
Save a fetchedObject NSArray to NSUserDefaults - app crashes at launch
The PROBLEM
Xcode was not reaction because the entire computer would freeze after I ran the app.
Fixing the NSArray
My fetch request was bringing a custom object, and NSUserDefaults does not support custom objects. So I am converting the NSArray to a NSData.
Saving to NSUserDefaults crashes app?
"Any idea why?". Yes:
[[NSUserDefaults standardUserDefaults] setObject:[[DIOSSession sharedSession] user]
forKey:@"diosSession"];
I don't know what [[DIOSSession sharedSession] user]
is, but only a NSArray
, NSDictionary
, NSString
, NSData
, NSNumber
and NSDate
may be stored.
So I guess that's why.
save in userdefaults is crashing app
You first have to serialise your object into a Data
instance before actually storing to UserDefaults
. Fortunately, Swift 4 provides built-in tools to easily do both serialisation and deserialisation (Codable
protocol).
Have a look at this tutorial where the required steps are described in-depth.
Related Topics
Backgroundtimeremaining Returns (35791394 Mins)
If Let Doesn't Unwrap Optional Value for Mkannotation's Title Property
Center Horizontal Uicollectionview Based on Content
Save Uiimage Array in Nsuserdefaults
Increase the Width of Content View Programmatically in Swift
Replace C Style For-Loop in Swift 2.2.1
Rxswift - Generic Parameter 'Self' Could Not Be Inferred
Aes 128 Message Decryption -- Swift, iOS
Swift Calling Setnavigationbarhidden But View Wont Move to Top
Why Do I Get an Mkerrordomain Error When Doing a Local Search
Swift 3 - Loading Multiple Viewcontrollers at Launch
Why Is This Array Out of Index
Screen Recording When My iOS App Is in Background with Replaykit
Get "No Keychain Available" Error When Try to Access Keychain from App Extension