NSMutableData to NSDictionary returning null - ios

I'm writing a program that uses the Instagram API and I'm running into some issues with NSMutableData and NSDictionary.
Since I have to make multiple calls to the API, I decided to create a NSMutableData object, append smaller NSData objects to it and then turn the whole thing into an NSDictionary.
However, after I make a second call to NSMutableData appendData NSData, when I turn NSMutableData into an NSDictionary, the dictionary returns null.
Here's some of my code.
NSMutableData *userData = [[NSMutableData alloc]init]
NSData *feed = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.instagram.com/v1/users/17636367/media/recent?access_token=%#",accessToken]]];
[userData appendData:feed];
NSData *moarData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.instagram.com/v1/users/17636367/media/recent?access_token=%#&max_id=%#",accessToken, maxID]]];
[userData appendData:moarData];
NSDictionary *dictTwo = [NSJSONSerialization JSONObjectWithData:userData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#",dictTwo);
dictTwo returns null. However, when I make only one call to appendData, the dictionary isn't empty.
Thanks.

When you append two separate JSON responses they will not form a JSON.
You can test the final result to see if it is JSON or not with the following link:
JSON validator
You need to parse each query response separately and then apply manipulation on that data: (Ex NSMutableDictionary, NSMutableArray etc).

The first call will return an array or dictionary. Assuming it is a dictionary you would get something like:
{"some":"data"}
This can be parsed correctly. When you make two calls you get:
{"some":"data"}{"other":"data"}
This is not valid JSON. You need to parse each item separately.

Related

Convert NSString representing an array of arrays of numbers to NSArray

I am receiving a string in my request; the string is a list of pairs of numbers, grouped with square brackets. (The list represents polygons to display inside my app.)
I need to convert it to an NSArray and parse all the numbers into coordinates.
The received string is
[[[53.502483, -113.420593], [53.503429, -113.421527], [53.503491, -113.421673], [53.503002, -113.42164], [53.502719, -113.421426], [53.502483, -113.420593]]]
All the examples I've found are just to convert a single list in text to NSArray. I couldn't find anything where there are multiple arrays in the string.
The string looks like valid JSON, so...
NSError *error;
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:nil error:&error];
Will give the array, provided string contains the input. If it's coming from a web request, you can save a step and convert the request's NSData directly.

NSPropertyListSerialization returning nil instead of serialized data

