I'm newbie in iOS. And I'm having a problem accessing my JSON file that I retrieve in my web app server.
JSON:
{
"content": [
{
"info": [
{
"type": "TEL",
"label": "Call Phone",
"id": "32d7da39-39cc-4319-ab76-e67db9385722"
}
],
"name": "myname",
"title": "myname_title",
"image": "",
}
],
"timestamp": 1370491676,
"error": "SUCCESS"
}
I convert NSData to JSON :
NSMutableDictionary *mydatas =[NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
When I'm using this code to retrieve the name:
NSString *name = [[mydatas objectForKey:#"content"] objectForKey:#"name"];
It terminate the program.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x71e3240'
Include SBJSon Framework from here
NSString *responseString = [[NSString alloc]initWithData: urlData encoding:NSUTF8StringEncoding];
//NSLog(#"%#",responseString);
NSDictionary * mydatas = [responseString JSONValue];
NSString *name = [[mydatas objectForKey:#"content"]objectForKey:#"name"];
content is an NSArray, not an NSDictionary. You need to use NSArray calls to retrieve the item in the array:
// Be sure to check that the array has at least one item or you'll throw an exception
NSArray *contentArray = [mydatas objectForKey:#"content"];
if ( contentArray.count > 0 ) {
NSString *image = [contentArray[0] objectForKey:#"name"];
}
Why you are not using the SBJSON framework . https://github.com/stig/json-framework/.
Then refer following SO question :How to parse JSON into Objective C - SBJSON . This will be easy for you to parse this data.
NSArray *contentArray = [mydatas objectForKey:#"content"];
[contentArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"name of content at index %i is == %#",idx,[obj valueForKey:#"name"]);
}];
By looking at your JSON I can say,
Your mydatas dictionary contains 3 keys which are content, timestamp, error
The object for key content is an array. If you want to retrieve the object for key name you need to do the following
if([[mydatas objectForKey:#"content"] count]>0)
{
NSString *name = [[[mydatas objectForKey:#"content"] objectAtIndex:0]objectForKey:#"name"];
}
This will work.
try like this,
NSString *name = [[[mydatas objectForKey:#"content"] objectAtIndex:0]objectForKey:#"name"];
Try This One
NSMutableDictionary *mydatas =[NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
Save it to Array
NSArray *array = [mydatas objectForKey:#"content"];
for (int i=0; i<[array count]; i++) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"info"] forKey:#"info"];
[someArray addObject:dic];
[typeArray addObject:[[dic valueForKey:#"info"] valueForKey:#"type"] valueForKey:#"name"]];
NSString * NameStr = [typeArray objectAtIndex:i];
NSLog(#"String For Name : %#",NameStr);
[dic release];
}
Hope its Work!!!!!!!!!!!
Related
I want to save a Json Object in a field (text) sqlite and then read it again with a select and retransform to NSDictionary or NSMutableArray to parse the key/values
This is how i save actually in the sqlite DB
As you see, is a song object from the iTunes api. I want to read that object and parse it.
This is how i make the select query and save it in a NSDictionary while i filling and NSMutableArary
globals.arrayMyPlaylists = [[NSMutableArray alloc] init];
// Form the query.
NSString *query = #"select * from myplaylists";
// Get the results.
NSArray *listas = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
for (int i = 0; i < listas.count; i++) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSLog(#"lista %d %# %#", i, listas[i][0], listas[i][1]);
[dictionary setObject:listas[i][0] forKey:#"id"];
[dictionary setObject:listas[i][1] forKey:#"nombre"];
NSString *query2 = [NSString stringWithFormat:#"select cancion from canciones where idplaylist = %#", listas[i][0]];
NSArray *canciones = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query2]];
[dictionary setObject:canciones forKey:#"canciones"];
[globals.arrayMyPlaylists addObject:dictionary];
dictionary = nil;
}
When i try to read it in the cellForRowAtIndexPath method
NSArray *canciones = [[NSArray alloc] initWithArray:[[globals.arrayMyPlaylists objectAtIndex:indexPath.row] valueForKey:#"canciones"]];
and try to get the value for the key artworkUrl100
[cell.tapa1 sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#", [[canciones objectAtIndex:i] valueForKey:#"artworkUrl100"]]] placeholderImage:nil];
i get the error
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x7ff575810600> valueForUndefinedKey:]: this class is not key value coding-compliant for the key artworkUrl100.'
i understand i'm messing up in some way with dictionarys/nsmutablearrays. I need some help. Thanks!
EDIT: this is how i save the data in the DB
NSString *query = [NSString stringWithFormat:#"insert into canciones (idplaylist, cancion) values ('%#', '%#')", [[globals.arrayMyPlaylists objectAtIndex:indexPath.row] valueForKey:#"id"], self.elementoSeleccionado];
[self.dbManager executeQuery:query];
self.elementoSeleccionado is the NSMutableArray with the "cancion" object and it's saved like it's shows the first image.
EDIT 2: this is what i get trying schmidt9's answer
EDIT 3: OK, i have the json string escaped. How i have to parse now?
You should parse your output first with NSJSONSerialization:
NSString *query2 = [NSString stringWithFormat:#"select cancion from canciones where idplaylist = %#", listas[i][0]];
NSArray *canciones = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query2]];
// I suppose your array canciones should contain only one song object ...
NSError *error = nil;
id object = [NSJSONSerialization JSONObjectWithData:canciones[0] options:0 error:&error];
if(error) {
// handle error ...
}
if([object isKindOfClass:[NSDictionary class]])
{
NSDictionary *result = object;
[dictionary setObject:result forKey:#"canciones"];
}
Edit
Saving to database
2 options:
- if you get a prepared json string, save it directly to DB, but before you should escape quotes. See eg. here
- if you have NSDictionary:
- (NSString*)JSONStringWithDictionary:(NSDictionary*)dictionary prettyPrinted:(BOOL)prettyPrinted
{
NSJSONWritingOptions options = (prettyPrinted) ? NSJSONWritingPrettyPrinted : 0;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:options error:nil];
return [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
}
After that you should escape the string too.
I'm trying to parse a JSON feed from my wordpress blog. I've got a custom field I need to use but can't get it to work with SBJson. Here's how my feed looks like (I've stripped the other useless stuff):
{
"status":"ok",
"count":27,
"count_total":2552,
"pages":95,
"posts":[
{
"id":8978,
"type":"post",
"custom_fields":{
"btnNameScrollBlog":[
"<null>"
]
"author-name":[
"John Doe"
]
},
}
I'm trying to get the author's name.
Here's the code I used for getting the feed on iOS:
-(void)downloadRecentPostJson{
[recentPost removeAllObjects];
[previous_total_per_page removeAllObjects];
NSURL *urls = [NSURL URLWithString:[NSString stringWithFormat:#"%#/?json=%#",url,methodJson]];
NSData *sa = [NSData dataWithContentsOfURL:urls];
NSString *jsonString = [[NSString alloc] initWithData:sa encoding:NSUTF8StringEncoding];
NSDictionary *result = [jsonString JSONValue];
NSArray* posts = [result objectForKey:#"posts"];
total_page = [[result objectForKey:#"pages"] intValue];
total_post_per_page = [[result objectForKey:#"count"] intValue];
[previous_total_per_page addObject:[result objectForKey:#"count"]];
current_page = 1;
for (NSDictionary *post in posts) {
id custom = [post objectForKey:#"custom_fields"];
id thumbnail = [post objectForKey:#"thumbnail"];
NSString *featuredImage = #"";
if (thumbnail != [NSNull null])
{
featuredImage = (NSString *)thumbnail;
}
else
{
featuredImage = #"0";
}
[recentPost addObject:[NSArray arrayWithObjects:[post objectForKey:#"id"],[post objectForKey:#"title_plain"],[post objectForKey:#"excerpt"],featuredImage,[post objectForKey:#"content"],[post objectForKey:#"date"],[post objectForKey:#"comments"],[post objectForKey:#"comment_status"],[post objectForKey:#"scrollBlogTemplate"],[post objectForKey:#"url"],[post objectForKey:#"specialBtn"],[post objectForKey:#"btnNameScrollBlog"],[post objectForKey:#"latScrollBlog"],[post objectForKey:#"longScrollBlog"],[post objectForKey:#"openWebUrlScrollBlog"],[post objectForKey:#"gallery"], [custom objectForKey:#"author-name"], nil]];
}
I tried setting the custom_fields object as an id: id custom = [post objectForKey:#"custom_fields"];
And then using it to get to the author's name: [custom objectForKey:#"author-name"]
But I get an NSInvalidArgumentException', reason: '-[__NSArrayM rangeOfString:]: unrecognized selector error.
Any suggestions??
What if I try and get the category title from the post?
"categories": [
{
"id": 360,
"slug": "deals",
"title": "Deals",
"description": "",
"parent": 0,
"post_count": 28
}
],
Do I put the categories in an array like this? How do I get the title from that? I tried this and getting the object at index 3, but got an error.
NSArray *cat = [post objectForKey:#"categories"];
'-[__NSArrayM rangeOfString:]: unrecognized selector error. means that you are treating an array as a string. Your code is nearly correct, you just need to get the first item from the array (preferably with a check that the array isn't empty) because
"author-name":[
"John Doe"
]
is an array containing one string. So:
NSArray *names = [custom objectForKey:#"author-name"];
NSString *name = [names firstObject];
NSArray *categories = [custom objectForKey:#"categories"];
NSDictionary *category = [categories firstObject];
NSString *title = [category objectForKey:#"title"];
I get this JSON from a web service:
{
"Respons": [{
"status": "101",
"uid": "0"
}]
}
I have tried to access the data with the following:
NSError* error;
//Response is a NSArray declared in header file.
self.response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSString *test = [[self.response objectAtIndex:0] objectForKey:#"status"]; //[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
NSString *test = [[self.response objectForKey:#"status"] objectAtIndex:0]; //(null)
But none of them work, if i NSLog the NSArray holding the serialized data, this i what i get:
{
Respons = (
{
status = 105;
uid = 0;
}
);
}
How do i access the data?
Your JSON represents a dictionary, for whom the value associated with the Respons key is an array. And that array has a single object, itself a dictionary. And that dictionary has two keys, status and uid.
So, for example, if you wanted to extract the status, I believe you need:
NSArray *array = [self.response objectForKey:#"Respons"];
NSDictionary *dictionary = [array objectAtIndex:0];
NSString *status = [dictionary objectForKey:#"status"];
Or, in latest versions of the compiler:
NSArray *array = self.response[#"Respons"];
NSDictionary *dictionary = array[0];
NSString *status = dictionary[#"status"];
Or, more concisely:
NSString *status = self.response[#"Respons"][0][#"status"];
Your top level object isn't an array, it's a dictionary. You can easily bypass this and add the contents of that key to your array.
self.response = [[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error] objectForKey:#"Respons"];
my json :
{
"name": "notification",
"args": [
"{\"data\": [{\"foreignId\":\"BF7E9276D8607DA5916F796F9F1B9743_2\",\"id\":\"\",\"img\":{\"small\":\"http://jiepang.com/static/img/icon-special-newbie.gif\"},\"poiId\":\"4fe133bb581f7129d6c3f2b3\",\"poiName\":\"Incubation Club Cafe - ICC\",\"source\":\"jiepang\",\"what\":\"aaaa。\",\"when\":\"\"}],\"size\":3,\"toWho\":[\"4ffa80c8e4b0f73fa2b758c9\"],\"type\":5,\"when\":\"2012-07-09T17:23:24Z\"}"
]
}
my code :
NSDictionary* data=(NSDictionary *)[packet.data JSONValue];
NSString* str=[NSString stringWithFormat:#"%#",[data objectForKey:#"name"]];
txtview.text = [txtview.text stringByAppendingString:str];
NSData *jsonData = [packet.data dataUsingEncoding:NSUTF8StringEncoding];
__autoreleasing NSError* error = nil;
NSDictionary *resultdata = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
// NSDictionary* arr=[data valueForKeyPath:#"args.data"];
NSMutableDictionary *peopleListFromJson = [[NSMutableDictionary alloc] init];
peopleListFromJson = [resultdata valueForKeyPath:#"args.data"];
// NSArray *peopleListFromJson = [[result objectForKey:#"data"]objectForKey:#"list"];
if ( ![peopleListFromJson isKindOfClass:[NSArray class]] && peopleListFromJson!=nil) {
peopleListFromJson =[NSArray arrayWithObject:peopleListFromJson];
}
for (NSDictionary *peopleFromJson in peopleListFromJson)
{
if([peopleFromJson objectForKey:#"foreignId"]!=[NSNull null])
{
NSString* str=[NSString stringWithFormat:#"%#",[peopleFromJson objectForKey:#"foreignId"]];
txtview.text = [txtview.text stringByAppendingString:str];
}
}
but it give me:
[<__NSCFString 0x2749a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key data.'
*** First throw call stack:
I am using ios5, without ARC.
This means that your key path is not correct. You can't use key path when dealing with arrays because it is unknown which item of the array you need.
You need to access the NSArray stored under the key args, then pull out the first item (which is a string), then convert that string into a NSDictionary, then pull out the key for data.
A quicker way is to make sure your JSON is formatted better:
{
"name": "notification",
"args": {"data": [{"foreignId": "BF7E9276D8607DA5916F796F9F1B9743_2", "id": "", "img":{"small": "http://jiepang.com/static/img/icon-special-newbie.gif"}, "poiId":"4fe133bb581f7129d6c3f2b3", "poiName":"Incubation Club Cafe - ICC","source":"jiepang","what":"aaaa。","when":""}],"size":3,"toWho":["4ffa80c8e4b0f73fa2b758c9"],"type":5,"when":"2012-07-09T17:23:24Z"}]
}
I'm trying to get values from nsdata class and doesn't work.
here is my JSON data.
{
"count": 3,
"item": [{
"id": "1",
"latitude": "37.556811",
"longitude": "126.922015",
"imgUrl": "http://175.211.62.15/sample_res/1.jpg",
"found": false
}, {
"id": "3",
"latitude": "37.556203",
"longitude": "126.922629",
"imgUrl": "http://175.211.62.15/sample_res/3.jpg",
"found": false
}, {
"id": "2",
"latitude": "37.556985",
"longitude": "126.92286",
"imgUrl": "http://175.211.62.15/sample_res/2.jpg",
"found": false
}]
}
and here is my code
-(NSDictionary *)getDataFromItemList
{
NSData *dataBody = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];
NSDictionary *iTem = [[NSDictionary alloc]init];
iTem = [NSJSONSerialization JSONObjectWithData:dataBody options:NSJSONReadingMutableContainers error:nil];
NSLog(#"id = %#",[iTem objectForKey:#"id"]);
//for Test
output = [[NSString alloc] initWithBytes:buffer length:rangeHeader.length encoding:NSUTF8StringEncoding];
NSLog(#"%#",output);
return iTem;
}
how can I access every value in the JSON? Please help me.
look like this ..
NSString *jsonString = #"your json";
NSData *JSONdata = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
if (JSONdata != nil) {
//this you need to know json root is NSDictionary or NSArray , you smaple is NSDictionary
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:JSONdata options:0 error:&jsonError];
if (jsonError == nil) {
//every need check value is null or not , json null like ( "count": null )
if (dic == (NSDictionary *)[NSNull null]) {
return nil;
}
//every property you must know , what type is
if ([dic objectForKey:#"count"] != [NSNull null]) {
[self setCount:[[dic objectForKey:#"count"] integerValue]];
}
if ([dic objectForKey:#"item"] != [NSNull null]) {
NSArray *itemArray = [dic objectForKey:#"item"]; // check null if need
for (NSDictionary *itemDic in itemArray){
NSString *_id = [dic objectForKey:#"id"]; // check null if need
NSNumber *found = (NSNumber *)[dic objectForKey:#"found"];
//.....
//.... just Dictionary get key value
}
}
}
}
I did it by using the framework : http://stig.github.com/json-framework/
It is very powerfull and can do incredible stuff !
Here how I use it to extract an item name from an HTTP request :
(where result is the JSO string)
NSString *result = request.responseString;
jsonArray = (NSArray*)[result JSONValue]; /* Convert the response into an array */
NSDictionary *jsonDict = [jsonArray objectAtIndex:0];
/* grabs information and display them in the labels*/
name = [jsonDict objectForKey:#"wine_name"];
Hope this will be helpfull
Looking at your JSON, you are not querying the right object in the object hierarchy. The top object, which you extract correctly, is an NSDictionary. To get at the items array, and the single items, you have to do this.
NSArray *items = [iTem objectForKey:#"item"];
NSArray *filteredArray = [items filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"id = %d", 2];
if (filteredArray.count) NSDictionary *item2 = [filteredArray objectAtIndex:0];
Try JSONKit for this. Is is extremely simple to use.
Note sure if this is still relevant, but in iOS 5, apple added reasonable support for JSON. Check out this blog for a small Tutorial
There is no need to import any JSON framework. (+1 if this answer is relevant)