When we use coreData, we will encounter the storage of more complex data types. For example, we want to store a model, but there is a dictionary in a model. At this time, how should we store it? As shown in the figure, in an
object contains a dictionary
We implement a public method to assign all properties of the object to the corresponding coreData model
id makeRemoteModelToCoreDataModel(id remoteModel,Class remoteDataClass,NSManagedObject *coreDataModel) {
int i;
unsigned int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList(remoteDataClass, &propertyCount);
NSMutableArray *propertyNameList = [NSMutableArray array];
for ( i=0; i < propertyCount; i++ ) {
objc_property_t *thisProperty = propertyList + i;
const char* propertyName = property_getName(*thisProperty);
NSString *string = [NSString stringWithFormat:@"%s",propertyName];
[propertyNameList addObject:string];
}
if (propertyNameList.count > 0) {
[propertyNameList enumerateObjectsUsingBlock:^(NSString* key, NSUInteger idx, BOOL *stop) {
id obj = [remoteModel valueForKey:key];
if (obj) {
if ([obj isKindOfClass:[NSString class]]) {
[coreDataModel setValue:obj forKey:key];
}else {
NSData *objData = [NSKeyedArchiver archivedDataWithRootObject:obj];
[coreDataModel setValue:objData forKey:key];
}
}
}];
free(propertyList);
return coreDataModel;
}else return nil;
}
Called when storing data
specialInfoDB = makeRemoteModelToCoreDataModel(specialBO, [specialObjectBO class],specialInfoDB);
Add the corresponding field in the coreData model, but the data type is NSData
as shown in the figure
When reading data, assign all fields of coredata to the model object we use.
Implemented method
id makeCoreDataModelToRemoteModel(id CoreDataModel,Class remoteDataClass) {
int i;
unsigned int propertyCount = 0;
objc_property_t *propertyList = class_copyPropertyList(remoteDataClass, &propertyCount);
NSMutableArray *propertyNameList = [NSMutableArray array];
for ( i=0; i < propertyCount; i++ ) {
objc_property_t *thisProperty = propertyList + i;
const char* propertyName = property_getName(*thisProperty);
NSString *string = [NSString stringWithFormat:@"%s",propertyName];
[propertyNameList addObject:string];
}
if (propertyNameList.count > 0) {
id dataModal = [[remoteDataClass alloc]init];
[propertyNameList enumerateObjectsUsingBlock:^(NSString* key, NSUInteger idx, BOOL *stop) {
id obj = [CoreDataModel valueForKey:key];
if ([obj isKindOfClass:[NSString class]]) {
[dataModal setValue:obj forKey:key];
}else {
id objFromData = [NSKeyedUnarchiver unarchiveObjectWithData:obj];
[dataModal setValue:objFromData forKey:key];
}
}];
free(propertyList);
return dataModal;
}else return nil;
}
transfer
specialObjectBO* specialBO = makeCoreDataModelToRemoteModel(specialInfoDB, [specialObjectBO class]);
These two places focus on the mutual conversion of dictionaries and NSData
NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dict];
NSDictionary *subDict = [NSKeyedUnarchiver unarchiveObjectWithData:dictData];
Note that the fields in our CoreData cannot directly store our custom object types, so if the field we want to store is a custom object type, we need to convert the field into a field type and then convert it to Data storage