I am putting two NSMutableArray objects into an NSDictionary and trying to serialize, but the method call is returning nil. One array, addresses, is an array of NSString objects. The other, engines is an array of objects that each contain several data types. I am attempting to serialize using the following code:
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:engAddr forKey:#"engAddr"];
[dictionary setObject:trainList forKey:#"engines"];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:dictionary
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
Stepping through, the debugger shows the arrays are properly added to the dictionary, but after the line that should serialize the dictionary it shows data = (NSData *) nil.
Where am I going wrong? Thank you for your help!
What kind of objects does engines contain?
Plist supports only specific objects below.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html#//apple_ref/doc/uid/10000048i-CH3-54303
If you want to serialize a custom object, convert it to NSData by NSKeyedArchiver.
To do that, objects must conform NSCoding protocol.

Parse json Data in iOS

I know it's a common question, but I am stuck with is API
How to Parse data from this API : http://dl.bahramradan.com/api/1/get/ig
it contain 20 Object and in every object there are 3 other Objects called "image",date" and "caption"
how can I store all "date" values in an NSMUtableArray in ios?
I did this :
NSString *urlStr = [NSString stringWithFormat:#"http://dl.bahramradan.com/api/1/get/ig"];
NSURL *url = [NSURL URLWithString:urlStr];
NSData *json = [NSData dataWithContentsOfURL:url];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:json options:0 error:NULL];
NSArray *dateArray = [dict objectForKey:#"date"];
But when I run my app, it crashs on the last line, what is wrong ?
I did not check, if your JSON is valid. But there is one obvious mistake in your code: If the JSON consists of 20 objects, I assume those being contained in an array, rather than in a dict!
So first thing to change is
NSArray *array = [NSJSONSerialization JSONObjectWithData:json options:0 error:NULL];
Then, you want to extract the 'date' values for all items and combine these in another array.
Easiest way to achieve that, is by using a KVC Collection Operator
NSArray *dateArray = [array valueForKeyPath:#"#unionOfObjects.date"];
So, what '#unionOfObjects.date' does, is: going through all the objects in the array, look for each of their 'date' value and combine them in the returned array.
Check out this excellent post about KVC Collection Operators!

Sending a CoreData NSManagedObject to Another Player in Game Center

How do I send a core data object called Deck *deck, which contains an NSString, an NSData photograph object, and an NSSet (a one-many relationship to other entities).
When I tried to send the Deck *deck using the [GKMatch sendData:toPlayers:] method, the NSData *outgoingPacket remained nil, but *deck had an address, according to the debug console.
- (void) sendDeck {
NSError *error;
NSData *outgoingPacket = [NSData dataWithBytes:&_deck length:sizeof(_deck)];
[self.myMatch sendData:outgoingPacket toPlayers:[NSArray arrayWithObject:self.pickerViewFriend] withDataMode:GKMatchSendDataReliable error:&error];
//myMatch is an instance of GKMatch.
//_deck is an instance variable set by #property Deck *deck, which is assigned by a UIPickerView, which works perfectly
}
(I realize this doesn't even address sending the cards associated with the deck, but I'm stuck at this point)
There are a couple of problems with this line:
NSData *outgoingPacket = [NSData dataWithBytes:&_deck length:sizeof(_deck)];
Since _deck is a pointer to an object (an instance of Deck), sizeof(_deck) just gives you the size of the pointer. That's just big enough for a single memory address.
You can't really fix the call because dataWithBytes:length: works with a contiguous block of memory. Your managed object is extremely unlikely to pass that test.
You could send each field independently, but that's kind of messy. An easier alternative would be to use NSDictionary as your transfer object. Convert between NSDictionary and Deck as needed, and encode NSDictionary as an NSData for transfer. Something like:
NSDictionary *dict = // Fill this with the values you want to send
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
Then at the other end,
NSData *data = // data received from other device
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];

iOS : JSON String to NSArray not working as expected

How to parse a a JSON string in iOS app? Using SBJSON. Running the code below. Getting data is successful but the count on the number of entries in the array is zero even tho the JSON string contains entries. My question is how query the JSON string in a loop?
Thanks!
// Create new SBJSON parser object
SBJsonParser *parser = [[SBJsonParser alloc] init];
// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://safe2pee.org/api/proxlist.php?location=37.7626214,-122.4351661&distance=1"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"string equal = %#", json_string);
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON b objects
NSArray *bathrooms = [parser objectWithString:json_string error:nil];
NSLog(#"count = %d", [bathrooms count]);
// Each element in bathrooms is a single bathroom
// represented as a NSDictionary
for (NSDictionary *bathroom in bathrooms)
{
// You can retrieve individual values using objectForKey on the bathroom NSDictionary
// This will print the tweet and username to the console
NSLog(#"%# - %#", [bathroom objectForKey:#"name"], [[bathroom objectForKey:#"lat"] objectForKey:#"long"]);
}
It's because it's not working. That's not a valid JSON string. That's 2 JSON dictionaries, back to back, with a comma in between. It's missing the wrapping []. If you actually test the result value of -objectWithString:error:, you'd see it's nil, and if you pass in an NSError** to the error parameter there, you'd get back an error message telling you it's invalid JSON.
I looked at the JSON string returned when I request the URL in your post, and it looks like it is being improperly truncated by the server. The JSON string returned contains a dictionary structure containing, among other things, a key called "bathrooms" whose value is an array of dictionary structures. Each of those bathroom dictionary structures contains several fields including "bid", "name", "lat", ..., "directions", and "comment".
When I scroll to the end of the JSON I received, I see a complete dictionary structure under the "bathrooms" array ("bid" is "MTIyIFMyUA==", "name" is "Momi Tobi's". That dictionary structure contains its closing brace but the closing "]" for the array is missing and the closing "}" for the top-level dictionary structure is missing.
You should look to the service to see why it is returning invalid JSON strings. Once you have a valid string it looks like you should be starting with an NSDictionary and parsing it something like this:
NSDictionary *result = [parser objectWithString:json_string error:nil];
NSArray *bathrooms = [result objectForKey:#"bathrooms"];

Resources