Weird NSDictionary crash - iphone

I have the following code:
NSDictionary *dict = [[NSDictionary alloc]
initWithObjectsAndKeys:myarray1, #"array1", myarray2, #"array2" nil];
NSArray *shorts =[[dict allKeys] sortedArrayUsingSelector:#selector(compare:)];
for (NSString *dir in shorts) {
NSArray *tempArr = [dict objectForKey:dir];
for (NSString *file in tempArr ) {
NSLog(#"%#", file);
}
}
Where myarray1 and myarray2 are NSArrays.
When I execute the code the application crashes with:
-[NSCFString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x1d134
This is apparently the tempArr, which is not recognized as an NSArray. I know that [dicFiles objectForKey:dir] returns an id type object, but as a generic type, I cannot get what I'm doing wrong.

You haven't included the code that initializes myarray1 and myarray2, but apparently one or both of them are instances of NSString rather than NSArray. You can check that after retrieving one of the objects from the array as follows:
if (![tempArr isKindOfClass:[NSArray class]])
{
NSLog(#"Unable to process temp array because it's an instance of %#", [tempArr class]);
}
else
{
// for loop code goes here...
}

Related

Core Data table to NSArray

I have the following Array which retrieved from the Core Data :
NSArray *dataArray = [context executeFetchRequest:request error:&error];
so I wrote this code to get each row data individually to send it to REST API:
for (NSString *str in dataArray) {
NSString *name =[dataArray valueForKey:#"name"];
NSString *dob = [dataArray valueForKey:#"dob"];
int gender =[[dataArray valueForKey:#"gender"]integerValue];
NSString *childId =[dataArray valueForKey:#"id"];
int response = [network sendName:name withDateOfBirth:dob andGender:gender forID:childId];
if (response == 200) {
// [self performSelectorOnMainThread:#selector(postSuccess) withObject:nil waitUntilDone:YES];
NSLog(#"Success");
}
}
but it's not working, because I couldn't know how data is stored in each index in the array!!
Please help, and if I am not doing this correctly please tell me a better way to do it.
Thanks.
NSString *name =[dataArray valueForKey:#"name"];
This doesn't do what you think it'll do. valueForKey:, when sent to an array, returns an array of the values corresponding to the given key for all the items in the array. So, that line will assign an array of the "name" values for all the items in dataArray despite the fact that you declared name as a NSString. Same goes for the subsequent lines.
What you probably want instead is:
for (NSManagedObject *item in dataArray) {
NSString *name = [item valueForKey:#"name"];
...
Better, if you have a NSManagedObject subclass -- let's call it Person representing the entity you're requesting, you can say:
for (Person *person in dataArray) {
NSString *name = person.name;
...
which leads to an even simpler version:
for (Person *person in dataArray) {
int response = [network sendName:person.name
withDateOfBirth:person.dob
andGender:person.gender
forID:person.id];
although I'd change the name of that method to leave out the conjunctions and prepositions. -sendName:dateOfBirth:gender:id: is enough, you don't need the "with", "and", and "for."

how can adding Key float values from NSDictionary to NSarray?

My brain is fried! I can't think.
i am new to iphone programming
am doing json parsing ....in that am storeing data from json to nsdictionary but .......
I want to add all nsdictionary float values from the dictionary to the array. This is what I am doing right now.As code below:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
dict = [responseString JSONValue];
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in [dict allKeys])
{
array = [dict objectForKey:key];
// array return float values but
[array addObject:array ]; // geting carsh dude to array return float values like 120.01
}
Please guide me i am not getting a part where i am doing a mistake.
Thanks in advance.
Your app is crashing because you are adding data to NSArray , this is static array, you can not add value at run time, so just Make NSMutableArray and add your data in NSMutableArray.
Your code is broken in a couple of ways.
This line assigns the array pointer to the object in the dictionary:
array = [dict objectForKey:key];
Then you are trying to add the array to itself, which does not make sense. But worse, since array does no longer point to your NSMutableArray you cannot even call that method.
[array addObject:array ];
You probably wanted to do something like this:
for (NSString *key in [dict allKeys])
{
id value = [dict objectForKey:key];
[array addObject:value];
}

Adding values into my plist

I have this plist that I have created
I have written most of my controller class which gets this plist and loads it into the documents directory so its possible to read/write to is.
Currently I have the reading working fine, and I used to have the writing working also, however I have just recently changed one of the objects (cache value) to a Dictionary with values related to that. Now when I try to write to this plist my app is crashing.
This is the error I am getting.
2012-04-05 09:26:18.600 mycodeTest[874:f803] * Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '*
-[NSDictionary initWithObjects:forKeys:]: count of objects (4) differs from count of keys (5)'
*** First throw call stack: (0x12cc022 0x1884cd6 0x1248417 0x12685e2 0x19844 0x17e86 0x17669 0x13b67 0xe53a49 0xe51e84 0xe52ea7 0xe51e3f
0xe51fc5 0xd96f5a 0x1d2aa39 0x1df7596 0x1d21120 0x1df7117 0x1d20fbf
0x12a094f 0x1203b43 0x1203424 0x1202d84 0x1202c9b 0x21aa7d8 0x21aa88a
0x450626 0x77ed 0x1e35 0x1) terminate called throwing an
exceptionCurrent language: auto; currently objective-c
with all of this in mind I will now show you my method, which is called from another class when it has the values ready to be saved.
//This method gets called from another class when it has new values that need to be saved
- (void) saveData:(NSString *)methodName protocolSignature:(NSString *)pSignature protocolVersion:(NSNumber *)pVersion requestNumber:(NSNumber *)rNumber dataVersionReturned:(NSNumber *)dvReturned cacheValue:(NSMutableDictionary *)cValue
{
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"EngineProperties.plist"];
// set the variables to the values in the text fields that will be passed into the plist dictionary
self.protocol = pSignature;
self.Version = pVersion;
self.request = rNumber;
self.dataVersion = dvReturned;
//if statment for the different types of cacheValues
if (methodName == #"GetMan")
{
//cache value only returns the one cachevalue depending on which method name was used
[self.cacheValue setValue:cValue forKey:#"Man"]; //do I need to have the other values of cacheValue dictionary in here? if so how do I do that.
c
}
else if (methodName == #"GetMod")
{
[self.cacheValue setValue:cValue forKey:#"Mod"];
}
else if (methodName == #"GetSubs")
{
[self.cacheValue setValue:cValue forKey:#"Subs"];
}
// This is where my app is falling over and giving the error message
// create dictionary with values in UITextFields
NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: protocol, pVersion, rNumber, dvReturned, cacheValue, nil] forKeys:[NSArray arrayWithObjects: #"Signature", #"Version", #"Request", #"Data Version", #"Cache Value", nil]];
NSString *error = nil;
// create NSData from dictionary
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
// check is plistData exists
if(plistData)
{
// write plistData to our Data.plist file
[plistData writeToFile:plistPath atomically:YES];
NSString *myString = [[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding];
NSLog(#"%#", myString);
}
else
{
NSLog(#"Error in saveData: %#", error);
// [error release];
}
}
I am abit lost when the error is saying that 4 keys differ from 5 when as far as i can tell i am applying 5 values to the dictionary any help would be appreciated.
Edit** another thing I noticed when debugging my issues was the fact it looks like I am not getting my cacheValue dictionary set up properly as its showing 0 key valuepairs??? is this right or wrong?
this is what happens when I log my plist in xcode as suggested below when I use [NSDictionary dictionaryWithObjectsAndKeys:..etc
Check setup is everything there?
Temp Dic output = {
Root = {
"Cache Value" = {
Manu = 0;
Mod = 0;
Sub = 0;
};
"Data Version returned" = 0;
"Signature" = null;
"Version" = 0;
"Request Number" = 0;
};
Run Man cache check results
Temp Dic output = {
"Version returned" = 5;
"Signature" = Happy;
"Version" = 1;
"Request Number" = 4;
as you can see Cache Value is completely missing after I have run the request.
I'm going to guess that cacheValue is nil when the crash occurs, resulting in only 4 objects in your values array, but 5 in keys.
Try using [NSDictionary dictionaryWithObjectsAndKeys:] instead.
In a situation like this, break up your code. Do each piece on a separate line, with temporary variables.
Put your keys and your values into temporary arrays.
Lot the values of everything, or set breakpoints in the debugger and examine all your values. Eli is almost certainly right that cacheValue is nil. The arrayWithObjects method stops on the first nil.
This code:
NSString *string1 = #"string 1";
NSString *string2 = #"string 2";
NSString *string3 = #"string 3";
NSString *string4 = nil;
NSString *string5 = #"string 5";
NSArray *anArray = [NSArray arrayWithObjects:
string1,
string2,
string3,
string4,
string5,
nil];
NSLog(#"anArray has %d elements", [anArray count]);
Will only show 3 elements in the array, even though the arrayWithObjects line appears to add 5 elements

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.

NSMutableArray not working properly...(count shouldn't be returning zero!)

NSMutableArray count is returning zero after adding objects to it, its been an hour of hacking away trying to figure out why, and I'm still stuck, so that brings me here.
Any ideas based off the following code, what the problem is?
the object 'search' is a custom class defined in the header set as a pointer, with retain, nonatomic attributes.
- (NSMutableArray *) populateArrayFromPlist{
NSLog(#"Populate Array from PList");
NSDictionary *dictionary;
// read "foo.plist" from application bundle
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"asearch.plist"];
dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
for (id key in dictionary)
{
search = [[ASearch alloc] init];
[dictionary valueForKey:key];
[search setID:[[dictionary valueForKey:key] intValue] ];
//[[search searchString] initWithString: key];
search.searchString = [[NSMutableString alloc] initWithString: key];
if (search == nil) {
printf("Let me know now\n\n\n\n");
}
NSLog(#"%#", [search searchString]);
NSLog(#"Setting string Value: %s\n", [key cString]);
NSLog(#"Setting ID Value: %i\n", [[dictionary valueForKey:key] intValue]);
//NSLog(#"aSearchArray count == %i", [[aSearchArray count] intValue]);
[aSearchArray addObject:search];
NSLog(#"aSearchArray count == %i", [aSearchArray count] );
aSearchArray is a nil object that is the only reason why you are getting count as zero.
For more confirmation just create a new local array and try to add your object to it.
You will get a proper count