Getting error in parsing JSON with array in iOS
I am recently on an iPhone, mostly in my application, I am understanding under the JSON model and have to store it in my normal 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, for example:
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 to parse the 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 crashes when I initialize the array or set some value to it. Error message:
-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730'
source to share
Your code is here
pcs.myProductCategory = [[MyProductCategory alloc] init];
pcs.myProductCategory = [item1 objectForKey:@"category"];
Creates an instance correctly MyProductCategory
, but then replaces it with a dictionary. You probably intended to write the second line as
NSDictionary *category = [item1 objectForKey:@"category"];
And then use this on the next line to unpack the contents of the dictionary
source to share
The error is that you have a string that initializes correctly myProductCategory
as your custom object:
pcs.myProductCategory = [[MyProductCategory alloc] init];
But on the very next line, you discard that and set it to be the dictionary specified in the entry category
:
pcs.myProductCategory = [item1 objectForKey:@"category"];
That way, when you go to the next line, it works because myProductCategory
no longer myProductCategory
, but rather NSDictionary
:
pcs.myProductCategory.arrayClamshells = [NSMutableArray alloc] init];
source to share