Reputation: 121
The 'leave-logic' works but I am having problems saving one NSMutableDictionary to NSUserDefaults.
Following code:
@implementation LoginService
{
NSUserDefaults *prefs;
}
- (void) parseResponse:(NSDictionary*) dictionary
{
NSMutableDictionary *dic=[[NSMutableDictionary alloc]initWithDictionary:dictionary];
prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:dic forKey:@“setKey”];
[prefs synchronize];
}
gives me the following crashes:
as an NSUserDefaults/CFPreferences value for key setKey
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object {
result = {
email = "";
group = 1;
locations = "";
"login_id" = "";
photo = "";
status = 1;
};
} for key setKey'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110e66e65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001108b6deb objc_exception_throw + 48
2 CoreFoundation 0x0000000110e66d9d +[NSException raise:format:] + 205
3 CoreFoundation 0x0000000110e26ef5 _CFPrefsValidateValueForKey + 149
4 CoreFoundation 0x0000000110e69a49 -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 217
5 CoreFoundation 0x0000000110d9e5b7 -[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 311
6 CoreFoundation 0x0000000110d9e44e -[CFPrefsSource setValue:forKey:] + 62
7 CoreFoundation 0x0000000110d5b991 +[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 1105
8 CoreFoundation 0x0000000110d9e3b2 _CFPreferencesSetValueWithContainer + 306
9 Foundation 0x0000000110244b25 -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 46
10 test 2015 0x000000010b5f2051 -[LoginService parseResponse:] + 5025
11 test 2015 0x000000010b567348 -[WebService successResponse:] + 104
12 test 2015 0x000000010b56693f __22-[WebService GETstart]_block_invoke + 127
13 test 2015 0x000000010b495d0b __74+[AFJSONRequestOperation JSONRequestOperationWithRequest:success:failure:]_block_invoke + 203
14 test 2015 0x000000010b4970d3 __64-[AFJSONRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke78 + 51
15 libdispatch.dylib 0x00000001113d1e5d _dispatch_call_block_and_release + 12
16 libdispatch.dylib 0x00000001113f249b _dispatch_client_callout + 8
17 libdispatch.dylib 0x00000001113da2af _dispatch_main_queue_callback_4CF + 1738
18 CoreFoundation 0x0000000110dc6d09 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
19 CoreFoundation 0x0000000110d882c9 __CFRunLoopRun + 2073
20 CoreFoundation 0x0000000110d87828 CFRunLoopRunSpecific + 488
21 GraphicsServices 0x000000011275dad2 GSEventRunModal + 161
22 UIKit 0x000000010ecfb610 UIApplicationMain + 171
23 test 2015 0x000000010b44fdbf main + 111
24 libdyld.dylib 0x000000011142692d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Upvotes: 2
Views: 1159
Reputation: 107
From Apple's Documentation The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects. See What is a Property List? in Property List Programming Guide.
Ensure that everything in dictionary is a property list object, simple ints don't work because everything has to be an object.
So, first go through all of the values in the dictionary, convert any ints/bools to NSNumbers, then save it back into the dictionary then into NSUserDefaults.
I can see from your error that the dictionary contains integers, these are likely causing the issue.
result = {
email = "";
group = 1; //This Line here
locations = "";
"login_id" = "";
photo = "";
status = 1; //This line here
};
Make sure that those lines above are NSNumber objects.
Upvotes: 1
Reputation: 1962
First of all, you should note that even if you write mutable class instances (like NSMutableDictionary
) to NSUserDefaults
, the objects you read out will always be immutable. You could have saved the passed NSDictionary
directly to the NSUserDefaults
. But that would not solve the problem.
Obviously, from the debug message, the dictionary that you are trying to save is not considered a property list object. To check what exactly is wrong, make sure that following is met:
In order for your NSDictionary
to be a property list, all of it’s values need to be too. By default, property list classes are NSDictionary
, NSArray
, NSString
, NSDate
, NSData
, and NSNumber
. Not so likely, but maybe "dictionary" passed object is not an NSDictionary
at all? Check it's class in runtime by using introspection like:
NSLog(@"actually it's a %@", [dictionary class])
Also note that NSDictionary
is considered a property list object only if all of it’s keys are NSStrings
.
If you are trying to store instances of classes other than those from above, then those objects have to conform to the NSCoding
protocol so they can be archived to NSData
objects, which are property list–compatible objects. So you can save them as NSData
objects and later restore them. If you want to se this in action, example code is here.
Upvotes: 0
Reputation: 2142
My first thought was that using the key of "setKey" was about the worst thing you could possibly set it to. Try another key WITHOUT the word "set" or "key"... something like "testing".
Also, why the NSMutableDictionary when your plain old dictionary will do. When reading it back out, then initialize your NSMutableDictionary with the NSDictionary.
Upvotes: 0