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
,告诉你一个对象是否可以被序列化。 正如朱利安指出,你可能不得不将你的对象转换为一个NSDictionary
。 NSManagedModel
提供了一些方便的方法来获取您的实体的所有属性。 所以你可以创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}