use specified key instead of attribute name // skip = skips this attribute for parsing // check if class matches -> Apply default value NSAssert1((![[[self class] entityName] isEqualToString:ROOT_ENTITY_NAME]), @"You have to subclass this master class", nil); ! if ([attributes count] == 0) return YES; NSEntityDescription *entity = [MManagedRoot managedObjectModel].entitiesByName[[[self class] entityName]]; ! for (NSString *attributeName in entity.attributesByName) { NSAttributeDescription *attribute = entity.attributesByName[attributeName]; if (!attribute) continue; ! // check if we should skip if (ModelUserInfoValue(attribute.userInfo[PARSE_SKIP])) continue; ! // pull attribute value from dictionary id attributeValue = (attribute.userInfo[PARSE_JSON_KEY]) ? [attributes valueForKeyPath:attribute.userInfo[PARSE_JSON_KEY]] : attributes[attributeName]; if ((!ModelUserInfoValue(attribute.userInfo[PARSE_UPDATE_IF_EXIST])) && (!attributeValue)) continue; if ((!ModelUserInfoValue(entity.userInfo[PARSE_UPDATE_IF_EXIST])) && (!attributeValue)) continue; // check if we are NSNull or nil, if we are apply value for nil/null if we actually have something in the userinfo // set nil if we have nothing in the userinfo dictionary if (([attributeValue isKindOfClass:[NSNull class]]) || (!attributeValue)) { if (attribute.userInfo[PARSE_VALUE_FOR_NULL]) { if (![attribute.userInfo[PARSE_VALUE_FOR_NULL] isEqualToString:PARSE_LEAVE_AS_SELF]) [self updateAttribute:attribute withValue:attribute.userInfo[PARSE_VALUE_FOR_NULL] transformable:YES]; } else { [self setValue:nil forKeyPath:attributeName]; } continue; } if (![self updateAttribute:attribute withValue:attributeValue transformable:NO]) { // updating the attribute was unsuccessful, meaning a class mismatch happened // we have to apply the default value if that's the case, or do nothing if // we don't have a default value if (attribute.userInfo[PARSE_DEFAULT_VALUE]) { if (![attribute.userInfo[PARSE_DEFAULT_VALUE] isEqualToString:PARSE_LEAVE_AS_SELF]) [self updateAttribute:attribute withValue:attribute.userInfo[PARSE_DEFAULT_VALUE] transformable:YES]; } else { [self setValue:nil forKeyPath:attributeName]; } continue; } MDebugErrorLog(@"Could not parse attribute (%@) from value (%@)...", attributeName, attributeValue); } ! self.deleted = @(NO); self.lastParsed = [NSDate date]; ! return YES; }
Main Thread ManagedObject Context ManagedObject Context ManagedObject Context ManagedObject Context ManagedObject Context NSManagedObjectDidSaveNotification Controller MO ID MO ID MO ID MO ID MO ID MO ID
main queue is used. */ @property (nonatomic, strong) dispatch_queue_t completionQueue; ! /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ @property (nonatomic, strong) dispatch_group_t completionGroup;