iOS: can't set the null value in an NSMutableDictionary - ios

I'm trying to set a value in an NSMutableDictionary but I'm always getting this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x10fd55990> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key image.'
In the NSMutableDictionary I have an #"image" field that can be null. I want to replace the null value with a placeholder image name.
This is how I do it:
NSMutableDictionary * item = self.carouselSource[index];
if([Utils isNull:[item valueForKey:#"image"]]) {
[item setValue:#"default_image.png" forKey:#"image"];
}
But the application crash in this line
[item setValue:#"default_image.png" forKey:#"image"];
due to the error above.

Your dictionary is immutable - it's an NSDictionary and not an NSMutableDictionary.if you want to convert any(array, dictionary) immutable to mutable use mutableCopy for full conversion(balance the retain count).
NSMutableDictionary * item = [self.carouselSource[index] mutableCopy];
if([Utils isNull:[item objectForKey:#"image"]]) {
[item setObject:#"default_image.png" forKey:#"image"];
}
instead of
NSDictionary * item = self.carouselSource[index];
if([Utils isNull:[item valueForKey:#"image"]]) {
[item setValue:#"default_image.png" forKey:#"image"];
}

Related

Why getting error: class is not key value coding-compliant for the key name?

As suggested in Xcode autocomplete suggestion using below code in objective c produced runtime error,
for (int i = 1; i <= 10; i++)
{
NSLog(#"%d", i);
NSDictionary *dic = [[NSDictionary alloc] init];
[dic setValue:#"Alex" forKey:#"name"];
[dic setValue:#"45" forKey:#"Age"];
}
2020-03-29 21:55:34.588607+0600 Test[5299:15492347] *** Terminating
app due to uncaught exception 'NSUnknownKeyException', reason:
'[<__NSDictionary0 0x7fff806228e0> setValue:forUndefinedKey:]: this
class is not key value coding-compliant for the key name.'
What am I missing?
Update
As matt commented NSDictionary is not mutable, then,
Why setValue method is available for NSDictionary in Autocomplete suggestion on Xcode?
Why can't methods that modifies non mutable collections be detected on compile time rather runtime?
I resolve the issue by changing setValue to setObject,
NSDictionary *dic = [[NSDictionary alloc] init];
[dic setObject:#"Alex" forKey:#"name"];
[dic setObject:#"45" forKey:#"Age"];

Fetching data from PLIST by Fast Enumeration

I am using for in loop to fetch data from plist.For in loop is correct as it is printing value. But,suddenly, it is showing following exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x97a14b0'.
Code:
NSString *sss=[[NSBundle mainBundle]pathForResource:#"s" ofType:#"plist"];
NSDictionary *dic=[[NSDictionary alloc]initWithContentsOfFile:sss];
for(NSArray *arr in [dic allKeys])
{
NSLog(#"%#",arr); // Ii is printing value
NSLog(#"%#",arr[0]); // It is showing exceptions
}
Plist:
There is some problem with NSLog(#"%#",arr[0]);. I want to print values of first index of arrays a and b.
here [dic allKeys] will be keys in dic that are NSString like "a", "b" etc.
so for your plist the code should be,
NSString *sss=[[NSBundle mainBundle]pathForResource:#"s" ofType:#"plist"];
NSDictionary *dic=[[NSDictionary alloc]initWithContentsOfFile:sss];
for(NSString *key in [dic allKeys])
{
NSLog(#"%#",key);
NSArray *value = [dic objectForKey:key];
NSLog(#"%#",value[0]);
}

Crashing with Terminating app due to uncaught exception 'NSUnknownKeyException

I am saving JSON in NSUserDefaults. When I retrieve a NSArray, it's crashing for accessing one of my JSON keys and showing *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x174676fc0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key s.'
NSDictionary *status = [[NSUserDefaults standardUserDefaults] objectForKey:#”today”];
NSArray *ch = [status valueForKey:#"c"];
NSArray *service1 = [status valueForKey:#"s"];
NSArray *eventList = [status valueForKey:#"l"];
NSArray *time = [eventList valueForKey:#"s"];
NSArray *dur = [eventList valueForKey:#"d"];
NSArray *eveid = [eventList valueForKey:#"e"];
NSArray *title = [eventList valueForKey:#"t"];
It's crashing at 5 line of code.
TL;DR; You are getting an NSString back from NSUserDefaults, not the NSDictionary you expect.
Your exception:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x174676fc0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key s.'
Indicates that status is an instance of NSString, not NSDictionary.
This line:
NSDictionary *status = [[NSUserDefaults standardUserDefaults] objectForKey:#”today”];
Is returning an NSString. When you call -valueForKey: the receiver does not support that key, so it throws an NSUnknownKeyException exception. The solution here is to validate what you get from NSUserDefaults is what you expect.
Does it respond to -valueForKey:?
Does it support the key you are using?
Is it an NSDictionary?
Are you setting the NSUserDefaults value for today with a string elsewhere in your application when you meant to use a dictionary?
All of these things are worth checking.
You don't want to use valueForKey: in combination with JSON data. Instead, use objectForKey:, which is the NSDictionary method.
NSDictionary *status = [[NSUserDefaults standardUserDefaults] objectForKey:#"today"];
NSArray *ch = [status valueForKey:#"c"];
NSArray *service1 = [status valueForKey:#"s"];
Additionally, I propose you use the modern and shorter syntax:
NSDictionary *status = [[NSUserDefaults standardUserDefaults] objectForKey:#"today"];
NSArray *ch = status[#"c"];
NSArray *service1 = status[#"s"];
BTW.: Are all elements in status of type array? That's a bit surprising.

NSJSONSerialization from an nsmanagedObject says a key is not key value coding-compliant

I'm trying to send back my NSManagedObject as a Serialized object to my webservice.
This is how I do it.
NSDictionary *menuDictionary = [self dictionaryFromMenu:appointment];
NSError *err;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:menuDictionary options:NSJSONWritingPrettyPrinted error:&err];
NSString *jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
- (NSDictionary *)dictionaryFromMenu:(Appointment*)appointment {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[appointment.app_id description],#"Id",
appointment.app_addressinfo, #"AddressInfo",
appointment.app_completed, #"Completed",
appointment.app_description, #"Description",
appointment.app_end, #"EndDate",
appointment.app_fullday, #"FullDay",
appointment.app_label, #"Label",
appointment.app_label_id, #"LabelId",
appointment.app_location, #"Location",
appointment.app_private, #"Private",
appointment.app_project_name, #"ProjectName",
appointment.app_project_number, #"ProjectNumber",
appointment.app_relation_address_city, #"RelationAddressCity",
appointment.app_relation_address_id, #"RelationAddressId",
appointment.app_relation_address_name, #"RelationAddressName",
appointment.app_relation_address_street, #"RelationAddressStreet",
appointment.app_relation_code, #"RelationCode",
appointment.app_relation_contact_id, #"RelationContactPersonId",
appointment.app_relation_contact_name, #"RelationContactPersonName",
appointment.app_relation_name, #"RelationName",
appointment.app_reminder_info, #"ReminderInfo",
appointment.app_start, #"StartDate",
appointment.app_state, #"State",
appointment.app_subject, #"Subject",
appointment.app_supplier_code, #"SupplierCode",
appointment.app_supplier_contact_person_id, #"SupplierContactPersonId",
appointment.app_supplier_contact_person_name, #"SupplierContactPersonName",
appointment.app_supplier_name, #"SupplierName",
appointment.app_type, #"Type",
nil];
return dict;
}
And this is how my entity looks like.
Now I get this error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Appointment 0x16dcb520> valueForUndefinedKey:]: the entity Appointment is not key value coding-compliant for the key "SupplierName".'
Any help ?
So the value for SupplierName is nil. That causes the construction of your dictionary to stop prematurely. You would have gotten a run time error if you had used the new #{}syntax.
You will need to change your code so for each key, if the value is nil, you use [NSNull null] instead.

Removing an object from a mutable dictionary throws an exception

I'm getting an exception after attempting to remove an object from a NSMutableDictionary. The relevant code follows. The 'settings' is passed to the method and can be a NSDictionary or a NSMutableDictionary.
NSMutableDictionary *mutableSettings = nil;
if ([settings isKindOfClass:[NSMutableDictionary class]])
mutableSettings = (NSMutableDictionary *)settings;
else
mutableSettings = [[[NSMutableDictionary alloc] initWithDictionary:settings] autorelease];
[mutableSettings removeObjectForKey:#"akey"];
This crashes with
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary removeObjectForKey:]: mutating method sent to immutable object'
Whats wrong with this? Thanks.
The problem here is that both NSDictionary and NSMutableDictionary return __NSCFDictionary as their class, due to the fact that NSDictionary is a class cluster.
I think you will just have to make a mutable copy of the settings dictionary whether it is mutable or not.
NSMutableDictionary *mutableSettings = [settings mutableCopy];

Resources