objectForKey crash? iOS - ios

I am trying to use the following code to load a UIButton and UITextField with information based upon a UISegmentedControl's current segment that is clicked but it is causing a SIGABRT crash.
Here is the code:
- (void)updateInfo {
NSLog(#"count1:%d", [self.accounts count]);
[self saveInfo];
NSLog(#"count2:%d", [self.accounts count]);
NSDictionary *dict = [self.accounts objectAtIndex:0];
NSData *imageData = [dict objectForKey:#"ProfileImage"];
UIImage *imageProfile = [UIImage imageWithData:imageData];
[image1 setImage:imageProfile];
NSDictionary *dict2 = [self.accounts objectAtIndex:1];
NSData *imageData2 = [dict2 objectForKey:#"ProfileImage"];
UIImage *imageProfile2 = [UIImage imageWithData:imageData2];
[image2 setImage:imageProfile2];
if ([self.accounts objectAtIndex:accountSC.selectedSegmentIndex] != nil) {
NSDictionary *dict = [self.accounts objectAtIndex:accountSC.selectedSegmentIndex];
//NSString *name = [dict objectForKey:#"Name"];
NSString *name = [accountSC titleForSegmentAtIndex:accountSC.selectedSegmentIndex];
[Name setText:name];
NSData *imageData = [dict objectForKey:#"ProfileImage"];
UIImage *imageProfile = [UIImage imageWithData:imageData];
[pictureButton setImage:imageProfile forState:UIControlStateNormal];
}
else {
Name.text = nil;
[pictureButton setImage:nil forState:UIControlStateNormal];
}
}
The first & second big block of code is temporary because I wanted to see the UIImage's based upon different objectAtIndex numbers.
Here is the console crash log:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString objectForKey:]: unrecognized selector sent to instance 0x2cc08'
Any reason why this can be happening? Do I need to post any other code I am using?
I really need help on this, I have been pulling my hair out!!!
Edit1:
I am using this code, also you were talking about isKindOfClass right?
Anyway this is the code:
NSDictionary *dict = [self.accounts objectAtIndex:1];
if ([dict isKindOfClass:[NSDictionary class]]) {
NSLog(#"YES");
}
else {
NSLog(#"NO");
}
Im testing now...

You're sending objectForKey: to an NSString object, specifically one that you've typed directly into your code somewhere in #"..." form rather than one you've created programmatically (or had created programmatically for you). Someone is putting something other than a dictionary into self.accounts.

NSDictionary: objectForKey:
objectForKey: returns the value associated with key, or nil if no value is associated with key.
key :A string identifying the value. If nil, just return nil.
(1)you should know the key is not blank
(2)you should know the object is not blank and the objects are the same type ,because you shouldn't use different kinds of type in a NSDictionary.
e.g. {#"key1":NSString,#"key2":NSArray} //this is a demonstration of error

Related

Unable to solve the error "[__NSCFBoolean length]: unrecognized selector sent to instance"

Code
NSDictionary *dict = [self.catArray objectAtIndex:indexPath.row];
NSURL *U1 =[NSURL URLWithString:[dict objectForKey:#"img"]];
[DownloadManager downloadImageWithURL:[NSURL URLWithString:[dict objectForKey:#"img"]] completionBlock:^(BOOL succeeded, UIImage *image) {
if (succeeded) {
[cell.iconImgView setImage:image];
}
}];
Getting error
[__NSCFBoolean length]: unrecognized selector sent to instance
Your issue is with this line:
NSURL *U1 =[NSURL URLWithString:[dict objectForKey:#"img"]];
The problem is caused by the fact that you assume:
[dict objectForKey:#"img"]
is returning an NSString when in fact it is returning an NSNumber representing a boolean value.
You need to either figure out why the data in the dictionary is incorrect or you need to use the correct key to get the URL.
[ [dict objectForKey:#"img"] stringValue];
Use above mention code for getting string value

image not showing in UIImage from cached data

I cant possibly get the image that i parsed from the XML to show on my UIImageView using the code below. Am I doing something wrong because I checked it using NSLog to show if there is a link and apparently there is.
NSString *imageURL = [currentData.imageLink];
NSLog(#"this is link = %#", imageURL);
[cachedList addObject:imageURL];
[myCache setObject:cachedList forKey:#"imageURL"];
cachedList = [myCache objectForKey:#"imageURL"]; /where cachedList is NSMutableArray
for(id obj in cachedList){
NSLog(#"value = %#", obj); //to show value
cell.imageShow.image = [UIImage imageNamed:obj];
}
and also I tried doing the below code, but it gives me an error.
if (cachedList != nil) {
cell.imageShow.image = [UIImage imageNamed:[cachedList valueForKey:#"imageURL"]];
}
I think if you are using UITableView then this is the thing i have used and i prefer for tableview
Link: https://github.com/jakemarsh/JMImageCache

Iterating an NSMutableDictionary with UIImage not working

I am trying to add Images fetched from an external service to an NSMutableDictionary and seeing weird results. This is what I am doing:
- (void)fetchImages{
//Fetch Item Brand Images
//self.itemBrands is an NSArray of NSDictionaries
for (NSDictionary *itemBrand in self.itemBrands){
NSString *currentItemId = [itemBrand objectForKey:#"ITEM_ID"];
//Valid Item Id. This Log message is displayed
NSLog(#"Current Item Id: %#",currentItemId);
NSString *currentItemImageUrl = [[IMAGE_URL stringByAppendingString:currentItemId] stringByAppendingString:#".png"];
//Image URL is valid. This log message is displayed
NSLog(#"Current Image URL: %#",currentItemImageUrl);
NSURL *url = [NSURL URLWithString:currentItemImageUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
if (image == nil){
//This log message is displayed when image is not present
NSLog(#"Image not Present 1");
}else{
//This log message is displayed when image is present
NSLog(#"Image Present 1");
[self.itemBrandImages setObject:image forKey:currentItemId];
}
}
//This for loop is not being executed at all. No log messages displayed.
for(id key in self.itemBrandImages){
NSLog(#"Current Item Id2: %#",key);
if ([self.itemBrandImages objectForKey:key] == nil){
NSLog(#"Image Not Present 2");
}else{
NSLog(#"Image Present 2");
}
}
}
The 2nd for loop where I am iterating over self.itemBrandImages is not being executed at all. None of the log messages inside are being displayed.
I tried the following before posting my issue here:
1) Researched similar problems in stack overflow and incorporated suggestion from one of them. The suggestion was "Perform an alloc init of the NSMUtableDictionary" in the init method of the .m file. This didn't help either.
2) To isolate the issue, I even tried adding a simple string to the NSMUtableDictionary instead of the image but even that does not seem to retained.
I am really confused as as to what I am missing or doing wrong here. Inputs are really appreciated.
Thanks,
Mike G
Perhaps:
for(NSString *key in [self.itemBrandImages allKeys])
I did an alloc init of the NSMutableDictianary right in my fetchImages method and it worked! Not sure why the alloc init in the init method did not work.
So here are my takeaways from this issue:
1) If you have an Array or dictionary #property that you are just getting and setting and not really adding or deleting objects to, then you don't need to explicitly alloc init them.
2) If you have an Array or dictionary #property that you are adding or deleting objects to ,you need to explicitly alloc init them.
Are my above statements true? Would love to hear your inputs on this.
Thanks,
Mike
New code:
- (void)fetchImages{
//Fetch Item Brand Images
self.itemBrandImages = [[NSMutableDictionary alloc] init];
for (NSDictionary *itemBrand in self.itemBrands){
NSString *currentItemId = [itemBrand objectForKey:#"ITEM_ID"];
NSLog(#"Current Item Id in ItemList: %#",currentItemId);
NSString *currentItemImageUrl = [[#"http://anythingtogo.freeiz.com/images/"stringByAppendingString:currentItemId] stringByAppendingString:#".png"];
NSLog(#"Current Image URL in ItemList: %#",currentItemImageUrl);
NSURL *url = [NSURL URLWithString:currentItemImageUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
if (image == nil){
NSLog(#"Image not Present 1");
}else{
NSLog(#"Image Present 1");
[self.itemBrandImages setObject:#"Test" forKey:currentItemId];
}
}

How to parse integer value to Json iOS?

I was passed NSstring it is coming properly data into uitableview but when I am parsing integer value it showing exception Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x744e9d0
This is my code
(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray * values=[json objectForKey:#"loans"];
NSLog(#"Array: %#",values);
for (NSDictionary *file in values)
{
NSNumber *fileTitle=[file objectForKey:#"id"];
// NSString *fileTitle = [file objectForKey:#"sector"];
[titles addObject: fileTitle];
}
[self.mainTableView reloadData];
}
You are assigning string value to NSNumber type.
Try to use this
NSString *fileTitle=[file objectForKey:#"id"];
[titles addObject: fileTitle];
and use string value.
[[titles addObject: fileTitle] stringValue];
I guess you are doing something like this in your -tableView: cellForIndexPath:
UITableViewCell *cell = [...];
cell.titleLabel.text = titles[indexPath.row];
You can only use NSString for -[UILabel setText:] method.
Convert your NSNumber to NSString with a simple -[NSNumber stringValue] or using NSNumberFormatter.
Everything seems ok. Just replace
NSNumber *fileTitle=[file objectForKey:#"id"];
by NSString *fileTitle = [file objectForKey:#"id"];

JSON Objective-C Parsing Fail

I have written the following code but I keep on getting nil. I have tried many different variations of this but I am failing exceptionally hard.
This is what I am getting from the server.
Two objects.
[{"description":"yolo.","name":"ye","id":1},{"description":"sMITH","name":"John","id":2}]
Any help would be greatly appreciated...... Thanks.
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
NSArray *jsonObjects = [jsonParser objectWithData:response];
NSMutableString *yolo = [[NSMutableString alloc] init];
for ( int i = 0; i < [jsonObjects count]; i++ ) {
NSDictionary *jsonDict = [jsonObjects objectAtIndex:i];
NSString *IDID = [jsonDict objectForKey:#"id"];
NSString *name = [jsonDict objectForKey:#"name"];
NSLog(#"ID: %#", IDID); // THIS DISPLAYS
[yolo appendString: IDID]; // THIS seems to be causing the new error...
[yolo appendString:#": "];
[yolo appendString: name];
NSLog(#"%#", yolo); // RETURNS NIL
}
EDIT:
currently my new error is...
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSDecimalNumber length]:
unrecognized selector sent to instance 0x81b89f0'
Looks like your [jsonDict objectForKey:#"id"] is an NSNumber(or NSDecimalNumber) and not an NSString. You should change the line NSString *IDID = [jsonDict objectForKey:#"id"]; to,
id myObject = [jsonDict objectForKey:#"id"];
NSString *IDID = nil;
if ([myObject isKindOfClass:[NSNumber class]]) {
IDID = [[jsonDict objectForKey:#"id"] stringValue];
} else {
IDID = [jsonDict objectForKey:#"id"];
}
This error appeared now since earlier you were not initializing NSMutableString *yolo and you were using appendString: on a nil object. Since now it is initialized as NSMutableString *yolo = [[NSMutableString alloc] init]; it is trying to call appendString on NSMutableString object which accepts only NSString type as its inputs where as you are passing an NSNumber in it. length is a method which appendString: internally calls. So you need to change this as well.
You never initialize yolo, so it's just nil the whole time you're calling -appendString: on it. Try this:
NSMutableString *yolo = [NSMutableString string];
Have you tried initializing the NSMutableString?
NSMutableString *yolo = [[NSMutableString alloc] init];
It looks like you are not really checking the type of the data coming to your app via your JSON feed. This might be the case of random crashes when users actually use your app. It might be also a reason for rejection to the App Store, is such crashes happen during your App's review.
You should be checking the type of all objects you receive from JSON, before calling methods on them :)
By implementing best practices you will have a stable and usable app. Build data models to validate your data. You can also you a JSON data model framework like JSONModel: http://www.jsonmodel.com/
It's obvious from your data that "id" is not a string, but a number. Assigning a pointer to an NSString* doesn't magically convert it to an NSString*. And it's obvious from the exception that you got that some object is an NSDecimalNumber when you thought it would be an NSString.
So: IDID is an NSNumber*, and pretending it is an NSString* will lead to crashes.

Resources