NSDictionary to NSArray not converting (Signal SIGBRT) - objective-c

I have a very simple HTTP query that runs and grabs some JSON object in another class. I have an NSDictionary object called finalDataArray being defined. I am basically trying to loop through and append names to a table, the number of rows are being calculated correctly. finalDataArray.count
But when I try to do this, I get an error on the first line below.
NSArray *contactArray = [finalDataArray allKeys];
NSLog(#"%#", contactArray);

Because I am such a newb, I didn't realize that if you had a "Miltidimensional" JSON object... it should be NSDictionary, but if you have a single dimenstional object... it should be NSArray which fixes my issue...
Thanks for all the help.

Related

NSPredicate with "NOT IN" condition fails

Ok, here's my problem. I am synchronizing data from a server via a REST-api. The returned data is in JSON, I loop through it and takes appropriate actions depending on the data. That is, I either store it as a new object, updates the object if it already exists or deletes it if only exists locally.
To achieve this, I collect the IDs from the returned objects when I loop through the JSON. This gives me a index of all the returned objects. I then query my locally stored data to see if it contains any objects that should be deleted (in other words, if the local ID does exists or not in the JSON response).
And here's my issue (sorry for a somewhat lengthy prologue); the NSPredicate that I use only works for certain scenarios and which ones work or fails seems to be random.
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// Array which populates with the IDs from the server
NSMutableArray *arrayOfLogIDS = [[NSMutableArray alloc] init];
/*
Fetching and parsing JSON ... collecting IDs and adding them to the array. See example below;
*/
NSArray *logs = [[json valueForKey:#"Logs"] valueForKey:#"Object"];
// Looping through the logs array
for (NSArray *log in logs) {
[arrayOfLogIDS addObject:[log valueForKey:#"serverID"]];
}
// The NSPredicate
NSPredicate *serverIDS = [NSPredicate predicateWithFormat:#"NOT (serverID IN %#)", arrayOfLogIDS];
// The array which holds the objects that should be deleted
NSArray *logs = [Logs MR_findAllWithPredicate:serverIDS inContext:localContext];
}];
The problem is just that the NSPredicate won't work for this specific circumstance. It returns no results even though I know I have objects locally that should be deleted.
I use this approach in other places in the application, and it works as expected. As you can see I am using Magical Record for Core Data management in this app.
I feel that I have completely run out of things to try next, so any help would be much appreciated! :)
Ok, as it turns out, the array of IDs sometimes had the values stored as string and sometimes as integers. Integers worked well with NSPredicate, strings not so much :) Solved! Thanks all for your time.

Appending NSDictionary to other NSDictionary

I have one NSDictionary and it loads up UITableView. If a user scrolls more and more, I call API and pull new data. This data is again in the form of an NSDictionary. Is it possible to add the new NSDictionary to the existing one?
You looking for this guy:
[NSMutableDictionary addEntriesFromDictionary:]
Make sure your UITableView dictionary is an NSMutableDictionary!
Check it here
Use NSMutableDictionary addEntriesFromDictionary to add the two dictionaries to a new mutable dictionary. You can then create an NSDictionary from the mutable one, but it's not usually necessary to have a dictionary non-mutable.
Is your NSDictionary full of other NSDictionaries? It sounds like you would need an NSMutableArray that you could add NSDictionaries to at the end. Assuming you can control the flow of data coming in and wouldn't run the risk of duplicates in your array, you could certainly append the data.
NSMutableArray *array = [[NSMutableArray alloc] init];
arrayCount = [array count]; // check the item count
[array addObject:dictToAppend];
Without seeing how you are implementing it, I can't provide more detailed code examples. Appending items is easy to do, but know it can only be done with mutable versions of Arrays or Dictionaries. Hope this helps a little.

What is the best approach to convert immutable objects to mutable objects (recursive)?

Specifically, this problem has come to me when I make a request with AFNeworking with JSONkit and receive a (id)JSON with several arrays and dictionaries nested.
If I don't want to modify the data, I don't have any problem:
self.myNSArray = [JSON objectForKey:#"result"];
But if I want to modify the data I must to store it in a mutable variable:
self.myNSMutableArray = [[JSON objectForKey:#"result"] mutableCopy];
The last one doesn't convert nested arrays or dictionaries to mutable data; it works only for first level.
The only way that I have found is on this link recursive mutable objects; but I don't know if there is a best way to resolve this kind of problem.
Thanks in advance.
You could use the CoreFoundation function CFPropertyListCreateDeepCopy with the mutability option kCFPropertyListMutableContainersAndLeaves:
NSArray *immutableArray = [JSON objectForKey:#"result"];
self.myMutableArray = [(NSMutableArray *)CFPropertyListCreateDeepCopy(NULL, immutableArray, kCFPropertyListMutableContainersAndLeaves) autorelease];
On ARC:
CFBridgingRelease(CFPropertyListCreateDeepCopy(NULL, (__bridge CFPropertyListRef)(immutableArray), kCFPropertyListMutableContainersAndLeaves))
really worked. Thanks
brainjam.
Make sure you are taking care of null values in response string, otherwise it will return you nil which causes to horrible results.
(For Eg. Try mutataing response from
http://www.json-generator.com/api/json/get/bQVoMjeJOW?indent=1)
Just place below line when converting API response to JSON Object.
responseString=[responseString stringByReplacingOccurrencesOfString:#"\":null" withString:#"\":\"\""];//To Handle Null Characters
//Search for below line in your parsing library and paste above code
data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
So there will be no null characters in your JSON object, hence no issue with using CFPropertyListCreateDeepCopy.
Cheers!!

How can I do a multidimensional lookup table in Objective-C?

New to Objective-C here...
I have a unique string code as the key that I'd like to use to look up associated values.
It seems an NSDictionary is what I'm looking for but I believe this is only used to lookup one value for a given key.
Can anyone provide the code on how to declare/fill a multidimensional immutable NSDictionary? Also the code to retrieve the values?
Also, please let me know I'm going about this the wrong way
Thanks
EDIT: example of array within a dictionary .... using example data from your comment.
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
NSArray *firstSet = [[NSArray alloc] initWithObjects:43, 22];
NSArray *secondSet = [[NSArray alloc] initWithObjects:32, 50];
[myDictionary setValue:firstSet forKey:#"010"];
[myDictionary setValue:secondSet forKey:#"011"];
// Get a value out - should be the 50 that you want
NSInteger *myValue = [[myDictionary objectForKey:#"011"] objectAtIndex:1];
Not tested - but should be 95% right. Does this make sense?
You can make any object you want be the value for a given key in an NSDictionary. This includes NSArray or even another NSDictionary. Using either of these would allow you to associate multiple values with one key.
For nested NSDictionaries or custom KVC-complient classes you can use keyPaths, and for nested NSArrays indexPaths.
Also stackoverflow will give you many examples.

appending array in objective c

i read this command from cocoadev.com but was not able to get it plz help me in explaining what this line of code do
[array addObject:[NSNumber numberWithInt:15]];
You have to use NSMutableArray instead of NSArray to use the method addObject:.
It adds a number object with the integer value of 15 to the collection (presumably an NSMutableArray) called array.