Reputation: 3556
my object CCategory.h
@interface CCategory : NSObject
@property(strong, nonatomic) NSNumber * _Nonnull categoryId;
@property(strong, nonatomic) NSNumber * _Nonnull originalId;
@property(strong, nonatomic) NSString * _Nonnull name;
@property(strong, nonatomic) NSString * _Nonnull type;
@property(nonatomic, strong) CCategory * _Nullable parent;
@property (nullable, nonatomic, retain) NSOrderedSet<CCategory *> *children;
- (instancetype _Nonnull )initWithId:(NSNumber *_Nullable)categoryId
andOriginalId:(NSNumber *_Nullable)originalId
andName:(NSString *_Nonnull)name
andType:(NSString *_Nonnull)type
andParent:(CCategory *_Nullable)parent
andChildren:(NSOrderedSet<CCategory *> *_Nullable)children NS_DESIGNATED_INITIALIZER;
@end
CCategory.m
@implementation CCategory
- (instancetype)init {
return [self initWithId:0 andOriginalId:0 andName:@"" andType:@"" andParent:nil andChildren:nil];
}
- (instancetype)initWithId:(NSNumber *)categoryId
andOriginalId:(NSNumber *)originalId
andName:(NSString *)name
andType:(NSString *)type
andParent:(CCategory *)parent
andChildren:(NSOrderedSet<CCategory *> *)children {
self = [super init];
if (self) {
self.categoryId = categoryId;
self.originalId = originalId;
self.name = name;
self.type = type;
self.parent = parent;
self.children = children;
}
return self;
}
@end
This is how I check class type:
CCategory * firstItem = [itemsArray objectAtIndex:0];
CCategory *child = [firstItem.children objectAtIndex:0];
NSString *className = NSStringFromClass([child class]);
NSLog(@"First Item is: %@", className);
firstItem returns type CCategory
, child returns type NSDictionary
After receiving from database object contains all data, but children for some reason is the NSDictionary
type, not CCategory
class type. Why is that? and how can I make children type CCategory
?
Upvotes: 0
Views: 79
Reputation: 26036
Because you declare some object of some class doesn't mean that it's of the correct class. If you write for instance
NSArray *array = [@[@"Hello"] firstObject];
array
will be in fact a NSString
object.
So, when you parse your response and create your CCategory
object from what I guess a NSDictionary
object.
That's why children
seems to be in fact an NSOrderedSet
of NSDictionary
and not of CCategory
objects.
A possible way to do it, is to call recursively initWithId:andOriginalId:andName:andType:andParent:andChildren:
for the children.
So instead of self.children = children;
NSMutableOrderedSet *childrenSet = [[NSMutableOrderedSet alloc] init];
for (NSDictionary *aChildDict in [children array])
{
CCategory *aChild = [CCategory alloc] initWithId:aChildDict[keyWhereThereIsID], etc.]
[childrenSet addObject:aChild];
}
self.children = childrenSet;
But that's more of a hack to set it like that in the init
method, because it says children
should be NSOrderedSet<CCategory *> *
.
So it's up to you, to either rename the method to be clear of what it does and maybe accept a NSOrderedSet<NSDictionary *> *
for children
instead, parse it before, create another one, etc.
One possible lazy option is to do that:
Rename to andChildren:(NSOrderedSet *)children
NSMutableOrderedSet *childrenSet = [[NSMutableOrderedSet alloc] init];
for (id *aChildObject in [children array])
{
CCategory *aChild = nil;
if ([aChildObject isKindOfClass:[NSDictionary class]]) //Need parsing
{
NSDictionary *aChildDict = (NSDictionary *)aChildObject;
aChild = [CCategory alloc] initWithId:aChildDict[keyWhereThereIsID], etc.];
}
else if ([aChildObject isKindOfClass:[CCategory class]]) //Already a CCategory Object
{
aChild = (CCategory *)aChildObject;
}
else
{
NSLog(@"Ooops, child of wrong class: %@", NSStringFromClass([aChildObject class]);
}
if (aChild) { [childrenSet addObject:aChild]; }
}
self.children = childrenSet;
Upvotes: 1