问题
I'm trying to serialize my Cart object which has an NSMutableArray
of items in it but getting an:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Item)'
If I'm understanding how this is supposed to work, I need to create an Array of Dictionaries in order for NSJSONSerialization
to work correctly. Is that not what I am doing below?
My Cart.h:
@interface Cart : BaseObject
@property (nonatomic, strong) NSString *comp;
@property (nonatomic, strong) NSString *sono;
@property (nonatomic, strong) NSString *cust;
@property (nonatomic, strong) NSString *scus;
@property (nonatomic, strong) NSString *cnid;
@property (nonatomic, strong) NSString *dldt;
@property (nonatomic, strong) NSString *whse;
@property (nonatomic, strong) NSString *pono;
@property (nonatomic, strong) NSString *pon2;
@property (nonatomic, strong) NSString *emad;
@property (nonatomic, strong) NSString *pkin;
@property (nonatomic, strong) NSString *comt;
@property (nonatomic, strong) NSString *rtin;
@property (nonatomic, strong) NSString *lbfg;
@property (nonatomic, strong) NSString *containsOpenPriced;
@property (nonatomic, strong) NSString *totalProductAmount;
@property (nonatomic, strong) NSMutableArray *items;
@property (nonatomic) BOOL *isSubmitting;
@end
My Cart.m:
@implementation Cart
@synthesize comp;
@synthesize sono;
@synthesize cust;
@synthesize scus;
@synthesize cnid;
@synthesize dldt;
@synthesize whse;
@synthesize pono;
@synthesize pon2;
@synthesize emad;
@synthesize pkin;
@synthesize comt;
@synthesize rtin;
@synthesize lbfg;
@synthesize containsOpenPriced;
@synthesize totalProductAmount;
@synthesize items;
- (id) initWithDictionary:(NSDictionary *)dictionary {
self = [super init];
if (self) {
self.comp = dictionary[@"comp"];
self.sono = dictionary[@"sono"];
self.cust = dictionary[@"cust"];
self.scus = dictionary[@"scus"];
self.cnid = dictionary[@"cnid"];
self.dldt = dictionary[@"dldt"];
self.whse = dictionary[@"whse"];
self.pono = dictionary[@"pono"];
self.pon2 = dictionary[@"pon2"];
self.emad = dictionary[@"emad"];
self.pkin = dictionary[@"pkin"];
self.comt = dictionary[@"comt"];
self.rtin = dictionary[@"rtin"];
self.lbfg = dictionary[@"lbfg"];
self.containsOpenPriced = dictionary[@"containsOpenPriced"];
self.totalProductAmount = dictionary[@"totalProductAmount"];
NSArray *itemsArray = dictionary[@"items"];
NSMutableArray *itemsMutableArray = [[NSMutableArray alloc]init];
for (NSDictionary *itemDictionary in itemsArray) {
Item *item = [[Item alloc] initWithDictionary:itemDictionary];
[itemsMutableArray addObject:item];
}
self.items = itemsMutableArray;
}
return self;
}
@end
My code for serializing my object:
NSMutableArray *itemsToSerialize = [[NSMutableArray alloc] init];
for (Item *item in cart.items) {
NSMutableDictionary *itemDict = [[NSMutableDictionary alloc] init];
[itemDict setObject:item forKey:@"item"];
[itemsToSerialize addObject:item];
}
NSMutableDictionary *data = [@{
@"comp" : cart.comp,
@"rtin" : cart.rtin,
@"pono" : cart.pono,
@"pon2" : cart.pon2,
@"totalProductAmount" : totalProductAmount,
@"sono" : cart.sono,
@"emad" : cart.emad,
@"lbfg" : lbfg,
@"pkin" : cart.pkin,
@"containsOpenPriced" : containsOpenPriced,
@"cnid" : cart.cnid,
@"whse" : cart.whse,
@"scus" : cart.scus,
@"dldt" : cart.dldt,
@"cust" : cart.cust,
@"comt" : cart.comt,
@"items": itemsToSerialize
} mutableCopy];
NSString *command = @"shoppingCart.update";
NSMutableDictionary *request = [@{
@"command" : command,
@"comp" : cart.comp,
@"cnid" : sessionController.operator.cnid,
@"cust" : cart.cust,
@"data" : data
} mutableCopy];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:request options:kNilOptions error:nil];
This dies on the above NSJSONSerialization
line. What am I missing?
回答1:
This line: [itemsToSerialize addObject:item];
should be [itemsToSerialize addObject:itemDict];
. The result is that you're trying to serialize an array of the items themselves, which gives the exception you're seeing.
回答2:
NSJSONSerialization only works on arrays (NSArray
or NSMutableArray
), dictionaries (NSDictionary
or NSMutableDictionary
, strings (NSString
or NSMutableString
), and NSNumber
.
The common mechanism is to create a - (NSDictionary *)serialize
method on your class that copies all its values into a dictionary to be passed into NSJSONSerialization. Then implement - (id)initFromSerialization:(NSDictionary *)serialization
to deserialize the object.
回答3:
I know this is kinda late but maybe this class can ease your coding:
Its a class that transform Custom NSObject to JSON readable object(NSArray or NSDictionary). Have a try and see. It has the capability to skip properties and changed property type from string to NSInteger or Float, it can also changed the final output property name lets say
CustomObject *X;
X.property1 = @"Test";
//and the output JSON readable format you want tot change X to Y
//CustomObject converted to readable format
{Y = @"Test"}
here is the class Disassembler
来源:https://stackoverflow.com/questions/19459750/serialize-custom-object-to-json-which-contains-nsmutablearray