Key value coding failure - ios

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];

Related

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (NSConcreteValue)

This is my dictionary:
{ #"RoutePolyline":<__NSArrayM 0x283983750>(<c59272f7 39263940 55a4c2d8 42f65240>),
#"RideID":6565
};
I am sending this dictionary as an argument in my API call.
and my app crashes at this line of code:
NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
This is the error it throws:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'Invalid type in JSON write
(NSConcreteValue)'
I know the RoutePolyline parameter is holding a NSValue (it is supposed to be an array of coordinates) and not any object type, but I have tried converting alot, but nothing have worked so far. For example
[NSValue valueWithMKCoordinate:*routeCoordinates]
Loop through your NSValue array and extract CLLocationCoordinate2D's value.
for (NSValue *value in coordinates) {
CLLocationCoordinate2D coordinate;
[value getValue:&coordinate];
NSDictionary *coDic = #{#"latitude" : [NSNumber numberWithDouble: coordinate.latitude],
#"longitude": [NSNumber numberWithDouble: coordinate.longitude]};
[array addObject:coDic];
}
Also Check if dictionary is valid JSON before serialize
if ([NSJSONSerialization isValidJSONObject:dic]) {
NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
}
Get coordinates (lat longs) values first and store to an array, you can serialize then, it should not crash. Try by using NSString values in api:
NSArray *arr = #[ #{#“lat”: [NSString stringWithFormat:#"%ld",routeCoordinates.latitude],
#“long”:[NSString stringWithFormat:#"%ld",routeCoordinates.longitude]
}];

NSCFString 0x2749a0 valueForUndefinedKey this class is not key value coding-compliant for the key push_type

