As mmackh said, you want to define a custom method for your ProductDetails
object that will return a simple NSDictionary
of values, e.g.:
@implementation ProductDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"color" : self.color,
@"quantity" : @(self.quantity)};
}
...
Let's assume that we added manufacturer
property to our ProductDetails
, which referenced a ManufacturerDetails
class. We'd just write a jsonObject
for that class, too:
@implementation ManufacturerDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"address1" : self.address1,
@"address2" : self.address2,
@"city" : self.city,
...
@"phone" : self.phone};
}
...
And then change the jsonObject
for ProductDetails
to employ that, e.g.:
@implementation ProductDetails
- (id)jsonObject
{
return @{@"name" : self.name,
@"color" : self.color,
@"quantity" : @(self.quantity),
@"manufacturer" : [self.manufacturer jsonObject]};
}
...
If you have potentially nested collection objects (arrays and/or dictionaries) with custom objects that you want to encode, you could write a jsonObject
method for each of those, too:
@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
If you do something like that, you can now convert arrays or dictionaries of your custom objects object into something that can be used for generating 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];
If you're simply trying to save these objects in a file, I'd suggest NSKeyedArchiver
and NSKeyedUnarchiver
. But if you need to generate JSON objects for your own private classes, you can do something like the above might work.