0

I'm really new to Cocoa development, so please be kind. Anyway, I'm trying to deserialize a JSON string I'm sending from my server through TouchJSON, but I'm getting a compiler warning of 'NSDictionary' may not respond to '+dictionaryWithJSONString:error:'.

I understand what the error is saying, but I have all the TouchJSON files in the project, and I have a reference to NSDictionary_JSONExtensions.h in the app_Prefix.pch file. When I type the command I do see it show up in the code sense, so why is it failing in the compiler?

Here's the code where it's failing, I'd appreciate any suggestions:

- (IBAction)authorizeUser:(id)sender {
 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://192.168.0.5/iOS"]];

 [request setRequestMethod:@"POST"];
 [request setPostValue:credentialsName.text forKey:@"Credentials.Name"];
 [request setPostValue:credentialsPassword.text forKey:@"Credentials.Password"];
 [request setPostValue:credentialsPIN.text forKey:@"Credentials.PIN"];
 [request startSynchronous];

 NSError *requestError = [request error];

 if (!requestError) {
  NSError *jsonError = NULL;
  NSDictionary *responseDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError]; /* <- ERROR... */

  status.text = [responseDictionary objectForKey:@"Success"];
 }
}

Thanks in advance!

UPDATE

#ifdef __OBJC__
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #import "ASIFormDataRequest.h"
    #import "CJSONDeserializer.h"
    #import "NSDictionary_JSONExtensions.h"
#endif

UPDATE 2

This is what shows up in the Preprocess, and the files are there as well as the method, so it should be working?

# 10 "/Users/Alex/Documents/iPad/Classes/SignInViewController.m" 2
# 1 "/Users/Alex/Documents/iPad/TouchJSON/Extensions/NSDictionary_JSONExtensions.h" 1
# 32 "/Users/Alex/Documents/iPad/TouchJSON/Extensions/NSDictionary_JSONExtensions.h"
@interface NSDictionary (NSDictionary_JSONExtensions)

+ (id)dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError;
Gup3rSuR4c
  • 9,145
  • 10
  • 68
  • 126
  • Post your prefix file contents. –  Jan 28 '11 at 03:53
  • @Bavarious, please look at my update above. – Gup3rSuR4c Jan 28 '11 at 04:07
  • @Alex Per seppo0010 suggestion, check whether your target has 'Precompile Prefix Header' enabled and 'Prefix Header' is the correct name of your prefix file. Also, try cleaning your target and rebuilding it. At any rate, if even #importing the header file in your implementation file doesn't work, something's very wrong. –  Jan 28 '11 at 04:28
  • @Bavarious, I checked the settings and it wasn't enabled so I went ahead and enabled it and set 'Prefix Header' to the PCH file. Sadly it still isn't having an effect, which means there's something very wrong, as you say. Now, my experience with XCode is roughly less than 10 hours, is it correct to have the TouchJSON (and ASIHttpRequest) files in the 'Other Sources' directory? Is there compiled version instead (Coming from .NET and I'm used to DLLs...)? – Gup3rSuR4c Jan 28 '11 at 05:36
  • 'Other Sources' is only a logical group so it shouldn't matter. Compiled versions are usually bundled as framework bundles but sometimes they're available as standalone static or dynamic libraries. Not sure if TouchJSON provides them. –  Jan 28 '11 at 05:44
  • One thing you could try is to check the output of the preprocessor (Build > Preprocess) on your implementation file that #imports that TouchJSON header file and see if the category on NSDictionary is being included. –  Jan 28 '11 at 05:45
  • @Bavarious, I did the preprocess and the category is included (I think), look at my second update. – Gup3rSuR4c Jan 28 '11 at 06:26
  • @Alex Interesting. Have you noticed that the method name is different from the one you're using? *Data* instead of *String*. –  Jan 28 '11 at 06:50
  • It looks like the string convenience method was added to the implementation file (.m) but not to the header file (.h). You can patch the header file to add the *String* method to the category declaration. –  Jan 28 '11 at 06:52
  • @Bavarious, I LOVE YOU, YOU ARE AWESOME! That's exactly what it was. I added it and the compiler stopped yelling at me, sadly it still isn't working and the dictionary comes back as null, so I can only assume there's bugs somewhere else. I'm gonna have to retrace everything, again, starting with the JSON, but that's all out of context for this question. – Gup3rSuR4c Jan 28 '11 at 07:50
  • @Alex Ouch. Try to inspect `jsonError` and see what error message TouchJSON returns. –  Jan 28 '11 at 07:53
  • @Bavarious, in the debugger I can see that `requestError` is `0x0` which I assume is 'no-issues', same for `jsonError`, so there shouldn't be any errors, right? As far as `responseDictionary`, I can't see any kind of meaningful information from the debugger, so it's up in the air... – Gup3rSuR4c Jan 28 '11 at 08:10
  • Actually, I take that back, somehow I got it to work. Don't know what I did, but I'm gonna move on. Thanks again for all of the help! – Gup3rSuR4c Jan 28 '11 at 08:25
  • @Alex For the record, this has already (and promptly!) been fixed by TouchJSON’s maintainer: {https://github.com/TouchCode/TouchJSON/blob/master/Source/Extensions/NSDictionary_JSONExtensions.h –  Jan 28 '11 at 22:04

2 Answers2

1

Ignore the code sense. It always suggest stuff that may not be available. Importing NSDictionary_JSONExtensions.h on your .m should fix the problem. The question is why is not fixed if it's on your .pch.

Reading the prefix restrictions, you may want to check this:

  * Use one and only one prefix header per target.
  * Set the Prefix Header and Precompile Prefix Header build settings for every target that uses precompiled headers.
seppo0010
  • 15,184
  • 5
  • 31
  • 30
  • I put the reference in both the PCH and M files and it makes no difference. I'm also curious, why it's failing when it's in the PCH file anyway (isn't that a global reference file?)... – Gup3rSuR4c Jan 28 '11 at 03:48
1

The problem is that

+ (id)dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError;

is defined in the implementation file (NSDictionary_JSONExtensions.m) but hasn't been declared in the header file (NSDictionary_JSONExtensions.h):

@interface NSDictionary (NSDictionary_JSONExtensions)
+ (id)dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError;
@end

none

You can patch the header file and add the declaration of the method you're using:

@interface NSDictionary (NSDictionary_JSONExtensions)
+ (id)dictionaryWithJSONData:(NSData *)inData error:(NSError **)outError;
+ (id)dictionaryWithJSONString:(NSString *)inJSON error:(NSError **)outError;
@end

until the developers fix this. I've just alerted TouchJSON's maintainer of this problem.

  • For the record, this has already (and promptly!) been fixed by TouchJSON’s maintainer. –  Jan 28 '11 at 22:04