我有一个应用程序使用核心数据与3个具有非常相似属性的实体。这种关系如下:
分支 - >>菜单 - >>类别 - >> FoodItem
每个实体都有一个关联的类:example
我正在尝试在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序列化兼容?
答案 0 :(得分:81)
那是因为您的“Menu”类在JSON中不可序列化。基本上,语言不知道你的对象应该如何用JSON表示(要包括哪些字段,如何表示对其他对象的引用......)
来自NSJSONSerialization Class Reference
可以转换为JSON的对象必须具有以下内容 属性:
- 顶级对象是NSArray或NSDictionary。
- 所有对象都是NSString,NSNumber,NSArray,NSDictionary或NSNull的实例。
- 所有字典键都是NSString的实例。
- 数字不是NaN或无穷大。
这意味着该语言知道如何序列化词典。因此,从菜单中获取JSON表示的一种简单方法是提供Menu实例的Dictionary表示,然后将序列化为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]);
答案 1 :(得分:24)
isValidJSONObject
上有一个类方法NSJSONSerialization
,它告诉您是否可以序列化对象。正如Julien指出的那样,您可能必须将对象转换为NSDictionary
。 NSManagedModel
提供了一些方便的方法来获取实体的所有属性。因此,您可以为NSManagedObject
创建一个类别,该类别具有将其转换为NSDictionary
的方法。这样,您就不必为要转换为字典的每个实体编写toDictionary
方法。
@implementation NSManagedObject (JSON)
- (NSDictionary *)toDictionary
{
NSArray *attributes = [[self.entity attributesByName] allKeys];
NSDictionary *dict = [self dictionaryWithValuesForKeys:attributes];
return dict;
}
答案 2 :(得分:1)
您可以使用+ isValidJSONObject:NSJSONSerialization类的方法。如果它无效,您可以使用 - initWithData:encoding: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];
}
答案 3 :(得分:0)
我将键切换为值:@ {value:@" key"} 它应该是@ {@" key":value}