Populate UITableView using NSMutableDictionary, keysSortedByValueUsingSelector - iphone

My model class has a NSMutableDictionary with my data. In my view class, I want to display that data in my UITableView cellforRowAtIndexPath method. My view class has an NSArray for the data to display.
I can do this to get my data into my NSArray to display correctly:
self.CategoriesArray = [model.CategoryDictionary allKeys];
However, since NSMutableDictionary does not sort on its own, my items in my TableView are not in alphabetical order. I thought I could do this:
However, I get the following error:
2Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFBoolean localizedCaseInsensitiveCompare:]: unrecognized selector sent to instance 0x13d0a20'
I'm assuming that's because my view class doesn't know what to do with the localizedCaseInsensitiveCompare method.
How do I solve this problem? Thanks.

I think you were saying that this gives you the correct results, just not in order, right?
self.CategoriesArray = [model.CategoryDictionary allKeys];
If that's the case, then this will give you the correct order if I'm understanding your question correctly:
NSArray* keys = [model.CategoryDictionary allKeys];
self.CategoriesArray = [keys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];

localizedCaseInsensitiveCompare: is only to compare NSString, not NSDictionary or NSArray.
To sort your categoriesArray look at
sortedArrayUsingComparator: and sortedArrayUsingDescriptors: for NSArray
sortUsingDescriptors and sortUsingComparator for NSMutableArray
To loop through your array you can do something like
for (NSString *string in categoriesArray)
{
}

Related

crash while removing objects from NSMutableArray

