Error with NSJSONSerialization - Invalid JSON Record Type (Menu)

I have an application using basic data with 3 objects with very similar attributes. The relationship is:

Industry โ†’> Menu โ†’> Category โ†’> FoodItem

Each object has an associated class: example

enter image description here

I am trying to create a JSON representation of data in a sqlite database.

//gets a single menu record which has some categories and each of these have some food items id obj = [NSArray arrayWithObject:[[DataStore singleton] getHomeMenu]]; NSError *err; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:&err]; NSLog(@"JSON = %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]); 

But instead of JSON, I get a SIGABRT error.

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

Any ideas how to fix this or how to make entity classes (Branch, Menu, etc.) compatible with JSON serialization?

+48
json objective-c serialization iphone ios5
Mar 27 '12 at 15:58
source share
4 answers

This is because your Menu class is not serialized in JSON. Bascially the language does not know how your object should be represented in JSON (which fields to include, how to represent links to other objects ...)

From NSJSONSerialization class help

An object that can be converted to JSON must have the following Properties:

  • The top-level object is 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.

This means that the language knows how to serialize dictionaries. Thus, an easy way to get the JSON view from your menu is to provide a dictionary view of your menu instances, which will then be serialized to JSON:

 - (NSDictionary *)dictionaryFromMenu:(Menu)menu { [NSDictionary dictionaryWithObjectsAndKeys:[menu.dateUpdated description],@"dateUpdated", menu.categoryId, @"categoryId", //... add all the Menu properties you want to include here nil]; } 

And you can use it like this:

 NSDictionary *menuDictionary = [self dictionaryFromMenu:[[DataStore singleton] getHomeMenu]]; NSError *err; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:menuDictionary options:NSJSONWritingPrettyPrinted error:&err]; NSLog(@"JSON = %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]); 
+80
Mar 27 2018-12-12T00:
source share

There is a method of the isValidJSONObject class on NSJSONSerialization that tells you whether an object can be serialized. As Julien pointed out, you probably have to convert your object to an NSDictionary . NSManagedModel provides some convenient methods for retrieving all of your attributes for your object. That way, you can create a category for NSManagedObject that has a way to convert it to NSDictionary . Thus, you do not need to write a toDictionary method for each object that you want to convert to a dictionary.

 @implementation NSManagedObject (JSON) - (NSDictionary *)toDictionary { NSArray *attributes = [[self.entity attributesByName] allKeys]; NSDictionary *dict = [self dictionaryWithValuesForKeys:attributes]; return dict; } 
+23
Apr 13 2018-12-12T00:
source share

You can use the + isValidJSONObject: method of the NSJSONSerialization class. If this is not valid, you can use the - initWithData: encoding: method of NSString.

 - (NSString *)prettyPrintedJson:(id)jsonObject { NSData *jsonData; if ([NSJSONSerialization isValidJSONObject:jsonObject]) { NSError *error; jsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:&error]; if (error) { return nil; } } else { jsonData = jsonObject; } return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } 
+1
Oct 08 '15 at 15:28
source share

I had a key switched with a value: @ {value: @ "key"} It should be @ {@ "key": value}

0
May 23 '16 at 17:07
source share



All Articles