I'm writing an iOS application that gets data from a web request. The request returns the following:
{"hash":"0369a5d5e65335309b2b1502dc96b5aba691b9451c83b9","error":0}
I get the data from the NSData* responseData object as follows:
NSDictionary* JSONdata = [NSJSONSerialization JSONObjectWithData:_responseData options:0 error:&error];
NSInteger responseError = (NSInteger)[JSONdata objectForKey:#"error"];
However, responseError is coming back uninitialized (filled with garbage values). I tried changing NSInteger to NSString* but that yields the following error
'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x9d02220'
Any ideas?
You need to use an NSNumber. Primitive values will not work for as iOS parses the data in NSObjects: NSArray, NSDictionary, NSNumber, NSString, and NSNull.
Try this: NSNumber *responseError = [JSONdata objectForKey:#"error"];
Then to convert to an NSInteger you can do this:
NSInteger responseInt = [responseError integerValue]; this will return an integer value.
Also for future reference, an NSDictionary cannot contain any primitive values.
Related
I am getting this error:
'-[ProductionCellData objectForKey:]: unrecognized selector sent to instance 0x14dca5d0'
on this line of code:
NSString *productionItem = [[myArray objectAtIndex:keyCounter] objectForKey:#"baseLineStart"];
keyCounter is equal to 0 and here is what myArray looks like
I am trying to get the value of baseLineStart but I keep getting the error above....how do I fix this?
objectForKey is normally used in dictionaries.
If you want to access the property, just refer to it:
NSString *productionItem = [myArray objectAtIndex:keyCounter].baseLineStart;
Or with even more modern syntax:
NSString *productionItem = myArray[keyCounter].baseLineStart;
The fact is that ProductionCellData does note responds to this selector, you should use
- (nullable id)valueForKey:(NSString *)key;
or get property from object in this way (if it is public )
NSString *productionItem = [[myArray objectAtIndex:keyCounter] baseLineStart];
Try to find error by the following way.
NSDictionary *dic = [myArray objectAtIndex:keyCounter];
NSLog(#"dic:%#",dic);
NSString *productionItem = [dic objectForKey:#"baseLineStart"];
//1. observe the dic object has "baseLineStart" key. if not found write the correct one.
//2. objeserve what type of value returns "[myArray objectAtIndex:keyCounter]". it may not NSDictionary which may resoan of crash
I am sending a json blob wrapped in a iron mq message.
It comes to Restkit as a:
{
id:"2837409187409328",
delay:60,
body:"{ myJson:{ "hey":true}}"
}
Im using a rkrelationship to map a child object with the body: as type CustomObject.
However when Restkit tries to map to that custom object it blows up because it views that 'body' as a NSString instead of NSDictionary and tries to get the value out of the resulting sourceObject by using the sourceKeyPath... but since its a NSString it blows up. With:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x7fcf91165060> valueForUndefinedKey:]: this class is not key value coding-compliant for the key alreadyLiked.'
I have tried to use dynamic mapping and replace the representation with an NSDictionary.
I have tried doing validate on the accessors as is suggested in the docs, but that code is never called.
Any ideas?
Solved with post processing. I ended up taking the string that was passed into the body, overriding the setter for that body property, and in that setter running a mapping operation to take the string of json, and map it to my custom object (after converting to a dictionary) then setting that on my parent object.
Hope this helps you!
//here I have an object with a string property called Body that contains JSON.
//I extract the json, turn it into a dictionary then map it to another property on that same object that actually has a relationship mapping...
//always check to see if the body actually exists before you try to map it
//otherwise you will have a crash in your overridden setter..
if(self.Body){
NSData *data = [self.Body dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *representation = json;
//NSDictionary *metadata = #{ #"URL": [NSURL URLWithString:#"http://restkit.org"]http://restkit.org"] };
RKObjectMapping *objectMapping = [MyObject mapping];
RKMappingOperation *operation = [[RKMappingOperation alloc] initWithSourceObject:representation destinationObject:mappedResultDTO mapping:objectMapping];
RKObjectMappingOperationDataSource *dataSource = [RKObjectMappingOperationDataSource new];
operation.dataSource = dataSource;
// [operation start];
NSError *error = nil;
BOOL success = [operation performMapping:&error];
}
I have a dictionary that when I log it shows...
{
Date = "2013-04-30 17:17:18 +0000";
Description = Kb;
EventID = "92193e58-c04a-4233-9a6c-1332bc056b20";
Title = Keyboard;
}
I'm trying to turn it into NSData for a JSON web service like this...
- (NSData *)JSONRepresentation
{
NSDictionary *dictionary = [self dictionaryObject];
NSError *jsonError;
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:&jsonError]; //This is where the error occurs.
return JSONData;
}
But every time I run it the app just crashes.
The dictionary is formed properly, the app just crashes at this line.
In AppCode I get the crash report...
EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe))
In Xcode the app just stops and if I try to continue it stops with an error...
EXC_BAD_ACCESS (code=1, address=0x0)
Your keys are invalid objects for converting to JSON. From the docs:
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary. All objects are
instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull. All
dictionary keys are instances of NSString. Numbers are not NaN or
infinity.
check before, if the dictionary is invalid to convert, return.:
if (![NSJSONSerialization isValidJSONObject:dictionary]) { return; }
I'm trying to parse some JSON to a NSArray but I'm getting the following error:
[__NSCFDictionary length]: unrecognized selector sent to instance 0x6d7a160
The area of code that's throwing this error is:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError* error;
NSLog(responseString);
NSArray *jsonArray = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:&error];
parties2=jsonArray;
NSLog([parties2 objectAtIndex:0]); //Exception thrown
[tableView reloadData];
}
parties2 is previously defined as:
parties2=[NSArray arrayWithObjects:nil];
My ResponseString looks like
[{"Name":"party 1.1","GreekName":"FoA 1","GreekID":325,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":1000,"price":15.0},{"Name":"party 1.2","GreekName":"FoA 1","GreekID":325,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":300,"price":20.0},{"Name":"party 1.3","GreekName":"FoA 1","GreekID":325,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":5000,"price":25.0},{"Name":"party 2.1","GreekName":"FoA 2","GreekID":326,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":500,"price":25.0},{"Name":"party 2.2","GreekName":"FoA 2","GreekID":326,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":300,"price":30.0},{"Name":"party 3.1","GreekName":"FoA 3","GreekID":327,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":0,"price":50.0},{"Name":"party 5.1","GreekName":"FoA 5 ","GreekID":329,"schoolName":"FoA University","schoolID":10,"numberAttending":0,"maxNumberAttending":300,"price":15.75}]
This is my first venture with ObjC, I'm coming from a .Net C# background so chances are I'm missing a very simple thing.
Thanks :)
Your JSON parsing is correct. The error is being thrown because of a bad syntax in your NSLog() statement.
NSLog() takes an NSString as an argument, but your are trying to pass an NSDictionary instead (i.e. the first element of your NSArray), which is causing the error.
The solution to this is to use an NSString format string to convert the NSDictionary object to a string, like this:
NSLog(#"%#",[parties2 objectAtIndex:0]);
We have the following method where we are trying to access an array object at a given index. The array is resultArr. When we do a resultArr count it gives us a result of 13. So we know that the array is not null but when we try to do objectAtIndex it crashes with the error.
Function:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray *keys = [json allKeys];
NSLog(#"keys: %#",keys);
NSArray* htmlAttributions = [json objectForKey:#"html_attributions"]; //2
NSArray* resultArr = (NSArray *)[json objectForKey:#"result"]; //2
NSArray* statusArr = [json objectForKey:#"status"]; //2
NSLog(#"htmlAttributions: %#",htmlAttributions);
NSLog(#"result: %#", resultArr); //3
NSLog(#"status: %#", statusArr); //3
NSLog(#"resultCount: %d",[resultArr count]);
[resultArr objectAtIndex:0];
}
Error:
2012-04-01 22:31:52.757 jsonParsing[5020:f803] resultCount: 13 2012-04-01 22:31:52.759 jsonParsing[5020:f803] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6d2f900 2012-04-01 22:31:52.760 jsonParsing[5020:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6d2f900'
*** First throw call stack:
Thank you.
The error message is fairly descriptive. One of the objects that your code expects to be an NSArray is actually an NSDictionary. You cannot access fields inside of an NSDictionary by using NSArray methods (and casting from NSDictionary* to NSArray* will not convert an NSDictionary into an NSArray).
This would mean that inside of the JSON, one of your elements was serialized as an object/associative array instead of as a plain array. You can easily determine which one by looking at your JSON data as text, and finding the item that uses { and } instead of [ and ].
You are saying
NSArray* resultArr = (NSArray *)[json objectForKey:#"result"]; //2
But that does not make this object ([json objectForKey:#"result"]) an NSArray. It is an NSDictionary, and sending it a message that NSDictionary does not respond to (objectAtIndex:) causes a crash.
You were able to send it the count message without crashing because NSDictionary does happen to respond to the count message. But your preconception that this is an array is still mistaken.
You cannot cast an NSDictionary* to an NSArray* as you tried to do with this line: NSArray* resultArr = (NSArray *)[json objectForKey:#"result"];, then call -objectAtIndex.