7

I'm trying to create a simple JSON object but I still get error and I know what's wrong in my code:

NSString *vCard = [BRContacts getContacts]; // this is just a string, could be nil
NSDictionary *JSONdic = nil;
if (vCard)
{
    JSONdic = [NSDictionary dictionaryWithObjectsAndKeys:@"1",@"status",vCard,@"data", nil];
}
else
{
    JSONdic = [NSDictionary dictionaryWithObjectsAndKeys:@"0",@"status",@"vCard is empty",@"error", nil];
}
NSError *error = nil;
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:JSONdic options:NSJSONWritingPrettyPrinted error:&error];
return [GCDWebServerDataResponse responseWithJSONObject:JSONdata];

The exception is

Invalid top-level type in JSON write

I checked also JSONdic and it's not nil in every case. Any suggestions?

Massimo Polimeni
  • 4,826
  • 4
  • 27
  • 54
  • I'm curious about how to deploy some JSON data in GCDWebServer, then I could send some JSON request to this mock server and check the response. Would do you mind to give me some reference like code or example? – Zhou Haibo Jun 25 '20 at 10:16

3 Answers3

4

Ok I solved. It was a problem related to this line:

return [GCDWebServerDataResponse responseWithJSONObject:JSONdata];

this response of GCDWebServer doesn't want a JSON NSData but a NSDictionary: the error is just because responseWithJSONObject process the input for create a JSON object (and I passed a JSON "pre-processed" object). So my error is not related to my initial code so I updated it just now for future reference, I solved using:

return [GCDWebServerDataResponse responseWithJSONObject:JSONdic]; 

According to the documentation for similar problem be sure to follow this rules:

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.
Massimo Polimeni
  • 4,826
  • 4
  • 27
  • 54
  • This is really helpful, does it mean we don't need to serialize json data instead ```responseWithJSONObject``` will do it (because responseWithJSONObject process the input for create a JSON object) – Zhou Haibo Jun 26 '20 at 05:32
3

I can't say what is the error, because I tried here and worked.

I tried with NSString *vCard = nil and NSString *vCard = @"SOMESTRING", both cases it worked.

NSString *vCard = @"SOMESTRING"; // this is just a string, could be nil
    NSDictionary *JSONdic = nil;
    if (vCard) {
        JSONdic = @{@"status" : @"1", @"data" : vCard};
    } else {
        JSONdic = @{@"status" : @"0", @"error" : @"vCard is empty"};
    }
    NSError *error = nil;
    NSData *JSONData = [NSData data];

if ([NSJSONSerialization isValidJSONObject:JSONdic]) {
    JSONData = [NSJSONSerialization dataWithJSONObject:JSONdic options:NSJSONWritingPrettyPrinted error:&error];
}

Make sure [BRContacts getContacts] returning a NSString, and I just rewrite to a modern syntax the NSDictionary declaration.

Felipe Docil
  • 587
  • 6
  • 11
  • Checked, altro tried with your example code same result :( – Massimo Polimeni Dec 10 '15 at 16:28
  • 1
    What happens if you log `JSONData`, if I log with `vCard = @"SOMESTRING"` that's what I get: `> JSONData = <7b0a2020 22737461 74757322 203a2022 31222c0a 20202264 61746122 203a2022 534f4d45 53545249 4e47220a 7d>` And `error = nil` – Felipe Docil Dec 10 '15 at 16:30
  • I get `<7b0a2020 22737461 74757322 203a2022 31222c0a 20202264 61746122 203a2022 534f4d45 53545249 4e47220a 7d>` and I don't know why but now also my error is `nil`. Still got the same exception :\ – Massimo Polimeni Dec 10 '15 at 16:42
  • 1
    Hmm, maybe isn't in that part of code. I'm pretty sure this `JSONData` is right. – Felipe Docil Dec 10 '15 at 16:47
  • Updated the answer, could you check if enter in this `if` – Felipe Docil Dec 10 '15 at 16:55
2

Swift 4: Worth Considering

JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]

instead of

JSONSerialization.data(withJSONObject: data, options: []) as? [String:AnyObject]
Naishta
  • 11,885
  • 4
  • 72
  • 54