In my iphone project (ARC enabled) i have a nsmuatble array which contains some 5 managed objects (which are retrieved from core data ) and in some scenario i need to remove all the objects from that nsmutablearray
i have used following methods to remove objects but its crashing in both the cases with the crash log -[__NSArrayI removeObject:]: unrecognized selector sent to instance 0xa391640
if (surveys && [surveys count]>0)
{
[surveys removeAllObjects];
surveys = [[NSMutableArray alloc]init];
}
and also i tried
if (surveys && [surveys count]>0)
{
for(Survey *obj_Survey in surveys)
{
[surveys removeObject:obj_Survey];
}
surveys = [[NSMutableArray alloc]init];
}
can any one tell me how do i empty that array,, any suggestions would be appreciated, thanx in advance
The answer is very simple.
For First case.
Check the part where you have initialized your array, and check if somewhere through your code, if you have assigned an NSArray to your NSMutableArray object.
For second case.
You cannot remove objects from the array while you are enumerating through it. This will result in a crash saying array has mutated while enumerating
This:
[__NSArrayI removeObject:] : unrecognized selector sent to instance 0xa391640
indicates that your array "surveys" is NSArray (not-mutable). Are you sure you have initialized it properly? If you do it by an assignment like this
NSMutableArray* surveys = [someManagedObjectContext executeFetchRequest:request]
an array "surveys" will be of type NSArray because Core Data fetch requests return NSArrays.
The error message says it all,
[__NSArrayI removeObject:]: unrecognized selector
__NSArrayI is a code-word for an immutable array (NSArray), That means your surveys object is not NSMutablArray, but NSArray.
You cannot add or remove objects from NSArray.
Check your code. You have assigned NSArray to surveys or you have reinitialized it as NSArray.
Remove all the things that you are doing and simply do like this
[surveys removeAllObjects];
As from the error that you are getting so maybe that Array is not NSmutableArray just normal array so thats why you can not remove object from It and you try to do so and app got crash
check where you have initialised it if it is Mutable or not
so as I said remove all that thing and use simple removeAllObject
From the exception it's very evident that at some point you are assigning an immutable instance to your mutable array. From the comments I could make out that you were sorting surveys and sorted array was returning immutable array. Type casting will not do good for getting mutableCopy of an immutable object.
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1,nil];
surveys = (NSMutableArray *) [[[NSMutableArray alloc]initWithArray:surveys ] sortedArrayUsingDescriptors:sortDescriptors];
Instead of it use
[surveys sortUsingDescriptors: #[sortDescriptor1]];
You might have initialised with Immutable Array.
Use the following Code:
NSMutableArray *newArray = [NSMutableArray arrayWithArray: oldArray];

How to parse Json object

I'm stuck at json object parsing really tried hard. The problem is how to parse the json object. Here's what i get the response in the log.
{"0":{"**title**":"Test Event","url_title":"test_event1","status":"open","entry_date":"Sep 10, 2012,
05:20:38AM","entry_id":"26","site_id":"1","channel_id":"3","field_dt_40":null,"field_dt_58":null,"channel_title":"News &
Events","channel_name":"news_events","start_date":"1348120800","end_date":"1348120800","start_time": "43200","end_time":"46800","where":"FCF","news_event_description":"<p>\n\tLunch with group.<\/p>\n"},
"1":{"**title**":"Test Event 2","url_title":"test_event_2","status":"open","entry_date":"Sep 10, 2012, 05:20:08AM","entry_id":"28","site_id":"1","channel_id":"3","field_dt_40":null,"field_dt_58":null,"channel_title":"News & Events","channel_name":"news_events","start_date":"1348207200","end_date":"1348207200","start_time":"43200","end_time":"46800","where":"FCF - Lunch","news_event_description":"<p>\n\tThis was a great event.<\/p>\n"},
"2":{"**title**":"Test Event 3","url_title":"test_event_3","status":"open","entry_date":"Sep 10, 2012, 05:20:54AM","entry_id":"29","site_id":"1","channel_id":"3","field_dt_40":null,"field_dt_58":null,"channel_title":"News & Events","channel_name":"news_events","start_date":"1346738400","end_date":"1346738400","start_time":"7200","end_time":"11700","where":"FCF - Lunch","news_event_description":"<p>\n\tFall planning season.<\/p>\n"}}
The problem is i want to show all the titles in the tableview. I can get the single Title by using key 0,1,2. But i want all the titles to be shown at once i parse
Please help me out guys, Thanks in advance.
Suppose jsonDict is your json dictionary.... Try this
NSArray * keys=[[NSArray alloc]init];
keys=[jsonDict allKeys];
NSMutableArray *titles=[[NSMutableArray alloc]init];
for(int i=0;i<[keys count];i++){
[titles addObject:[[jsonDict valueForKey:[keys objectAtIndex:i]]valueForKey:#"title"]];
}
NSLog(#"your array of titles : %#",titles); //use this array to fill your cell
Are you trying to parse the JSON yourself? You might find it easier to use something that's already well tested, such as TouchJSON or Apple's own NSJSONSerilization. The result should be a graph of Objective-C objects that you can use however you like.
In any case, what you've got there is the equivalent of a dictionary of dictionaries. If you have that as a NSDictionary called myJSONDictionary, you can say:
NSArray *theObjects = [myJSONDictionary allValues]; // gets all the objects
NSArray *theTitles = [theObjects valueForKey:#"**title**"]; // gets all the titles
You can also iterate through a dictionary using fast enumeration:
NSMutableArray *theTitles = [NSMutableArray array];
for (NSString *key in myJSONDictionary) {
NSDictionary *object = [myJSONDictionary objectForKey:key];
NSString *title = [object objectForKey:#"**title**"];
[theTitles addObject:title]
}
There's no real advantage to doing that instead of using KVC as in the first example if you just need the titles, but it could be the right choice if you have more complex work to do for each object.

NSMutableArray automatically typecasting into NSArray

I created an NSMutableArray object by
NSMutableArray *array = [[NSMutableArray alloc]init];
and used method componentsSeperatedByString: as
array = [myString componentsSeperatedByString:#"++"];
but when I performed operation on array like,
[array removeAllObjects];
I got exception like "removeAllObjects unrecognized selector send to instance".
I solved this issue by modifying code like,
NSArray *components = [myString componentsSeperatedByString:#"++"];
array = [NSMutableArray arrayWithArray:components];
and I after that could perform operation like
[array removeAllObjects];
My doubt is why did NSMutableArray automaticaqlly converted to NSArray? How Can I avoid automatic type conversion like this, to prevent exceptions? Thanks in advance....
There is a mistake in your understanding of how Objective-C works. This line:
NSMutableArray *array = [[NSMutableArray alloc]init];
allocates and initializes the array, and the pointer array points to this object. Now, this line:
array = [myString componentsSeperatedByString:#"++"];
makes the array pointer to point to the new array returned by componentsSeparatedByString method. You loose the reference to your alloced and inited mutable array when you do this, and you create the memory leak if you don't use ARC.
This is happening because [myString componentsSeperatedByString:#"++"] returns an NSArray. You can try something like this:
array = [[myString componentsSeperatedByString:#"++"] mutableCopy];
or
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
This is because – componentsSeparatedByString: returns a NSArray: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/componentsSeparatedByString:
Do something like:
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
On the line
array = [myString componentsSeperatedByString:#"++"];
you are replacing the NSMutableArray you allocated with a new NSArray (and leaking your NSMutableArray. Try using this:
NSMutableArray *array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
It's not converted, the array pointer could be UIButton* if you write something like
array = [self likeThatButton];
where likeThatButton is your method returning UIButton*. As always in objective c, NSMutableArray *array means only the Xcode will try to analyze your code and suggest convenient warnings and code completion.
An NSMutableArray instance won't be converted automatically.
The method componentsSeperatedByString returns an NSArray-Object. You should get a compiler warning when assigning the return-value to a NSMutableArray-Pointer.

Editting NSMutableDictionary in array

I've got a question: I've got an NSMutableArray, which I pass on in multiple views. In one of the views, a value of an object inside that array (NSMutableDictionary) can be editted. I do that using the code:
NSMutableDictionary *tester = [[NSMutableDictionary alloc] initWithDictionary:selectedItem copyItems:YES];
NSMutableString *newLoc = [[NSMutableString alloc] initWithString:locationField.text];
[tester setValue:newLoc forKey:#"Location"];
[selectedList replaceObjectAtIndex:[selectedList indexOfObject:selectedItem] withObject:tester];
The problem I'm having with this, is replacing that object in selectedList. It gives the error *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0xa631e30'
It works if I copy the new item in a copy-array of selectedList, and alloc selectedList with the new value again, but the other views are having problem finding that same list again in the array (new allocated location).
TL;DR version: how can I edit a value (through replacing?) inside an NSMutableArray? Why doesn't replaceObjectAtIndex work?
EDIT: It was immutable indeed. Still, the main question remains:
I've got:
NSMutableDictionary *tester = [[NSMutableDictionary alloc] initWithDictionary:geselecteerdItem copyItems:YES];
[geselecteerdItem setValue:nieuweLoc forKey:#"Location"];
[geselecteerdeLijst replaceObjectAtIndex:[geselecteerdeLijst indexOfObject:tester] withObject:geselecteerdItem];
When I'm using: [warningList replaceObjectAtIndex:[warningList indexOfObject:geselecteerdeLijst] withObject:keuzeLijst], it gives me an outofbounds error because the index of the array geselecteerdeLijst obviously changed inside warningList. Any idea's?
selectedList is an immutable array, which doesn't support any modifications. You can do something like this, though:
NSMutableArray *tmp = [NSMutableArray arrayWithArray: selectedList];
[tmp replaceObjectAtIndex:[selectedList indexOfObject:selectedItem] withObject:tester];
EDIT: To clarify, __NSArrayI is a concrete immutable subclass of NSArray, __NSArrayM is a mutable one. You should not rely on the private class names, but since they speak for themselves, you can at least know which is mutable and which is not.

Remove an object in NSMutableArray?

I have a NSMutableArray like this:
NSMutableArray *array =...; (array contain my custom object)
NSMutableArray *toRemove = [array getObjectsToRemove];
But when I try to call removeObjectsInArray ( [array removeObjectsInArray:toRemove]; ) it breaks my app! Can anybody tell me how to solve my problem :(
I expect the error you are getting is "[NSMutableArray getObjectsToRemove] unrecognized selector sent to.."
NSMutableArray does not have such a method.
That's as far as I can answer without a bit more information, like the actual error message and the code for getObjectsToRemove (wherever it is defined).