非常によく似た属性を持つ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シリアル化に互換性を持たせる方法はありますか?
これは、「Menu」クラスがJSONでシリアル化できないためです。基本的に、言語はオブジェクトがJSONでどのように表現されるべきかを知りません(どのフィールドを含めるか、他のオブジェクトへの参照をどのように表現するか...)
NSJSONSerialization Class Reference から
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
には、オブジェクトをシリアル化できるかどうかを示すクラスメソッド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;
}
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}である必要があります