Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top