Using NSJSONSerialization for mac - objective-c

I'm trying to user NSJSONSerialization in a mac app, but i can't get it working, I'm trying to get it to load UserTimeline, and just show the text of the last tweet, and thats it, but I can't seem to find the proper way to use it. the api i have tried to use :
http://api.twitter.com/1/statuses/user_timeline.json?screen_name=AlexTrott_
And
http://twitter.com/statuses/user_timeline/AlexTrott_.json
but neither of them i've had look, this is how i've been trying to use NSJSONSerialization :
NSString *tweets = [NSURL URLWithString:#"http://twitter.com/statuses/user_timeline/AlexTrott_.json"];
NSData *jsonData = [tweets dataUsingEncoding:NSUTF8StringEncoding];
NSError *e = nil;
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSLog(#"%#", json);
that is just what i've been using to see if it's loaded them, but it's been failing me.
I also tried was going to try this method http://www.raywenderlich.com/5492/working-with-json-in-ios-5 however thats solely for iOS and i don't know how i'd get it to work on Mac.
Any links on how to use NSJSONSerialization for mac would be brilliant, or any help with could would also be a major thanks. I tried getting help on the apple developer forums, but no luck there.

NSURL *tweets = [NSURL URLWithString:#"http://twitter.com/statuses/user_timeline/AlexTrott_.json"];
//NSData *jsonData = [tweets dataUsingEncoding:NSUTF8StringEncoding];
//NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSData *jsonData=[NSData dataWithContentsOfURL:tweets];
NSError *e = nil;
id yourJsonData=[NSJSONSerialization JSONObjectWithData:jsonData options:
NSJSONReadingMutableContainers error:&error];
NSLog("%#",yourJsonData );//you must get a json object here
//let's assume you need to get the key kalled user_name from your JSON Response
NSDictionary *theJson=[yourJsonData objectForKey:#"user_name"];
for(NSMutableArray *usernames in theJson){
// do something with usernames from your object
}

My application also receives his last tweet. You should consider the limits to the server with these requests (350 per hour). If you exceed this limit, there is no nsarray in nsdata it is nsdictionary, which describes the error and the request, which will undoubtedly be taken into account. I did it this way:
NSError* error = nil;
id responseBody = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
if (error) {
[[NSAlert alertWithError:error] runModal];
}
if ([responseBody respondsToSelector:#selector(objectAtIndex:)]) {
else {
if ([responseBody count]) {
NSString* currentStatus = [[responseBody objectAtIndex:0] objectForKey:#"text"]; //now you can do smth with your status))
}
else {
NSLog(#"You have not tweetted yet!");
}
}
}
else if([responseBody respondsToSelector:#selector(objectForKey:)]) {
NSString* error = [responseBody objectForKey:#"error"];
NSLog(#"CURRENT STATUS ERROR => %#", error);
}

Related

Trying to parse JSON data from Flickr. Cocoa error 3840

I’ve never used an API in conjunction with web services before and I’m having trouble parsing the JSON data I’m receiving from Flickr’s API. The only thing I do know (from all the things I have read) is that it is easy and very simple. About as far as I can get is returning a string in the console. Using a dictionary returns null and or an error. What am I missing? I want to be able to pull out the id and owner so that I can get the photo url.
This returns data on my photo:
NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#”%#”, json); //this returns data on my photo
This returns null(resultDict) and error 3840:
NSString *requestString = #”https://api.flickr.com/services/rest?&method=......etc;
NSURL *url = [NSURL URLWithString:requestString];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary *resultdict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#”%#”, resultDict); //returns null
If (error != nil) { NSLog(#”%#”, [error localizedDescription]); }
else { self.myDict = [[resultDict objectforKey:#”photos”] objectAtIndex:0];
NSLog(#”%#”, self.myDict); }
}];
[task resume];
To check if I have an array of dictionaries I did the following and it returned 0:
NSMutableArray *resultArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainer error:&error]; error:&error];
NSLog(#"%lu", (unsigned long)resultArray.count);
Are you sure that
[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
returns a Dictionary and not an Array of Dictionnaries?
EDIT :
Can you try to use this to request the API please?
I checked in my projects, my reponses seems to have the same syntax as yours.
Only the code I use is different.
(If you could give us the full URL you've to call, it would be easier for us ^^')
NSString *str=#"YOUR URL";
NSURL *url=[NSURL URLWithString:str];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error: &error];
NSMutableDictionary* resultList = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
I copied it without the errors. I let you manage that ^^
NSMutableDictionary ***resultdict** = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#”%#”, **resultDict**); //returns null
resultdict and resultDict are not the same variables. I bet you have an instance variable or a global variable somewhere named resultDict. Instance variables should start with an underscore, among other reasons because it avoids problems like this.
For question maker this answer won't be actual but maybe for them who will face with such problem.
I had the same problem when tried to get data from flickr.photos.getRecent method. I forgot to add into URL parametrs value nojsoncallback=1.
Without it you get response in JSONP.

Custom Parameters on ChatRoom messages

I am looking to display usernames alongside messages in a chatroom using quickblox. I was hoping to simply embed the sender name in the custom parameters of the message but the params never make it through to my chatroomDidRecieveMessage.
I copied the code from the example with no luck.
[message setCustomParameters:#{#"playSound": #YES}];
Also, can't seem to find a pattern in the senderID/recipientID that can go along with the message. So questions is, what is the best option for getting the sender data when a message is received?
Working on iOS...
Better way is to incapsulate all sender's info into JSON, for example, let's send user's location in message:
#define kLatitude #"latitude"
#define kLongitude #"longitude"
#define kMessage #"message"
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"12.23423424" forKey:kLatitude];
[dict setObject:#"-2.13123333" forKey:kLongitude];
[dict setValue:#"Hello, this is my location" forKey:kMessage];
// to JSON:
NSError *error = nil;
NSData* nsdata = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
// send message
NSString* jsonString =[[NSString alloc] initWithData:nsdata encoding:NSUTF8StringEncoding];
[[QBChat instance] sendMessage:jsonString toRoom:self.currentRoom];
And receive message:
-(void)chatRoomDidReceiveMessage:(QBChatMessage *)message fromRoom:(NSString *)roomName{
// JSON parsing
NSData *data = [message.text dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSString *message = [jsonDict objectForKey:kMessage];
NSString *latitude = [jsonDict objectForKey:kLatitude];
NSString *longitude = [jsonDict objectForKey:kLongitude];
}

App crashing because NSArray objectforkey: Objective C

I am trying to parse some Json with Objective C.
My problem is that I am getting the correct json back but when I try parse some of the json my app crashes.
// i will use a code from connect to DB tutorial
NSString *strURL = [NSString stringWithFormat:#"http://www.ddproam.co.za/Central/Asset/AssetsWithSerial?Serial=S00000001"];
// to execute php code
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
// to receive the returend value
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"Login response:%#",strResult);
NSError *error;
//parse out the json data
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:dataURL //1
options:kNilOptions
error:&error];
NSArray* defineJsonData = [json objectForKey:#"AssetDesc"]; //2
NSLog(#"value: %#", defineJsonData); //3
Here is my json:
[{"AssetID":1,"AssetName":"Asset 1","AssetDesc":"This is a manually inserted Asset","AssetTypeID":1,"AssetTypeDesc":"This is a manually inserted Asset Type"}]
I am trying to get the AssestName out of the string. I must be doing something wrong.
The whole thing is an array containing a dictionary, not a dictionary containing an array...
This is a very dirty way to get the value you want - you want to write something more safe than this. Try checking the type of class returned before you try to use it...
NSArray* json = [NSJSONSerialization JSONObjectWithData:dataURL //1
options:kNilOptions
error:&error];
NSDictionary* defineJsonData = [json lastObject]; //2
NSLog(#"value: %#", [defineJsonData objectForKey:#"AssetDesc"]); //3

The Operation couldn't be completed. (Cocoa error: 3840.)

I am trying to parse JSON for an ios 6 app, but can't seem to get it to work. I have scoured tons of forums but haven't found a solution that works, that I understand enough to implement, or that applies.
I apologize if there is one that I missed.
First I have a test WebService that as far as I can tell returns valid JSON
http://thetrouthunter.com/SVLocationsAPI.php
Second, here is my Objective-C code:
+ (NSDictionary *)connectToService:(NSString *)query
{
NSError *error = nil;
query = [NSString stringWithFormat:#"%#&format=json&nojsoncallback=1", query];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *jsonData = [[NSString stringWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:nil] dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;
NSLog(#"locations: %#", results);
if (error)
NSLog(#"[%# %#] JSON error: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
return results;
}
+ (NSArray *)userLocation {
NSString *request = [NSString stringWithFormat:#"http://thetrouthunter.com/SVLocationsAPI.php"];
return [[self connectToService:request] valueForKeyPath:#"locations.location"];
}
The ls NSLog function is printing out the error: "The operation couldn't be completed. (Cocoa error: 3840.)"
I can't figure out why this is the case. I have tried all sorts of things.
You are adding %#&format=json&nojsoncallback=1 to the URL in connectToService:, and that new URL results in a webpage, not the JSON you expect (i.e. http://thetrouthunter.com/SVLocationsAPI.php&format=json&nojsoncallback=1).
It might be useful to log the actual result from the HTTP request so that you can debug this until you get JSON (i.e. prior to calling the serialization functions).

Decode JSON to NSArray or NSDictionary

I hope to decode the JSON data below:
{
"content":
[
{
"1":"a",
"2":"b",
"3":"c",
"4":"d",
"mark":"yes"
}
]
}
Not sure if put it in NSArray or NSDictionary
Welcome any comment
which iOS version are you using? in iOS 5 you have the NSJSONSerialization class to parse JSON data, if you need to target older iOSs or MAC OSX you should use third parties lib such as SBJSON. The string posted will be a NSDictionary with an array with one dictionary. The array will be accessible using the key #"content"
In code:
NSString * jsonString = #"blblblblblb";
NSStringEncoding encoding;
NSData * jsonData = [jsonString dataUsingEncoding:encoding];
NSError * error=nil;
NSDictionary * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
In SWIFT 2.0:
let jsonString = "blblblblblb"
let encoding = NSUTF8StringEncoding
let jsonData = jsonString.dataUsingEncoding(encoding)
guard let jData = jsonData else {return}
do {
let parsedData = try NSJSONSerialization.JSONObjectWithData(jData, options: [])
} catch let error {
print("json error: \(error)")
}
[UPDATE]
The NSJSONSerialization class is also available for 10.7 my comment wasn't correct.
That particular string will decode into an NSDictionary because the outermost thing is a JSON object which maps onto a NSDictionary for every JSON implementation I have ever seen. If you want to process an arbitrary string, you'll need to test what you get back
NSError *jsonError;
id parsedThing = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (parsedThing == nil)
{
// error
}
else if ([parsedThing isKindOfClass: [NSArray class]])
{
// handle array, parsedThing can be cast as an NSArray safely
}
else
{
// handle dictionary, parsedThing can be cast as an NSDictionary
// NB only dictionaries and arrays allowed as long as NSJSONReadingAllowFragments
// not specified in the options
}
stringWithContentsOfFile:encoding: is deprecated in iOS<6
for iOS 6+
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"contents" ofType:#"json"];
NSError * error=nil;
NSString *jsonString = [NSString stringWithContentsOfFile:filePath encoding:nil error:&error];
NSData * jsonData = [jsonString dataUsingEncoding:nil];
NSArray * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
contents.json file is in your bundle.
You can do the following:
NSData *data = ...; //JSON data
NSError *jsonError = nil;
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
You will get back an NSDictionary containing an NSArray containing a single NSDictionary containing five NSString objects.
I used google speech recognition API and I was getting a json response which was not directly parsable on iOS. Results samples were like :
First I tried saying Hello 1 2 3 which was recognised without issues. Json response was :
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello 123","confidence":0.59780568},{"transcript":"hello 1 2 3"}],"final":true}],"result_index":0}
Or when talked for too long, I got a 404 HTML like below :
<html><title>Error 400 (Bad Request)!!1</title></html>
And when I spoke gibberish , I got :
{"result":[]}
So to parse all such response, I used the below code :
NSString *msg = #"Could not synthesize !";
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString: %#",responseString);
if([responseString containsString:#"transcript"]&&responseString.length>25)
{
responseString = [responseString stringByReplacingOccurrencesOfString:#"{\"result\":[]}" withString:#""];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
if(dictionary!=nil)
if(dictionary.allValues.count>0)
{
NSArray *array =[dictionary valueForKeyPath:#"result.alternative.transcript"];
if(array)
{
NSArray *array2 = [array objectAtIndex:0];
if(array2)
{
NSLog(#"%#",[array2 objectAtIndex:0] );
msg = [array2 objectAtIndex:0];
};
}
}
}
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Google Response" message:msg delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Hope this helps someone.