NSDictionary init with object for keys - iphone

NSLog(#"1");
NSArray *obj= [NSArray arrayWithObjects:appDel.token, nil];
NSLog(#"2");
NSArray *key= [NSArray arrayWithObjects:#"Token", nil];
NSLog(#"3");
NSDictionary *d= [[NSDictionary alloc] initWithObjects:obj forKeys:key];
NSLog(#"4");
DoSomething();
NSLog(#"5");
Need help with the above code. I seem to be crashing on #"4" (it does not print 4).
The error from Xcode:
'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' -[NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (1)'
Any kind soul can point me in the right direction? It use to work till i upgraded to Xcode 5 :(

I'm most certain of the fact that NSLog(#"%#", appDel.token); will display (null), because your token is nil. Verify that appDel.token isn't nil, and you won't be getting that error.
Hope this helps.

Your appDel.token is nil. Add the below reusable method in your project utility.
-(BOOL)isObjectEmpty:(id)object
{
return object == nil || ([object respondsToSelector:#selector(length)] && [(NSData *)object length] == 0) || ([object respondsToSelector:#selector(count)] && [(NSArray *)object count] == 0);
}

Related

ObjectAtIndex causes app to crash

When I do an NSLog of the contents of my NSMutableArray, it returns :
(
hat,
hat
)
So why is it that when I do an NSLog like so NSLog(#"%#", [pro.matches objectAtIndex:0]); it crashes with the error: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
So strange
This is where I fill it:
[self.matches removeAllObjects];
NSArray *JSONarray = [[NSArray alloc] initWithArray:[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]];
int i;
for (i=0; i<[JSONarray count]; i++) {
//[self.matches addObject:[JSONarray objectAtIndex:i]];
[self.matches addObject:#"hat"];
}
//NSLog(#"boys with bo%#", [[matches objectAtIndex:1] objectForKey:#"host"]);
block();
//JSON and add to matches.
}
}];
block();
and this is where i call it:
[pro refreshMatchesWithCallback:^
{
//[self.tableView reloadData];
NSLog(#"the count of a lifetime is %#", [pro.matches objectAtIndex:0]);
}];
When you first log the contents it has nothing in due to the way completion blocks work, try this:
[pro refreshMatchesWithCallback:^
{
//[self.tableView reloadData];
if(pro.matches.count > 0) {
NSLog(#"the count of a lifetime is %#", [pro.matches objectAtIndex:0]);
}
}];
Hope this Helps!
Sam
always prefer to use this approach
for(Object* obj in arra)
{
...
}
this will enter in loop if the counter is greater than 0. no check needed
Cheerz :P

Check if key exists in NSDictionary is null or not

I did search on how to check if NSDictionary key exists or not and came up with the solution. But still it throws me an error saying adding null value to the key.
I am not sure if my code is correct or not. If anyone has any idea about this can help me.
NSDictionary *result;
id myImageURL = [result objectForKey:#"url"];
if ((NSNull *)myImageURL == [NSNull null])
myImageURL = #"";
id myImage = [result objectForKey:#"image"];
if ((NSNull *)myImage == [NSNull null])
myImage = #"";
Check if null add nothing and if not add the value. But it still gives me an error dont know why.
/****OUTPUT*****/
2011-08-11 14:56:06.668 Tab_Table_Win[6510:207] RESULTS : {
image = "<UIImage: 0xbc332c0>";
url = "http://a3.twimg.com/profile_images/999228511/normal.jpg";
}
2011-08-11 14:56:06.669 Tab_Table_Win[6510:207] url : http://a3.twimg.com/profile_images/999228511/normal.jpg
2011-08-11 14:56:06.670 Tab_Table_Win[6510:207] IMage : <UIImage: 0xbc332c0>
/*****Breaks Here ***/
2011-08-11 14:56:06.876 Tab_Table_Win[6510:207] RESULTS : {
}
2011-08-11 14:56:06.878 Tab_Table_Win[6510:207] url : (null)
2011-08-11 14:56:06.879 Tab_Table_Win[6510:207] IMage : (null)
2011-08-11 14:56:06.881 Tab_Table_Win[6510:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'
Correct answer is :
NSDictionary *result;
NSURL *myImageURL = [result objectForKey:#"url"];
UIImage *myImage = [result objectForKey:#"image"];
/**** Correct way ****/
if (myImageURL != nil && myImage != nil) {
[images setObject:myImage forKey:myImageURL];
}
Thank you for all the explanation.
Tommy explained this perfectly.
What I recommend is create an extension of the NSDictionary class like:
#import <Foundation/Foundation.h>
#interface NSDictionary (Safety)
- (id)safeObjectForKey:(id)aKey;
#end
And the implementation file:
#import "NSDictionary+Safety.h"
#implementation NSDictionary (Safety)
- (id)safeObjectForKey:(id)aKey {
NSObject *object = self[aKey];
if (object == [NSNull null]) {
return nil;
}
return object;
}
#end
And instead of using [dictionary objectForKey:#"keyName"]; in your code, use
[dictionary safeObjectForKey:#"keyName"];
This way, as Tommy explained, you'd be sending a method call to a nil which wouldn't crash the app but your object would get a nil value.
Hope this helps.
Whenever I try to check if an object being returned from a dictionary is null, I do this:
id obj = [myDictionary objectForKey:entityKeyName];
if (obj == [NSNull null]) {
// do something
}
Then in your code, it would be:
NSDictionary *result;
NSString *myImageURL = [result objectForKey:#"url"];
if (myImageURL == [NSNull null])
myImageURL = #"";
That's what I would do in your code.
Also, just making sure, is the NSDictionary result defined? In your code, it doesn't have anything it's being set to. It's just being defined as variable you plan on using called results
the answer below worked for me:
https://stackoverflow.com/a/2784675/936957
if ([dictionary objectForKey:key]) {
// previously stored data for "key"
}
Also note that you can get array of the keys in a dictionary using
[dictionary allKeys]
If an object doesn't exist for a key, NSDictionary will return nil. An NSNull is an actual object, and therefore a distinct thing. It's like the distinction between being able to record that there was a value and the value as null, and not recording whether there was a value. It also rests a bit on you thinking in C terms of the indirection of a pointer to an object rather than just an object, so it's not completely semantically pleasing from that perspective.
In Objective-C, you may send any message to nil and the result is guaranteed to be nil (or 0). So if your code is designed to ensure that you have a safe object reference, as you might in C++, then what you're doing is unnecessary. Compound statements like:
object = [[Type alloc] init];
Are always explicitly safe, even if alloc fails and returns nil. All that'll happen is that the call to init won't do anything at all, and object will end up with the value nil because the result of sending of init to nil is also nil.
That being said, the answers provided by Bill and Emmanuel should be correct. Compare your result either directly to nil or implicitly to zero. If you're getting a crash later on, I'll guess it's because you're expecting myImageUrl and myImage to be types other than NSString (I notice you've used the typeless id in your original code) and sending them a message they don't respond to.
NSDictionary *result;
NSString *myImageURL = [result objectForKey:#"url"];
if (myImageURL == NULL)
myImageURL = #"";
NSString *myImage = [result objectForKey:#"image"];
if (myImageURL == NULL)
myImage = #"";
See if that works, rather than overthinking the NULL class.
this another option:
if (![result objectForKey:#"image"])
{
NSLog(#"doesn't exist");
}
if ([result objectForKey:#"image"])
{
NSLog(#"exist");
}
that was not work for me, i figured it out like this
id myImageURL = [result objectForKey:#"url"];
if ([myImageURL isKindOfClass:[NSNull class]])
myImageURL = #"";
Alright here's the actual answer which #Iomec almost had
UIImage *myImage = ([result objectForKey:#"image"] != [NSNull null] ? [result objectForKey:#"image"] : nil);
That is the actual correct answer because, it comes as null and when you say myImage = [receivedObject...]; then if myImage = nil, you are in effect casting a null value(nil) into a class which is an exception, if not a running bug.
You should:
1) test for NSNull null value
2) if not nil then assign
If you code hasn't bugged out yet, it will in production when you have 8 apps running in the background one day.
I got the same issue with JSONKit. The implementation there is
- (id)objectForKey:(id)aKey
{
[...]
return((entryForKey != NULL) ? entryForKey->object : NULL);
}
So this will definitely return NULL if the object isn't there. I check it like the following
NSArray* array = [myDictionary objectForKey:#"a"];
if((NSNull*)arrays!=[NSNull null])
{
[...]
}
1. Results Dictionary after JSON parsing:
//if hits success
{"result":{"action":"authentication","statusCode":"200","statusMsg":"No
error, operation
successful.","count":1,"data":{"apiToken":"509e6d21-4f69-4ded-9f3d-4537e59e6a3a","userId":8,"role":"Bidder","firstName":"bidder","lastName":"bidder","emailAddress":"1cbrecbill#wricapitalgroup.com","countiesCovered":"21,16,11,1,2,14,32,3,4,25,13,15,5,41,43,6,12,7,24,39,17,36,42,44,29,40,8,18,19,27,9,28,23,10,33,26,35,20,30,22,34,31"}}}
//Data is Dictionary inside Result
-----------------------------------------------------------------------
I had an error showing : NULL DATACould not cast value of type 'NSNull' (0xda7058) to 'NSDictionary' (0xda6d74) and the result was
the following.
({"result":{"action":"authentication","statusCode":"204","statusMsg":"Invalid
Username or Password","count":null,"data":null}})
I fixed the Null check of dictionary.
if (result.objectForKey("data") is NSNull)
{
print ("NULL DATA")
}
else
{
let data = result["data"]as! NSDictionary
print (data)
}
Might want to add a bit more safety by checking to make sure it is NOT a string instead of just checking if it IS a nil. (To make sure it is not a number or anything else you might not want.)
id myImageURL = [result objectForKey:#"url"];
if (![myImageURL isKindOfClass:[NSString class]]) {
myImageURL = #"";
}
When you call objectForKeyin nullable dictionary, app gets crashed so I fixed this from this way to avoid from crash.
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:#"name"];
self.age = [dictionary objectForKey:#"age"];
}
return self;
}

[NSNull isEqualToString:]

Im trying to set a string to "No Display name if [object objectForKey#"display_name"] is NULL". It crashing with this in the log
2011-06-16 10:58:36.251 BV API[15586:ef03] displayNameType is: NSNull
2011-06-16 10:58:36.251 BV API[15586:ef03] +[NSNull isEqualToString:]: unrecognized selector sent to class 0x1228c40
2011-06-16 10:58:36.253 BV API[15586:ef03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSNull isEqualToString:]: unrecognized selector sent to class 0x1228c40'
*** First throw call stack:
(0x1198f1c 0x132b52e 0x119bb2b 0x10f3076 0x10f2bb2 0x116d9 0x112ad 0x8b0e17 0x8b9783 0x8b43ae 0x8b9d20 0xb6312b 0x815c35 0xac2e1e 0x8b7583 0x8b771d 0x8b775d 0xc1b5 0x7ed84c 0x7ed7e2 0x89477a 0x894c4a 0x893ee4 0x813002 0x81320a 0x7f960c 0x7ecd52 0x211b8f6 0x116831a 0x10c3d07 0x10c1e93 0x10c1750 0x10c1671 0x211a0c3 0x211a188 0x7eac29 0x1b29 0x1aa5)
terminate called throwing an exceptionsharedlibrary apply-load-rules all
Current language: auto; currently objective-c
NSString *displayNameType = (NSString *)[[object objectForKey:#"display_name"] class ];
NSLog(#"displayNameType is: %#", displayNameType);
NSString *displayNameString = [NSString stringWithFormat:#"%#", [object objectForKey:#"display_name"]];
displayNameString = [displayNameString uppercaseString];
if ([displayNameType isEqualToString:#"NSNull"]) {
NSLog(#"dnt is null");
NSString *displayNameString = #"No Display Name";
displayNameString = [displayNameString uppercaseString];
}
A cast will not change an object class (type).
You have to manage the case when your value is [NSNull null] with something like :
id displayNameTypeValue = [object objectForKey:#"display_name"];
NSString *displayNameType = #"";
if (displayNameTypeValue != [NSNull null])
displayNameType = (NSString *)displayNameTypeValue;
I created a category on NSNull, works well for me:
#interface NSNull (string)
-(BOOL) isEqualToString:(NSString *) compare;
#end
#implementation NSNull (string)
-(BOOL) isEqualToString:(NSString *) compare {
if ([compare isKindOfClass:[NSNull class]] || !compare) {
NSLog(#"NSNull isKindOfClass called!");
return YES;
}
return NO;
}
#end
You might want something like this:
NSString *displayNameType = NSStringFromClass([[object objectForKey:#"display_name"] class]);
And btw in your question, it shouldn't read "if it's NULL", but rather "if it's an NSNull instance".
I'll throw in my answer to clarify a bit. The problem is that the object in the NSDictionary has [NSNull null] value (slightly different to both nil and NULL). The issue comes from some libraries (a particular JSON parser comes to my mind) set the value for some keys with NULL value to [NSNull null]. Why? Because sometimes it is needed to differentiate in a NSDictionary the case when a key is not present from the case when the key has NULL value. In an NSDictionary there is no way of telling, but JSON structures do convey such difference. When you get a a variable that comes from a library or parser that does that the value may be [NSNull null]. NSNull is a singleton thus just checking for equality (pointer equality) is enough. For example I would do:
NSString *value = [object objectForKey:#"display_name"];
if (value && value != [NSNull null]){
// Here I have the value I expect
// Do something
}else{
// The value is null ... don't display
}
To my experience, the font may be well missing. If you got the problem, you could check where you set the new font and if it exists.
let font = UIFont.init(name:"YOUR_FONT_NAME", size: 16) -> is it nil or not ?
Detect whether or not the object is null instead of trying to infer from the class name.
// if you're key may not exist (NSDictionary will return nil... not sure what type
// you are using
if (![object objectForKey:#"display_name"]){
// ...
}
// or if the value may actually be an NSNull object
if ([[object objectForKey:#"display_name"] == (id)[NSNull null]){
// ...
}
I haven't tested the second argument, but look here for more about testing null.
I solved this by doing a check against [NSNull null]. The code I used in my app:
_lblBusinessName.text = _business.BusinessName != [NSNull null] ? _business.BusinessName : #"";
However XCode threw some warnings so to get rid of those I casted to an NSObject* type, like this:
_lblBusinessName.text = **(NSObject*)**_business.BusinessName != [NSNull null] ? _business.BusinessName : #"";

SKProduct attributes throw exc_bad_access

I'm implementing in app purchase in my app. I created a product at itunes and also product requesting functions in code successfully. the product returns. the problem is that i cannot access any of the attributes of the prouct (localizedTitle, price etc.). It allways throws exc_bad_access. here's my code:
NSMutableArray *myProduct = [[NSMutableArray alloc] init];
[myProduct addObjectsFromArray:response.products];
if(myProduct != nil && [myProduct count] > 0)
{
SKProduct *subscriptionProduct = [myProduct objectAtIndex:0];
if(subscriptionProduct != nil)
{
if(subscriptionProduct.localizedTitle != nil)
NSLog("%#",subscriptionProduct.localizedTitle); /***EXC_BAD_ACCESS** */
}
}
[request autorelease];
I set NSZombieEnabled YES, but still no explanation for exc_bad_access.
I'll be glad if someone has an answer.
Thanks in advance.
You've forgotten to put an # symbol before your NSLog format string:
NSLog(#"%#",subscriptionProduct.localizedTitle); /***EXC_BAD_ACCESS** */

TableView UISearchBar on Tab Bar Controller Crashes while Searching

I've been playing around with a search facility for my application table view for a while now trying to get it working but i keep getting the same error in my console.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' [NSCFDictionary rangeOfString:options:]: unrecognized selector sent to instance
I believe that this following section may be the problem I have tried passing some NSLog entries inside the if statement and it seems to get through it but the problem is when I click on the search bar and starting typing, the first letter I type calls the error and cancels my app.
Here is where the problem is
In View Will Appear "Food" Array is initialized as below:
NSString *myDBnew =#"/Users/taxsmart/Documents/rw3app.sql";
database = [[Sqlite alloc] init];
[database open:myDBnew];
NSString *quer = [NSString stringWithFormat:#"Select category from foodcat"];
Food = [database executeQuery:quer];
//[database executeNonQuery:quer];
[database close];
Search bar delegate method where error is encountered:
(void) searchTableView
{
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
// [searchArray addObjectsFromArray:Food];
for(NSDictionary *dictionary in Food)
{
NSString temp1 = [dictionary objectForKey:#"category"];
[searchArray addObject:temp1];
}
for (NSString *sTemp in searchArray)
{
NSLog(#"Value: %#",NSStringFromClass([sTemp class]));
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
What should I do?
Please Help.
Please Suggest
Thanks
It looks that result of database query (Food) is dictionary that contains dictionary. This code:
for(NSDictionary *dictionary in Food)
{
NSString temp1 = [dictionary objectForKey:#"category"];
[searchArray addObject:temp1];
}
can be replaced with:
for(NSDictionary *dictionary in Food)
{
NSObject *ob = [dictionary objectForKey:#"category"];
if([ob isKindOfClass: [NSString class]])
{
[searchArray addObject:ob];
}
else if([ob isKindOfClass: [NSDictionary class]])
{
NSDictonary *dic1 = (NSDictionary*)ob;
// ... at this point you can get the string for desired dictionary key
// or you can ignore it
}
}
With this code we can be sure that only strings are put into searchArray.
If you want to make full tree parsing for desired key 'category' then you should make some recursive function to search the dictionary.
You can dump Food variable to console to see at which leaf is actually the result you are looking for. Put the break-point and into console type 'po Food'.
Appears that there is an NSDictionary in your dataArray.
Add an
NSLog(#"%#",NSStringFromClass([description class]]));
To see which classes your dataArray contains.