NSJSONSerialization错误 – JSON写入中的无效types(Menu)

我有一个应用程序使用具有非常相似属性的3个实体的核心数据。 关系如下:

分支 – >>菜单 – >>分类 – >> FoodItem

每个实体都有一个关联的类:例子

在这里输入图像说明

我想在sqlite数据库中生成数据的JSON表示。

//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]); 

但是,而不是JSON,我得到一个SIGABRT错误。

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

任何想法如何解决它或如何使实体类(分支,菜单等)JSON序列化兼容?

这是因为你的“菜单”类不能在JSON中序列化。 基本上,语言不知道你的对象应该如何在JSON中表示(包含哪些字段,如何表示对其他对象的引用)

从NSJSONSerialization类参考

可以转换为JSON的对象必须具有以下属性:

  • 顶级对象是NSArray或NSDictionary。
  • 所有对象都是NSString,NSNumber,NSArray,NSDictionary或NSNull的实例。
  • 所有的字典键都是NSString的实例。
  • 数字不是NaN或无穷大。

这意味着该语言知道如何序列化字典。 因此,从菜单中获取JSON表示的简单方法是提供Menu实例的字典表示,然后将其序列化为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]; } 

你可以像这样使用它:

 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]); 

isValidJSONObject上有一个类方法isValidJSONObject ,告诉你一个对象是否可以被序列化。 正如朱利安指出,你可能不得不将你的对象转换为一个NSDictionaryNSManagedModel提供了一些方便的方法来获取您的实体的所有属性。 所以你可以创build一个NSManagedObject的类别,它有一个方法将其转换为一个NSDictionary 。 通过这种方式,您不必为要转换为字典的每个实体编写toDictionary方法。

 @implementation NSManagedObject (JSON) - (NSDictionary *)toDictionary { NSArray *attributes = [[self.entity attributesByName] allKeys]; NSDictionary *dict = [self dictionaryWithValuesForKeys:attributes]; return dict; } 

你可以使用NSJSONSerialization类的+ isValidJSONObject:方法。 如果无效,可以使用NSString的 – initWithData:encoding:方法。

 - (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]; } 

我把钥匙换成了值:@ {value:@“key”}它应该是@ {@“key”:value}