mmackh が言ったように、単純な値ProductDetails
を返すオブジェクトのカスタム メソッドを定義する必要があります。NSDictionary
@implementation ProductDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"color" : self.color,
@"quantity" : @(self.quantity)};
}
...
クラスを参照するmanufacturer
プロパティを に追加したと仮定しましょう。そのクラスに対しても、次のように記述します。ProductDetails
ManufacturerDetails
jsonObject
@implementation ManufacturerDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"address1" : self.address1,
@"address2" : self.address2,
@"city" : self.city,
...
@"phone" : self.phone};
}
...
そして、それを採用するようにjsonObject
forを変更します。ProductDetails
@implementation ProductDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"color" : self.color,
@"quantity" : @(self.quantity),
@"manufacturer" : [self.manufacturer jsonObject]};
}
...
エンコードしたいカスタム オブジェクトでコレクション オブジェクト (配列や辞書) をネストする可能性がある場合はjsonObject
、それらのそれぞれに対してメソッドを記述することもできます。
@interface NSDictionary (JsonObject)
- (id)jsonObject;
@end
@implementation NSDictionary (JsonObject)
- (id)jsonObject
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([obj respondsToSelector:@selector(jsonObject)])
[dictionary setObject:[obj jsonObject] forKey:key];
else
[dictionary setObject:obj forKey:key];
}];
return [NSDictionary dictionaryWithDictionary:dictionary];
}
@end
@interface NSArray (JsonObject)
- (id)jsonObject;
@end
@implementation NSArray (JsonObject)
- (id)jsonObject
{
NSMutableArray *array = [NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj respondsToSelector:@selector(jsonObject)])
[array addObject:[obj jsonObject]];
else
[array addObject:obj];
}];
return [NSArray arrayWithArray:array];
}
@end
そのようなことをすると、カスタム オブジェクト オブジェクトの配列または辞書を、JSON の生成に使用できるものに変換できるようになります。
NSArray *products = @[[[Product alloc] initWithName:@"Prius" color:@"Green" quantity:3],
[[Product alloc] initWithName:@"Accord" color:@"Black" quantity:1],
[[Product alloc] initWithName:@"Civic" color:@"Blue" quantity:2]];
id productsJsonObject = [products jsonObject];
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:productsJsonObject options:0 error:&error];
これらのオブジェクトを単にファイルに保存しようとしている場合は、NSKeyedArchiver
とNSKeyedUnarchiver
. しかし、独自のプライベート クラスの JSON オブジェクトを生成する必要がある場合は、上記のような方法でうまくいく可能性があります。