3

I am newly to iPhone, basically in my application I am parsing below JSON model and need to save it in my custom Entity class.

JSON model :

{
    "Products": [
        {
            "Pcs": [
                {
                    "product_id": 2,
                    "product_name": "MyProduct",
                    "category": {
                        "Clamshells": [
                            {
                                "product_category_id": 11,
                                "product_category_name": "MyProductCategory",
                                "Sub_category": [
                                    {
                                        "sub_category_id": 21,
                                        "sub_category_name": "MyProductSubCategory"
                                    }
                                ]
                            }
                        ],
                        "Detachables": [
                            {
                                "product_category_id": 12,
                                "product_category_name": "MyProductCatrgory1",
                                "Sub_category": [
                                    {
                                        "sub_category_id": 31,
                                        "sub_category_name": "MyProductSubCategory1"
                                    }
                                ]
                            }
                        ],
                        "Convertibles": [
                            {
                                "product_category_id": 13,
                                "product_category_name": "MyProductCatrgory2",
                                "Sub_category": [
                                    {
                                        "sub_category_id": 41,
                                        "sub_category_name": "MyProductSubCategory2"
                                    }
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    ]
}

I have created three entity classes like :

PCs.h :

#import <Foundation/Foundation.h>
#import "MyProductCategory.h"

@interface PCs : NSObject

@property (nonatomic, retain) NSString *productTitle;
@property (nonatomic, retain) NSString *productId;
@property (nonatomic, retain) MyProductCategory *myProductCategory;

@end

MyProductCategory.h :

#import <Foundation/Foundation.h>
#import "Clamshell.h"

@interface MyProductCategory : NSObject

@property (nonatomic, retain) Clamshell *clamshell;
@property (nonatomic, retain) NSMutableArray *arrayClamshells;
@property (nonatomic, retain) NSMutableArray *arrayConvertibles;
@property (nonatomic, retain) NSMutableArray *arrayDetachables;

@end

Clamshell.h :

#import <Foundation/Foundation.h>

@interface Clamshell : NSObject<NSCoding>

@property (nonatomic, retain) NSString *subProductTitle;
@property (nonatomic, retain) NSString *subProductId;

@end

Here is my code for parsing data :

    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
                                                                     options:kNilOptions
                                                                       error:&error];


                productsDict = [json objectForKey:@"Products"];

                pcsArray = [[NSMutableArray alloc] init];

    dispatch_async (dispatch_get_main_queue (),
                            ^{
                                for (NSDictionary *items in productsDict)
                                {
                                    NSDictionary *pcsDict = [items objectForKey:@"Pcs"];

                                    for (NSDictionary *item1 in pcsDict) {

                                        PCs *pcs = [[PCs alloc] init];
                                        pcs.productId = [item1 objectForKey:@"product_id"];
                                        pcs.productTitle = [item1 objectForKey:@"product_name"];

                                        //for the category                                            
                                           pcs.myProductCategory = [[MyProductCategory alloc] init];
                                           pcs.myProductCategory = [item1 objectForKey:@"category"];

                                           NSMutableArray *clamshellDict = [pcs.myProductCategory valueForKey:@"Clamshells"];


                                           NSMutableArray *array = [[NSMutableArray alloc]init];

                                            for (NSDictionary *items2 in clamshellDict) {
                                                Clamshell *clam = [[Clamshell alloc] init];
                                                clam.subProductId = [items2 objectForKey:@"sub_category_id"];
                                                clam.subProductTitle = [items2 objectForKey:@"sub_category_name"];

                                                [array addObject:clam];// 
                                            }

                                            pcs.myProductCategory.arrayClamshells = [NSMutableArray alloc] init]; //here it is crashing

pcs.myProductCategory.arrayClamshells = [array copy];
                                        }

                                        [pcsArray addObject:pcs];
                                    }

                                    NSLog(@"PCs array is = %@", pcsArray);
                                }

                            });

But it is crashing when I am initializing the array or setting any value to it. Error message is :

-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730'
halfer
  • 19,824
  • 17
  • 99
  • 186
Anand Gautam
  • 2,541
  • 3
  • 34
  • 70
  • Where is setArrayClamshells method? – Rajesh Jun 16 '15 at 06:14
  • @iDev It's just the default setter method called when `.arrayClamshells =` is. – rebello95 Jun 16 '15 at 06:15
  • yes it seems like object.array or object setArray – Anand Gautam Jun 16 '15 at 06:16
  • keep a breakpoint in arrayClamshells property. Try using exception breakpoint – Rajesh Jun 16 '15 at 06:16
  • I checked using breakpoint, the value of array is "error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector. The process has been returned to the state before expression evaluation." before initialization. After initializing it is crashing. – Anand Gautam Jun 16 '15 at 06:18
  • 2
    Your issue seems to be there: `pcs.myProductCategory = [item1 objectForKey:@"category"];`. You're assigning a NSDictionary to a `MyProductCategory`, and then it's considered as a NSDictionary (why causes and explains the crash error). Plus, there are some alloc/init which are clearly bad done. – Larme Jun 16 '15 at 06:19
  • @Larmepcs.myProductCategory is giving me the correct dictionary. Can you please suggest me the correct way to achieve my output. – Anand Gautam Jun 16 '15 at 06:23

2 Answers2

2

The error is that you have a line that properly initializes myProductCategory as your custom object:

pcs.myProductCategory = [[MyProductCategory alloc] init];

But in the very next line, you discard that and set it to be the dictionary specified by category entry:

pcs.myProductCategory = [item1 objectForKey:@"category"];

Thus, when you get to the following line, it would crash, because myProductCategory is no longer a MyProductCategory, but rather is a NSDictionary:

pcs.myProductCategory.arrayClamshells = [NSMutableArray alloc] init];
Rob
  • 415,655
  • 72
  • 787
  • 1,044
2

Your code here

pcs.myProductCategory = [[MyProductCategory alloc] init];
pcs.myProductCategory = [item1 objectForKey:@"category"];

Is correctly creating your MyProductCategory instance, but then replacing it with a dictionary. You probably intended to write the second line as

NSDictionary *category = [item1 objectForKey:@"category"];

And then use that in the next line to unpack the dictionary content

Wain
  • 118,658
  • 15
  • 128
  • 151