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

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

Related

How to remove a null value directly from NSDictionary

I´m a beginer and have lately got a great deal of trouble with this issue.
I want to pass a NSDictnonary Data to a server from my app and in some cases if the user hasen´t chosen any option I want to remove nil objects.
I have looked into this thread that seems be the right method but I haven't succeed to implement in my code.
How to remove a null value from NSDictionary
My guess would be to implement the code to Null directly in my NSDictonary
Here´s my Dictionary code
-(NSDictionary*)parametersForCreateActivities
{
NSString *token = [[A0SimpleKeychain keychain] stringForKey:tokenConstant];
NSString *userId = [[A0SimpleKeychain keychain] stringForKey:child_id];
NSString *userCreate = [[NSUserDefaults standardUserDefaults] objectForKey:#"CreateTitle"];
NSString *createDescription = [[NSUserDefaults standardUserDefaults] objectForKey:#"DescriptionText"];
NSString *createTimestart = [[NSUserDefaults standardUserDefaults] objectForKey:#"TimeStartString"];
NSString *createTimestop = [[NSUserDefaults standardUserDefaults] objectForKey:#"TimeStopString"];
NSString *createImage = [[NSUserDefaults standardUserDefaults] objectForKey:#"DefaultcreateImageID"];
NSDictionary *parameters;
if (userId && token) {
parameters = #{child_id: userId, tokenConstant:token, activity_name :userCreate, create_Description :createDescription, create_Timestart :createTimestart, create_Timestop :createTimestop, create_Image :createImage};
}
return parameters;
}
My guess is that It should check somewhere in the code for nil objects and remove theme. But I have really struggled with figuring out how to format the code.
I´m guessing the code should be something like this but I have no idea where to place it and how to format it.
NSMutableDictionary *dict = [parametersForCreateActivities mutableCopy];
NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]];
[dict removeObjectsForKeys:DefaultcreateImageID];
Try below code
NSMutableDictionary *yourDictionary; // Your dictionary object with data
NSMutableDictionary *updatedDic = [yourDictionary mutableCopy];
for (NSString *key in [yourDictionary allKeys]) {
if ([yourDictionary[key] isEqual:[NSNull null]] || [yourDictionary[key] isKindOfClass:[NSNull class]]) {
updatedDic[key] = #"";
}
}
yourDictionary = [updatedDic copy];
NSLog(#"%#",yourDictionary);

keysSortedByValueUsingSelector crashes but sortedArrayUsingSelector runs fine

I found a workaround myself, but still trying to understand the problem.
I created a Autocomplete text field with the use of uitableview which is hidden until textfield is edited. The UI part works fine. It's the searching for the results part that's the problem. I declared a local NSMutableDictionary to store my results because I wanted the results to be sorted by the key's values.
if I call keysSortedByValueUsingSelector on the dictionary directly, it crashes. However if I get the keys by [dict allKeys] first, then call sortedArrayUsingSelector, it works fine:
// This commented out line will crash
// NSArray *sortedKeysArray = [dict keysSortedByValueUsingSelector:#selector(compare:)];
// The next two lines runs fine.
NSArray *keyArray = [dict allKeys];
NSArray *sortedKeysArray = [keyArray sortedArrayUsingSelector:#selector(compare:)];
Here is the complete source code for the search method:
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring
{
// Put anything that starts with this substring into the autocompleteUrls array
// The items in this array is what will show up in the table view
[autocomplete_symbol_array removeAllObjects];
rRSIAppDelegate *appDelegate = (rRSIAppDelegate *)([[UIApplication sharedApplication] delegate]);
NSString *input_str = [substring uppercaseString];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
int i = 0;
for(SymbolInfo *symbol_info in appDelegate.m_symbol_info_array)
{
i++;
NSString *info_str = [[[symbol_info.m_symbol uppercaseString] stringByAppendingString:#"|"] stringByAppendingString:[symbol_info.m_company_name uppercaseString]];
NSUInteger pos = [info_str rangeOfString:input_str].location;
if (pos != NSNotFound)
{
int tmp = pos * 10000 + i;
NSNumber *map_key = [[NSNumber alloc] initWithInt:tmp];
[dict setObject:symbol_info forKey:map_key];
}
}
// This commented out line will crash
// NSArray *sortedKeysArray = [dict keysSortedByValueUsingSelector:#selector(compare:)];
// The next two lines runs fine.
NSArray *keyArray = [dict allKeys];
NSArray *sortedKeysArray = [keyArray sortedArrayUsingSelector:#selector(compare:)];
for (NSNumber *key in sortedKeysArray)
{
SymbolInfo *symbol_info = [dict objectForKey:key];
[autocomplete_symbol_array addObject:symbol_info];
}
// NSLog(#"everything added: %d", [autocomplete_symbol_array count]);
[autocompleteTableView reloadData];
}
The NSMutableDictionary's method is:
- (void)setObject:(id)anObject forKey:(id < NSCopying >)aKey;
This means that the key should implement the NSCopying protocol.

Extracting Unique Objects from a Data Array

I want to add names in a data array only if the name does not previously exist in the data array. When I attempt to print these names, I do get repetitions. Is there a way to solve this?
-(NSMutableArray *)autoComplete
{
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSString *url = [NSString stringWithFormat:#"%#45.25,-95.25&limit=100&client_id=Von0J4Bu6INiez5bGby2R&client_secret=50sUjSbg7dba8cQgtpdfr5Ns7wyYTqtmKpUU3khQ",kWSURL];
NSDictionary * returnDict = (NSDictionary *) [self callWebService:url];
if([returnDict objectForKey:#"success"])
{
NSArray *responceArray = [returnDict objectForKey:#"response"];
for (NSDictionary *dict in responceArray) {
placeDC *place = [[placeDC alloc]init];
NSDictionary *placeDict = (NSDictionary *)[dict objectForKey:#"place" ];
NSDictionary *loctionDict =(NSDictionary *)[dict objectForKey:#"loc"];
NSString * name =[placeDict objectForKey:#"name"];
NSString * stateFull =[placeDict objectForKey:#"stateFull"];
NSString * countryFull =[placeDict objectForKey:#"countryFull"];
NSString *latitude =[loctionDict objectForKey:#"lat"];
NSString *longitude = [loctionDict objectForKey:#"long"];
place.placeNmae=name;
place.countryFullName=countryFull;
place.stateFullName=stateFull;
NSLog(#"%# ",stateFull);
place.latitude=[latitude doubleValue];
place.longitude=[longitude doubleValue];
[dataArray addObject:place];
}
}
return dataArray;
}
First Check that is there any response from the Server side or not, to check response use NSLog() or Break Points.
if response is ok then put a the following check your code
if (![dataArray containsObject:#"Some Name"])
{
// add Object
}
You could add the name NSString to an NSSet and check in every cycle whether it contains it or not.
Inside your if you could write something like:
NSArray *responceArray = [returnDict objectForKey:#"response"];
NSSet *names = [[NSSet alloc] init];
for (NSDictionary *dict in responceArray) {
NSDictionary *placeDict = (NSDictionary *)[dict objectForKey:#"place" ];
NSString * name =[placeDict objectForKey:#"name"];
if (![names containsObject:name]) {
[names addObject:name];
placeDC *place = [[placeDC alloc]init];
NSDictionary *loctionDict =(NSDictionary *)[dict objectForKey:#"loc"];
NSString * stateFull =[placeDict objectForKey:#"stateFull"];
NSString * countryFull =[placeDict objectForKey:#"countryFull"];
NSString *latitude =[loctionDict objectForKey:#"lat"];
NSString *longitude = [loctionDict objectForKey:#"long"];
place.placeNmae=name;
place.countryFullName=countryFull;
place.stateFullName=stateFull;
NSLog(#"%# ",stateFull);
place.latitude=[latitude doubleValue];
place.longitude=[longitude doubleValue];
[dataArray addObject:place];
}
}
Hope this helps!
Do one thing, add your dict in another array and search in this array that data already exist or not,
[tempAry addObject: dict];
and before insertion
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", name];
NSArray *filteredArray = [tempAry filteredArrayUsingPredicate:predicate];
if ([filteredArray count] == 0)
{
[dataArray addObject:place];
}
else{
//Already exist
}
Why don't you create a separate dictionary, as an ivar or property of you class, for storing our required value, say it as :
NSMutableDictionary *uniqueValueDict=[NSMutableDictionary new];
And keep storing your required value and key as:
[uniqueValueDict setObject:stateFull forKey:uniqueValueDict];
Your work will be done.
This is the easiest solution that i have applied and this should get you going in picking up unique elements out of array.
NSArray * claimedOfferArray = [[NSArray alloc]initWithObjects:#"A",#"B",#"A",#"C",#"B" nil];
NSArray * distinctArray = [[NSArray alloc]init];
distinctArray =[[NSSet setWithArray:claimedOfferArray] allObjects];
This code will also work with NSMutableArray
Let me know if it works for you..:).

Convert NSMutableArray to NSDictionary in order to use objectForKey?

I have an NSMutableArray that looks like this
{
"#active" = false;
"#name" = NAME1;
},
{
"#active" = false;
"#name" = NAME2;
}
Is there a way to convert this to an NSDictionary and then use objectForKey to get an array of the name objects? How else can I get these objects?
There is a even shorter form then this proposed by Hubert
NSArray *allNames = [array valueForKey:#"name"];
valueForKey: on NSArray returns a new array by sending valueForKey:givenKey to all it elements.
From the docs:
valueForKey:
Returns an array containing the results of invoking
valueForKey: using key on each of the array's objects.
- (id)valueForKey:(NSString *)key
Parameters
key The key to retrieve.
Return Value
The value of the retrieved key.
Discussion
The returned array contains NSNull elements for each object that returns nil.
Example:
NSArray *array = #[#{ #"active": #NO,#"name": #"Alice"},
#{ #"active": #NO,#"name": #"Bob"}];
NSLog(#"%#\n%#", array, [array valueForKey:#"name"]);
result:
(
{
active = 0;
name = Alice;
},
{
active = 0;
name = Bob;
}
)
(
Alice,
Bob
)
If you want to convert NSMutableArray to corresponding NSDictionary, just simply use mutableCopy
NSMutableArray *phone_list; //your Array
NSDictionary *dictionary = [[NSDictionary alloc] init];
dictionary = [phone_list mutableCopy];
This is an Array of Dictionary objects, so to get the values you would:
[[myArray objectAtIndex:0]valueForKey:#"name"]; //Replace index with the index you want and/or the key.
This is example one of the exmple get the emplyee list NSMutableArray and create NSMutableDictionary.......
NSMutableArray *emloyees = [[NSMutableArray alloc]initWithObjects:#"saman",#"Ruchira",#"Rukshan",#"ishan",#"Harsha",#"Ghihan",#"Lakmali",#"Dasuni", nil];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *word in emloyees) {
NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
letterList = [dict objectForKey:firstLetter];
if (!letterList) {
letterList = [NSMutableArray array];
[dict setObject:letterList forKey:firstLetter];
}
[letterList addObject:word];
} NSLog(#"dic %#",dict);
yes you can
see this example:
NSDictionary *responseDictionary = [[request responseString] JSONValue];
NSMutableArray *dict = [responseDictionary objectForKey:#"data"];
NSDictionary *entry = [dict objectAtIndex:0];
NSString *num = [entry objectForKey:#"num"];
NSString *name = [entry objectForKey:#"name"];
NSString *score = [entry objectForKey:#"score"];
im sorry if i can't elaborate much because i am also working on something
but i hope that can help you. :)
No, guys.... the problem is that you are stepping on the KeyValue Mechanism in cocoa.
KeyValueCoding specifies that the #count symbol can be used in a keyPath....
myArray.#count
SOOOOOO.... just switch to the ObjectForKey and your ok!
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:#"theValue", #"#name", nil];
id kvoReturnedObject = [myDictionary valueForKey:#"#name"]; //WON'T WORK, the # symbol is special in the valueForKey
id dictionaryReturnedObject = [myDictionary objectForKey:#"#name"];
NSLog(#"object = %#", dictionaryReturnedObject);

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.