1

This is my code:

    NSError *error = nil;
    SBJsonParser *parserJson = [[SBJsonParser alloc] init];
    NSDictionary *jsonObject = [parserJson objectWithString:webServiceResponse error:&error]; 
    [parserJson release], parserJson = nil;

    //Test to see if response is different from nil, if is so the parsing is ok
    if(jsonObject != nil){
        //Get user object
        NSDictionary *userJson = [jsonObject objectForKey:@"LoginPOST2Result"];
        if(userJson != nil){
            self.utente = [[User alloc] init];
            self.utente.userId = [userJson objectForKey:@"ID"];
        }

While Json string webServiceResponse is:

{"LoginPOST2Result":
    "{\"ID\":1,
    \"Username\":\"Pippo\",
    \"Password\":\"Pippo\",
    \"Cognome\":\"Cognome1\",
    \"Nome\":\"Nome1\",
    \"Telefono\":\"012345678\",
    \"Email\":null,
    \"BackOffice\":true,
    \"BordoMacchina\":false,
    \"Annullato\":false,
    \"Badge\":1234}"
}

The problem arise when is execute this line:

self.utente.userId = (NSInteger *) [userJson objectForKey:@"ID"];

and the error is:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x6861520'

The error seems to be due to the fact that the object userJson is not an NSDictionary but rather NSCFString type and therefore does not respond to the message objectForKey:.
Where am I doing wrong?

LuckyStarr
  • 1,468
  • 2
  • 26
  • 39

2 Answers2

2

The problem is that whilst the value in the json response for the key "LoginPOST2Result" looks like a dictionary, it is actually a string as it is enclosed in quotes.

So you are sending the objectForKey: message to an NSString and not an NSDictionary. NSString does not respond to objectForKey:.

It looks like the webServiceResponse is being generated incorrectly or parsed incorrectly.

Brian Coleman
  • 1,070
  • 5
  • 4
  • You're right. There was an error in the line: \"status\":\"ok\". I correct it so: "status":"ok" and now is a correct JSon string. – LuckyStarr Oct 22 '11 at 13:01
1

You need to better understand what is a pointer and what no in the Cocoa Framework.

Infact you are defining userJson to NSDictionary and not NSDictionary *. Consider that all objects in Cocoa are pointers. Infact check that [NSDictionary objectForKey:] returns an "id" and then you must use NSDictionary *. Using simply NSDictionary you will refer to the class.

Similar mistake is done later in the cast to (NSInteger *) but NSInteger (NSInteger is not an object, it's a basic type hesitated from long or int (depends on the platform architecture) as you can see from its definition:


#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
#else
typedef int NSInteger;
#endif

And also it seems from the object definition above that the key you are trying to get is dumped as a string and you are trying to fetch a dictionary. Please check the original json which probably is not in the format you expect.

So at the end you have at least 3 errors that will make your app crash.

viggio24
  • 12,316
  • 5
  • 41
  • 34
  • I fixed the first two errors. In the first there was a typing error in the second one was really a mistake. However, the app keeps crashing. The format of the response is just that. I tried to validate it and is ok. The proble is that this line NSDictionary *userJson = [jsonObject objectForKey:@"LoginPOST2Result"]; return a NSCFString instead of NSDictionary. – LuckyStarr Oct 22 '11 at 13:17
  • Look carefully at the dump of the webServiceResponse: "LoginPost2Result": "..." --> the two double quotes inside what the should-be dictionary means that this is not a real dictionary! can you try to print the json string you download from the web service? I think that the parser sees that as a string and not a dictionary, so it could be a mistake in the way the json is written. – viggio24 Oct 22 '11 at 13:22
  • The JSon String from the server is: {"LoginPOST2Result":"{\"ID\":1,\"Username\":\"Pippo\",\"Password\":\"Pippo\",\"Cognome\":\"Cognome1\",\"Nome\":\"Nome1\",\"Telefono\":\"012345678\",\"Email\":null,\"BackOffice\":true,\"BordoMacchina\":false,\"Annullato\":false,\"Badge\":1234}"} . I tried to validate it with [http://jsonlint.com](http://jsonlint.com/) and it responde that it is a valid Json string. – LuckyStarr Oct 22 '11 at 13:34
  • can you append it in your post and without the "\" so don't copy and paste the json from Xcode console but get it directly from the browser or using curl. If I don't see the proper format I cannot answer. – viggio24 Oct 22 '11 at 13:40
  • I modified my post. The web service give me the json string with "\", i have get it from browser. – LuckyStarr Oct 22 '11 at 13:47
  • so I can confirm that the web service is returning the LoginPost2Results as a string and not a dictionary. What can you try to do so is do the first parse, extract the value as a string (not a dictionary), feed it to the json parser again: now it should be understood as a simple json made of dictionary keys only. The \" are simply escapes of the quotes in the string, to avoid interference with the opening and closing quotes at the boundaries. Let me know if you succeed now. – viggio24 Oct 23 '11 at 06:45