This question already has answers here:
Cocoa-Touch - How parse local Json file
(5 answers)
Closed 7 years ago.
When i parse one JSON i got following result inside my NSArray
(
{
category = Allergies;
group = Allergies;
name = "Food Allergies";
option = "";
subGroup = "";
type = VARCHAR;
},
{
category = Allergies;
group = Allergies;
name = "Drug Allergies";
option = "";
subGroup = "";
type = VARCHAR;
},
{
category = Allergies;
group = "";
name = "Blood Group";
option = "[{\"id\":1,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"A+\"},{\"id\":2,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"A-\"},{\"id\":3,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"B+\"},{\"id\":4,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"B-\"},{\"id\":5,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"O+\"},{\"id\":6,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"O-\"},{\"id\":7,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"AB+\"},{\"id\":8,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"AB-\"}]";
subGroup = "";
type = SINGLESELECT;
}
)
Now when i tried to take value for key "option"
[array valueForKey:#"option"]objectAtIndex:indexPath.row];
i got following result
[{"id":1,"isDefault":false,"additionalOption":false,"optionName":"A+"},{"id":2,"isDefault":false,"additionalOption":false,"optionName":"A-"},{"id":3,"isDefault":false,"additionalOption":false,"optionName":"B+"},{"id":4,"isDefault":false,"additionalOption":false,"optionName":"B-"},{"id":5,"isDefault":false,"additionalOption":false,"optionName":"O+"},{"id":6,"isDefault":false,"additionalOption":false,"optionName":"O-"},{"id":7,"isDefault":false,"additionalOption":false,"optionName":"AB+"},{"id":8,"isDefault":false,"additionalOption":false,"optionName":"AB-"}]
but when tried to access "optionName" like following format
[optionArray valueForKey:#"optionName"];
then i got this error
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFConstantString 0x10d8638a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key optionName.'
Please help me to fix this..
Assuming you are using ios 5 or higher, JSON serialization is built in:
NSArray *json = [NSJSONSerialization
JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
options:kNilOptions
error:&error];
Prior to ios5, you can use SBJSON to achieve the same:
NSArray *jsonObjects = [jsonParser objectWithString:string error:&error];
Use this method
- (NSArray *)convertStringToDictionary:(NSString *)str{
NSError *jsonError;
NSData *objectData = [str dataUsingEncoding:NSUTF8StringEncoding];
NSArray *json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&jsonError];
return json;
}
And call like this
NSArray *arr = [self convertStringToDictionary:#"[{\"id\":1,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"A+\"},{\"id\":2,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"A-\"},{\"id\":3,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"B+\"},{\"id\":4,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"B-\"},{\"id\":5,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"O+\"},{\"id\":6,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"O-\"},{\"id\":7,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"AB+\"},{\"id\":8,\"isDefault\":false,\"additionalOption\":false,\"optionName\":\"AB-\"}]"];
NSLog(#"Option Name ----> %#",[[arr objectAtIndex:0] valueForKey:#"optionName"]);
OUTPUT
Option Name ----> A+
Try using below got to convert to array
NSArray *tmpDayArray=[[NSArray alloc]init];
NSError *error;
NSData *dictData = [NSJSONSerialization dataWithJSONObject:tmpDayArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *open_days = [[NSString alloc] initWithData:dictData encoding:NSUTF8StringEncoding];
Try Below code for convert it to NSArray
NSArray * array =[NSJSONSerialization JSONObjectWithData:[[NSString stringWithFormat:#"%#",#"YOUR STRING"] dataUsingEncoding:NSUTF8StringEncoding]options: NSJSONReadingMutableContainers error:nil];
You have a complex "object graph." It looks like your outer object is an array, and inside that you have dictionaries.
If optionArray is an NSArray then it will give you exactly the error you are reporting if you try to treat it as a dictionary.
Your code:
[array valueForKey:#"option"]objectAtIndex:indexPath.row];
Is doing that (Although you are using KVC, where you should be using array and dictionary methods directly.)
Your code should look like this instead:
NSDictionary* aDict = array[indexPath.row];
NSString *optionString = aDict[#"option];
Without using any third party like SBJson
NSString *optionString = [[array valueForKey:#"option"]objectAtIndex:indexPath.row];
Actually you are getting optionString as json String so you have to parse it and then use like this
NSData *data = [optionString dataUsingEncoding:NSUTF8StringEncoding];
NSArray * optionArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#",[optionArray valueForKey:#"optionName"]);
I get this JSON object from my web service
0: {
Username: "John"
Password: "12345"
Position: "Admin"
Job: "Developer"
ResourceJobId: 1
}
When I try to assign a value, for example, to Username JSON string, I get a semantic error:
id obj = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
for (NSDictionary *dictionary in array) {
NSString *usernameString = #"";
//this line of code gives me an error: Expression is not assignable
[dictionary objectForKey:#"Username"] = usernameString ;
I know how get the JSON object with NSJSONSerialization class, but my target is how assign the value #"" to the JSON object.
So how can I assign the value #"" to the Username JSON string?
While you are trying to fetched dictionary from array. it is not mutable dictionary so you need to created NSMutableDictionary while fetching data from Array. following code will help you to change username.
for (NSMutableDictionary *dictionary in array)
{
NSMutableDictionary* dictTemp = [NSMutableDictionary dictionaryWithDictionary:dictionary];
[dictTemp setObject:usernameString forKey#"Username"];
[_arrayList replaceObjectAtIndex:index withObject:dictTemp];
}
Well your assignment operation is written wrong, it should be indeed like this:
If you need to get value from dictionary
usernameString = [dictionary objectForKey:#"Username"];
If you want to set a value to your dictionary, first of all your dictionary should be NSMutableDictionary
[dictionary setObject:usernameString forKey:#"Username"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
id obj = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
if(!error && [obj isKindOfClass:[NSArray class]]){
NSArray *array = (NSArray *)obj;
Booking *booking = nil;
for (NSMutableDictionary *dictionary in array) {
NSString *usernameString = #"";
//this line of code gives me an error: Expression is not assignable
[dictionary objectForKey:#"Username"] = usernameString;
Yes, is a compiler error
You need to have a mutabledictionary inorder to change the value. Try this
for (NSDictionary *dictionary in array) {
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary];
NSString *usernameString = #"";
[mutableDictionary setValue:#"" forKey:usernameString];
}
Even the answers are correct, I want to add that you do not have to do this your own. NSJSONSerialization already has a solution for that. Simply pass as options one of these:
NSJSONReadingMutableContainers = (1UL << 0),
NSJSONReadingMutableLeaves = (1UL << 1),
when reading the JSON.
So I have some json in a file like so
{
"address": {
"home": {
"street": "A Street"
}
}
}
I pull out the json string like so
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
I want to change a value on the fly, using a key path, so I need to make a deep mutable copy of the structure. So I am doing it like so
id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
data = [NSKeyedArchiver archivedDataWithRootObject:json];
json = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Using breakpoints I can see the json and it all looks fine. However, I get a crash on this line
[json setValue:#"Different Street" forKeyPath:#"address.home.street"];
The compiler suggested there isn't a key at this key path that conforms to key-value coding.
Annoyingly, this line works fine and returns the street string
id value = [json valueForKeyPath:#"address.home.street"];
Why can't I set a value like this?
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x1741bb580> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key pan.'
Use NSJSONReadingMutableContainers when reading your JSON. By default your containers are read in as immutable containers.
id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments|NSJSONReadingMutableContainers error:nil];
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"];
I created a web service which returns JSON or so I think. The data returned look like this:
{"invoice":{"id":44,"number":42,"amount":1139.99,"checkoutStarted":true,"checkoutCompleted":true}}
To me, that looks like valid JSON.
Using native JSON serializer in iOS5, I take the data and capture it as a NSDictionary.
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error];
NSLog(#"json count: %i, key: %#, value: %#", [json count], [json allKeys], [json allValues]);
The output of the log is:
json count: 1, key: (
invoice
), value: (
{
amount = "1139.99";
checkoutCompleted = 1;
checkoutStarted = 1;
id = 44;
number = 42;
}
)
So, it looks to me that the JSON data has a NSString key "invoice" and its value is NSArray ({amount = ..., check...})
So, I convert the values to NSArray:
NSArray *latestInvoice = [json objectForKey:#"invoice"];
But, when stepping through, it says that latestInvoice is not a CFArray. if I print out the values inside the array:
for (id data in latestInvoice) {
NSLog(#"data is %#", data);
}
The result is:
data is id
data is checkoutStarted
data is ..
I don't understand why it only return the "id" instead of "id = 44". If I set the JSON data to NSDictionary, I know the key is NSString but what is the value? Is it NSArray or something else?
This is the tutorial that I read:
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
Edit: From the answer, it seems like the "value" of the NSDictionary *json is another NSDictionary. I assume it was NSArray or NSString which is wrong. In other words, [K,V] for NSDictionary *json = [#"invoice", NSDictionary]
The problem is this:
NSArray *latestInvoice = [json objectForKey:#"invoice"];
In actual fact, it should be:
NSDictionary *latestInvoice = [json objectForKey:#"invoice"];
...because what you have is a dictionary, not an array.
Wow, native JSON parser, didn't even notice it was introduced.
NSArray *latestInvoice = [json objectForKey:#"invoice"];
This is actually a NSDictionary, not a NSArray. Arrays wont have keys. You seem capable from here.
Here I think You have to take to nsdictionary like this
NSData* data = [NSData dataWithContentsOfURL: jsonURL];
NSDictionary *office = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSDictionary *invoice = [office objectForKey:#"invoice"];