My Json
{
aps = {
alert = {
body = "This is a testing message !!!";
title = Notification;
};
};
data = "{\"push_type\":6,\"badge\":1,\"alert\":\"This is a testing message !!!\",\"sound\":\"default\",\"content-available\":\"1\",\"is_login\":2}";
"gcm.message_id" = "0:1494478903994917%6c350cc06c350cc0"; }
I want to get push_type like here it is 6.
My code is:
NSDictionary *data=[[userInfo valueForKey:#"data"] valueForKey:#"push_type"]];
After run this line an error occur push_type is not key value coding complaints...
Could you please help me where i am wrong,or how can i achieve this,please refer me an example,link thanks!
Try with it.
NSString *jsonString=[[userInfo valueForKey:#"data"];
NSData *JsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:JsonData options:0 error:nil];
Now from "data" dictionary you can get any value from its key, like "push_type" etc...

NSTaggedPointerString objectForKey in objective-c

when I try to fetch the result from the JSON result. It throws the following exception.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString objectForKey:]: unrecognized selector sent to instance 0xa006449656c6f526'
My code.
NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutableData encoding:NSUTF8StringEncoding];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dataDict in jsonObjects) {
NSString *firstname = [dataDict objectForKey:#"FirstName"];
}
The above code throws an NSException.
My JSON response looks like this.
{
"IsExternal": 0,
"LoginId": 4,
"EmployeeId": 223,
"FirstName": "GharValueCA",
"RoleId": 4,
"LastName": null,
"Mobile": null,
"AgencyId": 100,
"BranchId": 74
}
Any help will be appreciated.
According to the definition of JSON, each JSON contains one object (which can be a collection type that contains other objects). In your case, your text starts with "{", so that's a dictionary. A single dictionary.
So NSJSONSerialization, when it reads that file, gives you back an NSDictionary containing values under keys like IsExternal, FirstName etc.
However, your code uses for( ... in ... ) on that dictionary (which, according to NSDictionary documentation, will iterate over the keys in the dictionary, which are strings), but then you treat those strings as if they were dictionaries again.
So instead of looping over the dictionary, you should just use the dictionary in jsonObjects directly, by calling something like -objectForKey: on it.
There is a misunderstanding:
jsonObjects is already the dictionary, assign the deserialized object immediately to dataDict.
NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:mutableData
options:0
error:nil];
// mutableContainers in not needed to read the JSON
The enumerated objects are strings, numbers or <null>. You called objectForKey: on a string which caused the error.
Get the name directly (no loop)
NSString *firstname = dataDict[#"FirstName"];
or you can enumerate the dictionary
for (NSString *key in dataDict) {
NSLog(#"key:%# - value:%#", key, dict[key]);
}
You should call
[jsonObjects objectForKey:#"FirstName"];
to get the FirstName value.
Below lines of code returns you (probably) a NSDictionary, so this is the container that stores all of your json values.
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
Try this code:
if ([jsonObjects isKindOfClass:[NSDictionary class]]) {
NSString *firstname = [jsonObjects objectForKey:#"FirstName"];
}
as your 'jsonObjects' is of generic type 'id' so just check that whether it is of NSDictionary type and then in if-block you can directly access it by objectForKey:
try this code, hope it help,
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
mutableData options:NSJSONReadingMutableContainers error:nil];
if([jsonObjects respondsToSelector:#selector(objectForKey:)]){
NSString *firstname = [jsonObjects objectForKey:#"FirstName"];
}

'NSInvalidArgumentException', reason: '-[__NSCFString allKeys]: unrecognized selector sent to instance 0x7ae2f750'

responce stored in dictionary :
dict_Profile=[response objectForKey:#"unknown_object"];
after that am doing like this
lbl_HeadName.text=[NSString stringWithFormat:#"%#",[dict_Profile objectForKey:#"FirstName"]];
this data getting from server
getUserProfileResponse
{
"status_code" = 200;
"unknown_object" = "{
ID:90,FirstName:Dr.Alekhya,LastName:Kasoju,GivenName:Alekhya Kumar,DOB:1993-07-15T00:00:00,_DcotorAction:edit,
Languages:[44,45,46],
Designations[5102],PersonalEmailID:alekhya.k#inativetech.com,
PersonalContactNo:7675879511,Medical_Council_ID:MED003,
ProfilePhoto:Doctor_9015763545-Attractive-young-Indian-Female-Doctor-with-notepad-isolated-on-white--Stock-Photo.jpg,PracticeStartedOn:2013,LanguagesList:[{Key:44,Value:Telugu},{Key:45,Value:English},{Key:46,Value:Hindi},{Key:47,Value:Tamil},{Key:138,Value:Urdhu},{Key:139,Value:oriya},{Key:140,Value:Bengali},{Key:141,Value:kanada},{Key:142,Value:Marati},{Key:144,Value:Kashmiri},{Key:198,Value:card},{Key:4304,Value:malayalam},{Key:4310,Value:Sanksrit},{Key:4311,Value:German},{Key:4350,Value:Japanies},{Key:5275,Value:PGDMC},{Key:5518,Value:physicians}],DesignationsList:[{Key:5100,Value:Allergist or Immunologist},{Key:5101,Value:Anesthesiologist },{Key:5102,Value:Cardiologist},{Key:5103,Value:Dermatologist },{Key:5104,Value:Gastroenterologist},{Key:5105,Value:Hematologist/Oncologist },{Key:5106,Value:Internal Medicine Physician },{Key:5108,Value:Nephrologist\U00c2\U00a0 },{Key:5109,Value:Neurologist\U00c2\U00a0 },{Key:5110,Value:Neurosurgeon },{Key:5111,Value:Obstetrician },{Key:5112,Value:Gynecologist},{Key:5113,Value:Nurse-Midwifery },{Key:5114,Value:Occupational Medicine Physician},{Key:5115,Value:Ophthalmologist },{Key:5116,Value:Oral and Maxillofacial Surgeon\U00c2\U00a0 },{Key:5117,Value:Orthopaedic Surgeon },{Key:5118,Value:Otolaryngologist\U00c2\U00a0(Head and Neck Surgeon)\U00c2\U00a0 },{Key:5119,Value:Pathologist\U00c2\U00a0 },{Key:5120,Value:Pediatrician },{Key:5121,Value:Plastic Surgeon\U00c2\U00a0 },{Key:5122,Value:Podiatrist\U00c2\U00a0 },{Key:5123,Value:Psychiatrist },{Key:5124,Value:Pulmonary Medicine Physician },{Key:5125,Value:Radiation Onconlogist\U00c2\U00a0 },{Key:5126,Value:Diagnostic Radiologist },{Key:5127,Value:Rheumatologist\U00c2\U00a0 },{Key:5128,Value:Urologist },{Key:5129,Value:Orthopedist},{Key:5216,Value:Ayurveda},{Key:5519,Value:physicians},{Key:5897,Value:Ayurved},{Key:5898,Value:Ayurvedic},{Key:7442,Value:Homeopathy Doctor},{Key:7921,Value:Homeopath},{Key:8770,Value:Gynecologist/Obstetrician},{Key:8771,Value:MBBS,DGO},{Key:8774,Value:Spine Surgeon},{Key:8775,Value:MS (Ortho), FNB - Spine Surgery},{Key:8779,Value:Gastroentrology Surgeon},{Key:8780,Value:General Surgeon},{Key:8781,Value:Dentist},{Key:8783,Value:ENT},{Key:8784,Value:Radiology},{Key:8785,Value:General Surgery},{Key:8786,Value:Homeopathic},{Key:8787,Value:Trichologist},{Key:8788,Value:Diabetologist},{Key:8791,Value:Laboratory Medicine},{Key:8801,Value:Hematologist}],YearsList:[{Key:0,Value:-- Select Year--},{Key:2016,Value:2016},{Key:2015,Value:2015},{Key:2014,Value:2014},{Key:2013,Value:2013},{Key:2012,Value:2012},{Key:2011,Value:2011},{Key:2010,Value:2010},{Key:2009,Value:2009},{Key:2008,Value:2008},{Key:2007,Value:2007},{Key:2006,Value:2006},{Key:2005,Value:2005},{Key:2004,Value:2004},{Key:2003,Value:2003},{Key:2002,Value:2002},{Key:2001,Value:2001},{Key:2000,Value:2000},{Key:1999,Value:1999},{Key:1998,Value:1998},{Key:1997,Value:1997},{Key:1996,Value:1996},{Key:1995,Value:1995},{Key:1994,Value:1994},{Key:1993,Value:1993},{Key:1992,Value:1992},{Key:1991,Value:1991},{Key:1990,Value:1990},{Key:1989,Value:1989},{Key:1988,Value:1988},{Key:1987,Value:1987},{Key:1986,Value:1986},{Key:1985,Value:1985},{Key:1984,Value:1984},{Key:1983,Value:1983},{Key:1982,Value:1982},{Key:1981,Value:1981},{Key:1980,Value:1980},{Key:1979,Value:1979},{Key:1978,Value:1978},{Key:1977,Value:1977},{Key:1976,Value:1976},{Key:1975,Value:1975},{Key:1974,Value:1974},{Key:1973,Value:1973},{Key:1972,Value:1972},{Key:1971,Value:1971},{Key:1970,Value:1970},{Key:1969,Value:1969},{Key:1968,Value:1968},{Key:1967,Value:1967},{Key:1966,Value:1966},{Key:1965,Value:1965},{Key:1964,Value:1964},{Key:1963,Value:1963},{Key:1962,Value:1962},{Key:1961,Value:1961},{Key:1960,Value:1960},{Key:1959,Value:1959},{Key:1958,Value:1958},{Key:1957,Value:1957},{Key:1956,Value:1956},{Key:1955,Value:1955},{Key:1954,Value:1954},{Key:1953,Value:1953},{Key:1952,Value:1952},{Key:1951,Value:1951},{Key:1950,Value:1950},{Key:1949,Value:1949},{Key:1948,Value:1948},{Key:1947,Value:1947},{Key:1946,Value:1946},{Key:1945,Value:1945},{Key:1944,Value:1944},{Key:1943,Value:1943},{Key:1942,Value:1942},{Key:1941,Value:1941},{Key:1940,Value:1940},{Key:1939,Value:1939},{Key:1938,Value:1938},{Key:1937,Value:1937},{Key:1936,Value:1936},{Key:1935,Value:1935},{Key:1934,Value:1934},{Key:1933,Value:1933},{Key:1932,Value:1932},{Key:1931,Value:1931},{Key:1930,Value:1930},{Key:1929,Value:1929},{Key:1928,Value:1928},{Key:1927,Value:1927},{Key:1926,Value:1926},{Key:1925,Value:1925},{Key:1924,Value:1924},{Key:1923,Value:1923},{Key:1922,Value:1922},{Key:1921,Value:1921},{Key:1920,Value:1920},{Key:1919,Value:1919},{Key:1918,Value:1918},{Key:1917,Value:1917},{Key:1916,Value:1916}]}";
}
as you see, the unknown_object in your response is just a string, not a json object,so it will be translated to a NSString * object, but not a dictionary.
if you want unknown_object to be a dictionary, you can adjust your response like following:
getUserProfileResponse
{
"status_code" = 200;
"unknown_object" = {
"ID" : 90,
"FirstName" : "Dr.Alekhya",
......
}
}
or
make your unknown_object to a valid json string,then transfer it back to a dictionary, like this:
NSData *data = [#"{\"id\" : 1}" dataUsingEncoding:NSUTF8StringEncoding];
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONWritingPrettyPrinted
error:nil];
allKeys is a property of Dictionary to which provides array of Keys in that dictionary.
Looks like you are calling allKeys on NSString object, Because of that you are getting this error.
Convert your String object to valid Dictionary. Try below
NSString *jsonString = "your string"
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
Hope it helps.
The response that you are getting is not actually a dictionary, so you need to convert NSSting to NSDictionary.
NSString *response = #"{ \"status_code\" : 200, \"unknown_object\" : { \"ID\" : \"90\", \"FirstName\" : \"Dr.Alekhya\"} }";
NSError *error;
NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict_Profile = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#"res = %#", dict_Profile);
//get data from dictionary
NSString *strName = [NSString stringWithFormat:#"%#",[[dict_Profile objectForKey:#"unknown_object"] valueForKey:#"FirstName"]];
NSLog(#"FirstName = %#", strName);
it may help you:
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:[response dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];

How to convert NSArray ( in string format) to real Array format? [duplicate]

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"]);

Resources