diff --git a/MJExtension/MJExtension.h b/MJExtension/MJExtension.h index ad35d09c..4b4dc728 100755 --- a/MJExtension/MJExtension.h +++ b/MJExtension/MJExtension.h @@ -12,4 +12,6 @@ #import "NSObject+MJClass.h" #import "NSObject+MJKeyValue.h" #import "NSString+MJExtension.h" -#import "MJExtensionConst.h" \ No newline at end of file +#import "MJExtensionConst.h" +#import "NSManagedObject+MJCoreData.h" + diff --git a/MJExtension/MJFoundation.h b/MJExtension/MJFoundation.h index 8a0e4578..a6038f13 100644 --- a/MJExtension/MJFoundation.h +++ b/MJExtension/MJFoundation.h @@ -10,4 +10,8 @@ @interface MJFoundation : NSObject + (BOOL)isClassFromFoundation:(Class)c; +/** + * 是否是容器,NSArray, NSSet, NSOrderSet + */ ++ (BOOL)isCollectionClass:(Class)c; @end diff --git a/MJExtension/MJFoundation.m b/MJExtension/MJFoundation.m index 23a7d8cd..32bf83bc 100644 --- a/MJExtension/MJFoundation.m +++ b/MJExtension/MJFoundation.m @@ -11,6 +11,7 @@ #import static NSSet *foundationClasses_; +static NSSet *collectionClasses_; @implementation MJFoundation @@ -27,11 +28,26 @@ + (NSSet *)foundationClasses [NSArray class], [NSDictionary class], [NSString class], - [NSAttributedString class], nil]; + [NSAttributedString class], + [NSSet class], + [NSOrderedSet class], + nil]; } return foundationClasses_; } ++ (NSSet *)collectionClass +{ + if (collectionClasses_ == nil) { + collectionClasses_ = [NSSet setWithObjects: + [NSSet class], + [NSArray class], + [NSOrderedSet class], + nil]; + } + return collectionClasses_; +} + + (BOOL)isClassFromFoundation:(Class)c { if (c == [NSObject class] || c == [NSManagedObject class]) return YES; @@ -45,4 +61,15 @@ + (BOOL)isClassFromFoundation:(Class)c }]; return result; } + ++ (BOOL)isCollectionClass:(Class)c { + __block BOOL result = NO; + [[self collectionClass] enumerateObjectsUsingBlock:^(Class collectionClass, BOOL * _Nonnull stop) { + if ([c isSubclassOfClass:collectionClass]) { + result = YES; + *stop = YES; + } + }]; + return result; +} @end diff --git a/MJExtension/NSManagedObject+MJCoreData.h b/MJExtension/NSManagedObject+MJCoreData.h new file mode 100644 index 00000000..9587236b --- /dev/null +++ b/MJExtension/NSManagedObject+MJCoreData.h @@ -0,0 +1,33 @@ +// +// NSManagedObject+MJCoreData.h +// MJExtensionExample +// +// Created by 陆晖 on 15/10/30. +// Copyright © 2015年 陆晖. All rights reserved. +// + +#import +#import "NSObject+MJKeyValue.h" + +/** 这个数组中的属性名将会作为唯一键值判断,如果所有键值都存在且相等,则从数据获取数据进行更新 */ +typedef NSArray * (^MJIdentityPropertyNames)(); + +@protocol MJCoreDataKeyValue + +@optional +/** + * CoreData里的unique key,映射之前,先通过unique key去查找对应的data,如果存在,则更新,不存在,则新建 + */ ++ (NSMutableArray *)mj_identityPropertyNames; + +@end + +@interface NSManagedObject (MJCoreData) + +/** + * CoreData里的unique key,映射之前,先通过unique key去查找对应的data,如果存在,则更新,不存在,则新建 + */ ++ (void)mj_setupIdentityPropertyNames:(MJIdentityPropertyNames)ientityPropertyNames; ++ (NSMutableArray *)mj_totalIdentityPropertyNames; + +@end diff --git a/MJExtension/NSManagedObject+MJCoreData.m b/MJExtension/NSManagedObject+MJCoreData.m new file mode 100644 index 00000000..422449c2 --- /dev/null +++ b/MJExtension/NSManagedObject+MJCoreData.m @@ -0,0 +1,30 @@ +// +// NSManagedObject+MJCoreData.m +// MJExtensionExample +// +// Created by 陆晖 on 15/10/30. +// Copyright © 2015年 陆晖. All rights reserved. +// + +#import "NSManagedObject+MJCoreData.h" +#import "NSObject+MJClass.h" + +@interface NSObject (MJClassPrivate) + ++ (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key; + +@end + +static const char MJCoreDataIdentityKey = '\0'; + +@implementation NSManagedObject (MJCoreData) + ++ (void)mj_setupIdentityPropertyNames:(MJIdentityPropertyNames)ientityPropertyNames { + [self mj_setupBlockReturnValue:ientityPropertyNames key:&MJCoreDataIdentityKey]; +} + ++ (NSMutableArray *)mj_totalIdentityPropertyNames { + return [self mj_totalObjectsWithSelector:@selector(mj_identityPropertyNames) key:&MJCoreDataIdentityKey]; +} + +@end diff --git a/MJExtension/NSObject+MJClass.h b/MJExtension/NSObject+MJClass.h index e4ac1c5a..dc4fd3f0 100644 --- a/MJExtension/NSObject+MJClass.h +++ b/MJExtension/NSObject+MJClass.h @@ -23,6 +23,16 @@ typedef NSArray * (^MJIgnoredPropertyNames)(); /** 这个数组中的属性名将会被忽略:不进行归档 */ typedef NSArray * (^MJIgnoredCodingPropertyNames)(); +/** 这个数组中的属性名才会进行JSON序列化 */ +typedef NSArray * (^MJJSONSerializationPropertyNames)(); +/** 这个数组中的属性名才会序列化到object中 */ +typedef NSArray * (^MJObjectMappingPropertyNames)(); + +/** 这个数组中的属性名会被忽略:不会进行JSON序列化 */ +typedef NSArray * (^MJIgnoredJSONSerializationPropertyNames)(); +/** 这个数组中的属性名会被忽略:才会序列化到object中 */ +typedef NSArray * (^MJIgnoredObjectMappingPropertyNames)(); + /** * 类相关的扩展 */ @@ -85,6 +95,52 @@ typedef NSArray * (^MJIgnoredCodingPropertyNames)(); */ + (NSMutableArray *)mj_totalIgnoredCodingPropertyNames; +#pragma mark - 序列化映射白名单配置 +/** + * 这个数组中的属性名才会进行JSON序列化 + * + * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档 + */ ++ (void)mj_setupJSONSerializationPropertyNames:(MJJSONSerializationPropertyNames)jsonSerializationPropertyNames; + +/** + * 这个数组中的属性名将会被忽略:不进行归档 + */ ++ (NSMutableArray *)mj_totalJSONSerializationPropertyNames; +/** + * 这个数组中的属性名才会序列化到object中 + * + * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档 + */ ++ (void)mj_setupObjectMappingPropertyNames:(MJObjectMappingPropertyNames)objectMappingPropertyNames; + +/** + * 这个数组中的属性名才会序列化到object中 + */ ++ (NSMutableArray *)mj_totalObjectMappingPropertyNames; + +#pragma mark - 序列化黑名单配置 + +/** + * 这个数组中的属性名会被忽略:不会序列化到object中 +*/ ++ (void)mj_setupIgnoreObjectMappingPropertyNames:(MJIgnoredObjectMappingPropertyNames)ignoredObjectMappingPropertyNames; + +/** + * 这个数组中的属性名会被忽略:不会序列化到object中 + */ ++ (NSMutableArray *)mj_totalIgnoredObjectMappingPropertyNames; + +/* + * 这个数组中的属性名会被忽略:不会进行JSON序列化 + */ ++ (void)mj_setupIgnoredJSONSerializationPropertyNames:(MJIgnoredJSONSerializationPropertyNames)ignoredJSONSerializationPropertyNames; + +/* + * 这个数组中的属性名会被忽略:不会进行JSON序列化 + */ ++ (NSMutableArray *)mj_totalIgnoredJSONSerializationPropertyNames; + #pragma mark - 内部使用 + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key; @end diff --git a/MJExtension/NSObject+MJClass.m b/MJExtension/NSObject+MJClass.m index 789b9a89..77348d68 100644 --- a/MJExtension/NSObject+MJClass.m +++ b/MJExtension/NSObject+MJClass.m @@ -16,6 +16,10 @@ static const char MJIgnoredPropertyNamesKey = '\0'; static const char MJAllowedCodingPropertyNamesKey = '\0'; static const char MJIgnoredCodingPropertyNamesKey = '\0'; +static const char MJJSONSerializationPropertyNamesKey = '\0'; +static const char MJObjectMappingPropertyNamesKey = '\0'; +static const char MJIgnoredJSONSerializationPropertyNamesKey = '\0'; +static const char MJIgnoredObjectMappingPropertyNamesKey = '\0'; static NSMutableDictionary *allowedPropertyNamesDict_; static NSMutableDictionary *ignoredPropertyNamesDict_; @@ -128,6 +132,42 @@ + (NSMutableArray *)mj_totalAllowedCodingPropertyNames { return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey]; } + +#pragma mark - 序列化白名单配置 ++ (void)mj_setupJSONSerializationPropertyNames:(MJJSONSerializationPropertyNames)jsonSerializationPropertyNames { + [self mj_setupBlockReturnValue:jsonSerializationPropertyNames key:&MJJSONSerializationPropertyNamesKey]; +} + ++ (NSMutableArray *)mj_totalJSONSerializationPropertyNames { + return [self mj_totalObjectsWithSelector:@selector(mj_jsonSerializationPropertyNames) key:&MJJSONSerializationPropertyNamesKey]; +} + ++ (void)mj_setupObjectMappingPropertyNames:(MJJSONSerializationPropertyNames)objectMappingPropertyNames { + [self mj_setupBlockReturnValue:objectMappingPropertyNames key:&MJObjectMappingPropertyNamesKey]; +} + ++ (NSMutableArray *)mj_totalObjectMappingPropertyNames { + return [self mj_totalObjectsWithSelector:@selector(mj_objectMappingPropertyNames) key:&MJObjectMappingPropertyNamesKey]; +} + +#pragma mark - 序列化黑名单配置 + ++ (void)mj_setupIgnoredJSONSerializationPropertyNames:(MJIgnoredJSONSerializationPropertyNames)ignoredJSONSerializationPropertyNames { + [self mj_setupBlockReturnValue:ignoredJSONSerializationPropertyNames key:&MJIgnoredJSONSerializationPropertyNamesKey]; +} + ++ (NSMutableArray *)mj_totalIgnoredJSONSerializationPropertyNames { + return [self mj_totalObjectsWithSelector:@selector(mj_ignoredJSONSerializaitonPropertyNames) key:&MJIgnoredJSONSerializationPropertyNamesKey]; +} + ++ (void)mj_setupIgnoreObjectMappingPropertyNames:(MJIgnoredObjectMappingPropertyNames)ignoredObjectMappingPropertyNames { + [self mj_setupBlockReturnValue:ignoredObjectMappingPropertyNames key:&MJIgnoredObjectMappingPropertyNamesKey]; +} + ++ (NSMutableArray *)mj_totalIgnoredObjectMappingPropertyNames { + return [self mj_totalObjectsWithSelector:@selector(mj_ignoredObjectMappingPropertyNames) key:&MJIgnoredObjectMappingPropertyNamesKey]; +} + #pragma mark - block和方法处理:存储block的返回值 + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key { diff --git a/MJExtension/NSObject+MJKeyValue.h b/MJExtension/NSObject+MJKeyValue.h index e2319405..44a3b5c0 100755 --- a/MJExtension/NSObject+MJKeyValue.h +++ b/MJExtension/NSObject+MJKeyValue.h @@ -26,6 +26,26 @@ */ + (NSArray *)mj_ignoredPropertyNames; +/** + * 这个数组中的属性名才会进行JSON序列化 + */ ++ (NSArray *)mj_jsonSerializationPropertyNames; + +/** + * 这个数组中的属性名才会序列化到object中 + */ ++ (NSArray *)mj_objectMappingPropertyNames; + +/* + * 这个数组中的属性名会被忽略:不会进行JSON序列化 + */ ++ (NSArray *)mj_ignoredJSONSerializaitonPropertyNames; + +/** + * 这个数组中的属性名会被忽略:不会序列化到object中 + */ ++ (NSArray *)mj_ignoredObjectMappingPropertyNames; + /** * 将属性名换为其他key去字典中取值 * @@ -110,6 +130,24 @@ + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys; + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys; + +/** + * 通过模型数组来创建一个字典数组 + * @param objectSet 模型数组 + * @return 字典数组 + */ ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet; ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet keys:(NSArray *)keys; ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet ignoredKeys:(NSArray *)ignoredKeys; + +/** + * 通过模型数组来创建一个字典数组 + * @param objectOrderedSet 模型数组 + * @return 字典数组 + */ ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet; ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet keys:(NSArray *)keys; ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet ignoredKeys:(NSArray *)ignoredKeys; #pragma mark - 字典转模型 /** * 通过字典来创建一个模型 @@ -156,6 +194,36 @@ */ + (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context; +/** + * 通过字典数组来创建一个模型数组 + * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString) + * @return 模型数组 + */ ++ (NSMutableSet *)mj_objectSetWithKeyValuesArray:(id)keyValuesArray; + +/** + * 通过字典数组来创建一个模型数组, + * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString) + * @param context CoreData上下文 + * @return 模型数组 + */ ++ (NSMutableSet *)mj_objectSetWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context; + +/** + * 通过字典数组来创建一个模型数组 + * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString) + * @return 模型数组 + */ ++ (NSMutableOrderedSet *)mj_objectOrderedSetWithKeyValuesArray:(id)keyValuesArray; + +/** + * 通过字典数组来创建一个模型数组, + * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString) + * @param context CoreData上下文 + * @return 模型数组 + */ ++ (NSMutableOrderedSet *)mj_objectOrderedSetWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context; + /** * 通过plist来创建一个模型数组 * @param filename 文件名(仅限于mainBundle中的文件) diff --git a/MJExtension/NSObject+MJKeyValue.m b/MJExtension/NSObject+MJKeyValue.m index 5635e292..249b955f 100755 --- a/MJExtension/NSObject+MJKeyValue.m +++ b/MJExtension/NSObject+MJKeyValue.m @@ -15,6 +15,13 @@ #import "MJFoundation.h" #import "NSString+MJExtension.h" #import "NSObject+MJClass.h" +#import "NSManagedObject+MJCoreData.h" + +@interface NSManagedObject (MJKeyValue) + ++ (NSArray *)mj_defaultAllowPropertyNamesWithContext:(NSManagedObjectContext *)context; + +@end @implementation NSObject (MJKeyValue) @@ -81,13 +88,24 @@ - (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *) Class clazz = [self class]; NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames]; + if ([self isKindOfClass:[NSManagedObject class]] && allowedPropertyNames.count == 0) { + allowedPropertyNames = [clazz mj_defaultAllowPropertyNamesWithContext:context]; + //加入缓存 + [clazz mj_setupAllowedPropertyNames:^NSArray *{ + return allowedPropertyNames; + }]; + } NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames]; + NSArray *ignoredMappingPropertyNames = [clazz mj_totalIgnoredObjectMappingPropertyNames]; + NSArray *objectMappingPropertyNames = [clazz mj_totalObjectMappingPropertyNames]; //通过封装的方法回调一个通过运行时编写的,用于返回属性列表的方法。 [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) { @try { // 0.检测是否被忽略 if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return; + if (objectMappingPropertyNames.count && ![objectMappingPropertyNames containsObject:property.name]) return; + if ([ignoredMappingPropertyNames containsObject:property.name]) return; if ([ignoredPropertyNames containsObject:property.name]) return; // 1.取出属性值 @@ -138,8 +156,15 @@ - (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *) [urlArray addObject:string.mj_url]; } value = urlArray; - } else { // 字典数组-->模型数组 - value = [objectClass mj_objectArrayWithKeyValuesArray:value context:context]; + } else { + // 3.字典数组-->模型数组 + if ([propertyClass isSubclassOfClass:[NSSet class]]) { + value = [objectClass mj_objectSetWithKeyValuesArray:value context:context]; + } else if ([propertyClass isKindOfClass:[NSOrderedSet class]]) { + value = [objectClass mj_objectOrderedSetWithKeyValuesArray:value context:context]; + } else { + value = [objectClass mj_objectArrayWithKeyValuesArray:value context:context]; + } } } else { if (propertyClass == [NSString class]) { @@ -165,8 +190,20 @@ - (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *) value = [numberFormatter_ numberFromString:oldValue]; } - // 如果是BOOL - if (type.isBoolType) { + BOOL isBOOLType = type.isBoolType; + + if (property.type.isNumberType && [self isKindOfClass:[NSManagedObject class]]) { + NSManagedObject *object = (NSManagedObject *)self; + NSEntityDescription *entityDescription = [object entity]; + NSAttributeDescription *attr = [[entityDescription attributesByName] objectForKey:property.name]; + NSAttributeType type = [attr attributeType]; + if (type == NSBooleanAttributeType) { + isBOOLType = YES; + } + } + + if (isBOOLType) { + // 如果是BOOL // 字符串转BOOL(字符串没有charValue方法) // 系统会调用字符串的charValue转为BOOL类型 NSString *lower = [oldValue lowercaseString]; @@ -210,11 +247,8 @@ + (instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectCon // 获得JSON对象 keyValues = [keyValues mj_JSONObject]; MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], nil, [self class], @"keyValues参数不是一个字典"); - - if ([self isSubclassOfClass:[NSManagedObject class]] && context) { - return [[NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(self) inManagedObjectContext:context] mj_setKeyValues:keyValues context:context]; - } - return [[[self alloc] init] mj_setKeyValues:keyValues]; + NSObject *data =[self mj_generateDataWithKeyValue:keyValues inContext:context]; + return [data mj_setKeyValues:keyValues context:context]; } + (instancetype)mj_objectWithFilename:(NSString *)filename @@ -232,6 +266,9 @@ + (instancetype)mj_objectWithFile:(NSString *)file } #pragma mark - 字典数组 -> 模型数组 + +#pragma mark Array + + (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray { return [self mj_objectArrayWithKeyValuesArray:keyValuesArray context:nil]; @@ -239,32 +276,30 @@ + (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray + (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context { - // 如果是JSON字符串 - keyValuesArray = [keyValuesArray mj_JSONObject]; - - // 1.判断真实性 - MJExtensionAssertError([keyValuesArray isKindOfClass:[NSArray class]], nil, [self class], @"keyValuesArray参数不是一个数组"); - - // 如果数组里面放的是NSString、NSNumber等数据 - if ([MJFoundation isClassFromFoundation:self]) return [NSMutableArray arrayWithArray:keyValuesArray]; - + return [self mj_objectMutableCollection:[NSMutableArray new] withKeyValuesArray:keyValuesArray context:context]; +} - // 2.创建数组 - NSMutableArray *modelArray = [NSMutableArray array]; - - // 3.遍历 - for (NSDictionary *keyValues in keyValuesArray) { - if ([keyValues isKindOfClass:[NSArray class]]){ - [modelArray addObject:[self mj_objectArrayWithKeyValuesArray:keyValues context:context]]; - } else { - id model = [self mj_objectWithKeyValues:keyValues context:context]; - if (model) [modelArray addObject:model]; - } - } - - return modelArray; +#pragma mark Set + ++ (NSMutableSet *)mj_objectSetWithKeyValuesArray:(id)keyValuesArray { + return [self mj_objectSetWithKeyValuesArray:keyValuesArray context:nil]; +} + ++ (NSMutableSet *)mj_objectSetWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context { + return [self mj_objectMutableCollection:[NSMutableSet new] withKeyValuesArray:keyValuesArray context:context]; } +#pragma mark OrderdSet + ++ (NSMutableOrderedSet *)mj_objectOrderedSetWithKeyValuesArray:(id)keyValuesArray { + return [self mj_objectOrderedSetWithKeyValuesArray:keyValuesArray context:nil]; +} ++ (NSMutableOrderedSet *)mj_objectOrderedSetWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context { + return [self mj_objectMutableCollection:[NSMutableOrderedSet new] withKeyValuesArray:keyValuesArray context:context]; +} + +#pragma mark File + + (NSMutableArray *)mj_objectArrayWithFilename:(NSString *)filename { MJExtensionAssertError(filename != nil, nil, [self class], @"filename参数为nil"); @@ -304,12 +339,24 @@ - (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArr Class clazz = [self class]; NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames]; + if ([self isKindOfClass:[NSManagedObject class]] && allowedPropertyNames.count == 0) { + NSManagedObject *object = (NSManagedObject *)self; + allowedPropertyNames = [clazz mj_defaultAllowPropertyNamesWithContext:object.managedObjectContext]; + //加入缓存 + [clazz mj_setupAllowedPropertyNames:^NSArray *{ + return allowedPropertyNames; + }]; + } + NSArray *jsonSerializationPropertyNames = [clazz mj_totalJSONSerializationPropertyNames]; + NSArray *ignoredJSONSerializationPropertyNames = [clazz mj_totalIgnoredJSONSerializationPropertyNames]; NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames]; [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) { @try { // 0.检测是否被忽略 if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return; + if (jsonSerializationPropertyNames.count && ![jsonSerializationPropertyNames containsObject:property.name]) return; + if ([ignoredJSONSerializationPropertyNames containsObject:property.name]) return; if ([ignoredPropertyNames containsObject:property.name]) return; if (keys.count && ![keys containsObject:property.name]) return; if ([ignoredKeys containsObject:property.name]) return; @@ -322,14 +369,40 @@ - (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArr MJPropertyType *type = property.type; Class propertyClass = type.typeClass; if (!type.isFromFoundation && propertyClass) { - value = [value mj_keyValues]; - } else if ([value isKindOfClass:[NSArray class]]) { + if ([propertyClass isSubclassOfClass:[NSManagedObject class]] && [self isKindOfClass:[NSManagedObject class]]) { + //core data对象关联另一个core data对象,可能存在inverse关系,需要过滤,否则造成循环调用 + NSManagedObject *object = (NSManagedObject *)self; + NSManagedObjectContext *context = object.managedObjectContext; + NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:context]; + NSRelationshipDescription *relationshipDescription = entityDescription.relationshipsByName[property.name]; + NSString *inverseRelationName = relationshipDescription.inverseRelationship.name; + NSArray *ignoreKeys; + if (inverseRelationName) { + ignoreKeys = @[inverseRelationName]; + } + value = [value mj_keyValuesWithIgnoredKeys:ignoreKeys]; + } else { + value = [value mj_keyValues]; + } + } else if ([MJFoundation isCollectionClass:[value class]]) { // 3.处理数组里面有模型的情况 value = [NSObject mj_keyValuesArrayWithObjectArray:value]; } else if (propertyClass == [NSURL class]) { value = [value absoluteString]; } + //TODO: 看看有没有办法放在初始化property的时候,为property.type.isBoolType赋值 + // 如果是CoreData对象,需要判断NSNumber的属性是否bool类型,否则JSON序列化的时候会序列化为0/1 + if (property.type.isNumberType && [self isKindOfClass:[NSManagedObject class]]) { + NSManagedObject *object = (NSManagedObject *)self; + NSEntityDescription *entityDescription = [object entity]; + NSAttributeDescription *attr = [[entityDescription attributesByName] objectForKey:property.name]; + NSAttributeType type = [attr attributeType]; + if (type == NSBooleanAttributeType) { + value = [value boolValue]?@YES:@NO; + } + } + // 4.赋值 if ([clazz mj_isReferenceReplacedKeyWhenCreatingKeyValues]) { NSArray *propertyKeys = [[property propertyKeysForClass:clazz] firstObject]; @@ -393,9 +466,11 @@ - (NSMutableDictionary *)mj_keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArr return keyValues; } #pragma mark - 模型数组 -> 字典数组 + +#pragma mark Array + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray { - return [self mj_keyValuesArrayWithObjectArray:objectArray keys:nil ignoredKeys:nil]; + return [self mj_keyValuesArrayWithObjectArray:objectArray ignoredKeys:nil]; } + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys @@ -410,19 +485,45 @@ + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray igno + (NSMutableArray *)mj_keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys { - // 0.判断真实性 - MJExtensionAssertError([objectArray isKindOfClass:[NSArray class]], nil, [self class], @"objectArray参数不是一个数组"); - - // 1.创建数组 - NSMutableArray *keyValuesArray = [NSMutableArray array]; - for (id object in objectArray) { - if (keys) { - [keyValuesArray addObject:[object mj_keyValuesWithKeys:keys]]; - } else { - [keyValuesArray addObject:[object mj_keyValuesWithIgnoredKeys:ignoredKeys]]; - } - } - return keyValuesArray; + return [self mj_keyValuesArrayWithObjectCollection:objectArray keys:keys ignoredKeys:ignoredKeys]; +} + +#pragma mark Set + ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet +{ + return [self mj_keyValuesArrayWithObjectCollection:objectSet keys:nil ignoredKeys:nil]; +} ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet keys:(NSArray *)keys +{ + return [self mj_keyValuesArrayWithObjectCollection:objectSet keys:keys ignoredKeys:nil]; +} ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet ignoredKeys:(NSArray *)ignoredKeys +{ + return [self mj_keyValuesArrayWithObjectCollection:objectSet keys:nil ignoredKeys:ignoredKeys]; +} + ++ (NSMutableArray *)mj_keyValuesArrayWithObjectSet:(NSSet *)objectSet keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys +{ + return [self mj_keyValuesArrayWithObjectCollection:objectSet keys:keys ignoredKeys:ignoredKeys]; +} + +#pragma mark OrderSet + ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet +{ + return [self mj_keyValuesArrayWithObjectCollection:objectOrderedSet keys:nil ignoredKeys:nil]; +} ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet keys:(NSArray *)keys +{ + return [self mj_keyValuesArrayWithObjectCollection:objectOrderedSet keys:keys ignoredKeys:nil]; +} ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet ignoredKeys:(NSArray *)ignoredKeys { + return [self mj_keyValuesArrayWithObjectCollection:objectOrderedSet keys:nil ignoredKeys:ignoredKeys]; +} ++ (NSMutableArray *)mj_keyValuesArrayWithObjectOrderedSet:(NSOrderedSet *)objectOrderedSet keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys +{ + return [self mj_keyValuesArrayWithObjectCollection:objectOrderedSet keys:keys ignoredKeys:ignoredKeys]; } #pragma mark - 转换为JSON @@ -458,6 +559,131 @@ - (NSString *)mj_JSONString return [[NSString alloc] initWithData:[self mj_JSONData] encoding:NSUTF8StringEncoding]; } + +#pragma mark - 私有方法 + ++ (id)mj_objectMutableCollection:(id)mutableCollection withKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context { + // 如果数组里面放的是NSString、NSNumber等数据 + if ([MJFoundation isClassFromFoundation:self]) { + if ([mutableCollection isKindOfClass:[NSMutableSet class]]) { + return [NSMutableSet setWithArray:keyValuesArray]; + } else if ([mutableCollection isKindOfClass:[NSMutableOrderedSet class]]) { + return [NSMutableOrderedSet orderedSetWithArray:keyValuesArray]; + } else { + return [NSMutableArray arrayWithArray:keyValuesArray]; + } + } + + // 如果是JSON字符串 + keyValuesArray = [keyValuesArray mj_JSONObject]; + + // 1.判断真实性 + MJExtensionAssertError([keyValuesArray isKindOfClass:[NSArray class]], nil, self, @"keyValuesArray参数不是一个数组"); + + // 2.遍历 + for (NSDictionary *keyValues in keyValuesArray) { + if ([keyValues isKindOfClass:[NSArray class]]){ + [mutableCollection addObject:[self mj_objectArrayWithKeyValuesArray:keyValues context:context]]; + } else { + id model = [self mj_objectWithKeyValues:keyValues context:context]; + if (model) [mutableCollection addObject:model]; + } + } + + return mutableCollection; +} + ++ (NSMutableArray *)mj_keyValuesArrayWithObjectCollection:(id)objectCollection keys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys +{ + // 0.判断真实性 + MJExtensionAssertError([MJFoundation isCollectionClass:[objectCollection class]], nil, self, @"objectCollection参数不是一个容器"); + + // 1.创建数组 + NSMutableArray *keyValuesArray = [NSMutableArray array]; + for (id object in objectCollection) { + if (keys) { + [keyValuesArray addObject:[object mj_keyValuesWithKeys:keys]]; + } else { + [keyValuesArray addObject:[object mj_keyValuesWithIgnoredKeys:ignoredKeys]]; + } + } + return keyValuesArray; +} + +/** + * 对象初始化工厂方法,根据class生成对应的实例 + */ ++ (NSObject *)mj_generateDataWithKeyValue:(id)keyValues inContext:(NSManagedObjectContext *)context { + return [[self alloc] init]; +} + +@end + +/** + * 重写实例生成方法,core data对象先通过identityPropertyName查找是否包含有对应的数据,如果有,则生成该数据的实例进行更新,否则插入新数据 + */ +@implementation NSManagedObject (MJKeyValue) + ++ (NSObject *)mj_generateDataWithKeyValue:(id)keyValues inContext:(NSManagedObjectContext *)context { + MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], nil, self, @"keyValue参数不是一个NSDictionary"); + MJExtensionAssertError(context != nil, nil, self, @"没有传递context"); + Class aClass = self; + NSManagedObject *mappingObject; + NSArray *identityProperyNames = [aClass mj_totalIdentityPropertyNames]; + + //TODO:这里的代码和setKeyValues:的代码有重复,后期需要优化 + //设置了唯一键值,则尝试去数据库中找到对应的数据 + if (identityProperyNames.count > 0) { + NSMutableArray *predicateArray = [[NSMutableArray alloc] initWithCapacity:identityProperyNames.count]; + [aClass mj_enumerateProperties:^(MJProperty *property, BOOL *stop) { + if ([identityProperyNames containsObject:property.name]) { + // 1.取出属性值 + id value; + NSArray *propertyKeyses = [property propertyKeysForClass:aClass]; + for (NSArray *propertyKeys in propertyKeyses) { + value = keyValues; + for (MJPropertyKey *propertyKey in propertyKeys) { + value = [propertyKey valueInObject:value]; + } + if (value) break; + } + + // 2.值的过滤 + id newValue = [aClass mj_getNewValueFromObject:self oldValue:value property:property]; + if (newValue) value = newValue; + + // 3.建立predicate + if (value) { + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", property.name, value]; + [predicateArray addObject:predicate]; + } else { + //unique key不在keyValues中,取消遍历,直接插入新数据 + *stop = YES; + } + } + }]; + + // 4. 查询对象 + if (predicateArray.count == identityProperyNames.count) { + NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass(self)]; + fetchRequest.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateArray]; + fetchRequest.fetchLimit = 1; + mappingObject = [context executeFetchRequest:fetchRequest error:nil].firstObject; + } + } + + if (!mappingObject) { + mappingObject = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(self) inManagedObjectContext:context]; + } + + return [mappingObject mj_setKeyValues:keyValues context:context]; +} + ++ (NSArray *)mj_defaultAllowPropertyNamesWithContext:(NSManagedObjectContext *)context { + MJExtensionAssertError(context != nil, nil, self, @"传入的context为nil"); + NSEntityDescription *description = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:context]; + return [description propertiesByName].allKeys; +} @end @implementation NSObject (MJKeyValueDeprecated_v_2_5_16) @@ -470,7 +696,7 @@ - (instancetype)setKeyValues:(id)keyValues error:(NSError **)error { id value = [self mj_setKeyValues:keyValues]; if (error != NULL) { - *error = [self.class mj_error]; + *error = [self.class mj_error]; } return value; @@ -485,7 +711,7 @@ - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)con { id value = [self mj_setKeyValues:keyValues context:context]; if (error != NULL) { - *error = [self.class mj_error]; + *error = [self.class mj_error]; } return value; } @@ -504,7 +730,7 @@ - (NSMutableDictionary *)keyValuesWithError:(NSError **)error { id value = [self mj_keyValues]; if (error != NULL) { - *error = [self.class mj_error]; + *error = [self.class mj_error]; } return value; } @@ -518,7 +744,7 @@ - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)err { id value = [self mj_keyValuesWithKeys:keys]; if (error != NULL) { - *error = [self.class mj_error]; + *error = [self.class mj_error]; } return value; } @@ -532,7 +758,7 @@ - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:( { id value = [self mj_keyValuesWithIgnoredKeys:ignoredKeys]; if (error != NULL) { - *error = [self.class mj_error]; + *error = [self.class mj_error]; } return value; } @@ -546,7 +772,7 @@ + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:( { id value = [self mj_keyValuesArrayWithObjectArray:objectArray]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -560,7 +786,7 @@ + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(N { id value = [self mj_keyValuesArrayWithObjectArray:objectArray keys:keys]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -574,7 +800,7 @@ + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignored { id value = [self mj_keyValuesArrayWithObjectArray:objectArray ignoredKeys:ignoredKeys]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -588,7 +814,7 @@ + (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error { id value = [self mj_objectWithKeyValues:keyValues]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -602,7 +828,7 @@ + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContex { id value = [self mj_objectWithKeyValues:keyValues context:context]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -616,7 +842,7 @@ + (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error { id value = [self mj_objectWithFilename:filename]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -630,7 +856,7 @@ + (instancetype)objectWithFile:(NSString *)file error:(NSError **)error { id value = [self mj_objectWithFile:file]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -644,7 +870,7 @@ + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSEr { id value = [self mj_objectArrayWithKeyValuesArray:keyValuesArray]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -658,7 +884,7 @@ + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NS { id value = [self mj_objectArrayWithKeyValuesArray:keyValuesArray context:context]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -672,7 +898,7 @@ + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError { id value = [self mj_objectArrayWithFilename:filename]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -686,7 +912,7 @@ + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error { id value = [self mj_objectArrayWithFile:file]; if (error != NULL) { - *error = [self mj_error]; + *error = [self mj_error]; } return value; } @@ -705,4 +931,4 @@ - (NSString *)JSONString { return [self mj_JSONString]; } -@end \ No newline at end of file +@end diff --git a/MJExtensionExample.xcodeproj/project.pbxproj b/MJExtensionExample.xcodeproj/project.pbxproj index 43f001d5..93512898 100644 --- a/MJExtensionExample.xcodeproj/project.pbxproj +++ b/MJExtensionExample.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 2D8FC6B81BEF7E89004471E9 /* MJExtensionConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FC6B71BEF7E89004471E9 /* MJExtensionConfig.m */; settings = {ASSET_TAGS = (); }; }; + 2D8FC6B81BEF7E89004471E9 /* MJExtensionConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FC6B71BEF7E89004471E9 /* MJExtensionConfig.m */; }; 2DE3CD971BEF7B3800DA0F2E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CD961BEF7B3800DA0F2E /* main.m */; }; 2DE3CD9A1BEF7B3800DA0F2E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CD991BEF7B3800DA0F2E /* AppDelegate.m */; }; 2DE3CD9D1BEF7B3800DA0F2E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CD9C1BEF7B3800DA0F2E /* ViewController.m */; }; @@ -16,26 +16,34 @@ 2DE3CDA51BEF7B3800DA0F2E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2DE3CDA31BEF7B3800DA0F2E /* LaunchScreen.storyboard */; }; 2DE3CDB01BEF7B3800DA0F2E /* MJExtensionExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDAF1BEF7B3800DA0F2E /* MJExtensionExampleTests.m */; }; 2DE3CDBB1BEF7B3800DA0F2E /* MJExtensionExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDBA1BEF7B3800DA0F2E /* MJExtensionExampleUITests.m */; }; - 2DE3CDE11BEF7B9F00DA0F2E /* MJExtensionConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDCD1BEF7B9F00DA0F2E /* MJExtensionConst.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE21BEF7B9F00DA0F2E /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDCF1BEF7B9F00DA0F2E /* MJFoundation.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE31BEF7B9F00DA0F2E /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD11BEF7B9F00DA0F2E /* MJProperty.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE41BEF7B9F00DA0F2E /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD31BEF7B9F00DA0F2E /* MJPropertyKey.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE51BEF7B9F00DA0F2E /* MJPropertyType.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD51BEF7B9F00DA0F2E /* MJPropertyType.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE61BEF7B9F00DA0F2E /* NSObject+MJClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD71BEF7B9F00DA0F2E /* NSObject+MJClass.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE71BEF7B9F00DA0F2E /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD91BEF7B9F00DA0F2E /* NSObject+MJCoding.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE81BEF7B9F00DA0F2E /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDB1BEF7B9F00DA0F2E /* NSObject+MJKeyValue.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDE91BEF7B9F00DA0F2E /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDD1BEF7B9F00DA0F2E /* NSObject+MJProperty.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CDEA1BEF7B9F00DA0F2E /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDF1BEF7B9F00DA0F2E /* NSString+MJExtension.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE011BEF7BE100DA0F2E /* MJAd.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDEE1BEF7BE100DA0F2E /* MJAd.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE021BEF7BE100DA0F2E /* MJBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF01BEF7BE100DA0F2E /* MJBag.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE031BEF7BE100DA0F2E /* MJBaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF21BEF7BE100DA0F2E /* MJBaseObject.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE041BEF7BE100DA0F2E /* MJBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF41BEF7BE100DA0F2E /* MJBook.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE051BEF7BE100DA0F2E /* MJBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF61BEF7BE100DA0F2E /* MJBox.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE061BEF7BE100DA0F2E /* MJDog.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF81BEF7BE100DA0F2E /* MJDog.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE071BEF7BE100DA0F2E /* MJStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFA1BEF7BE100DA0F2E /* MJStatus.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE081BEF7BE100DA0F2E /* MJStatusResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFC1BEF7BE100DA0F2E /* MJStatusResult.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE091BEF7BE100DA0F2E /* MJStudent.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFE1BEF7BE100DA0F2E /* MJStudent.m */; settings = {ASSET_TAGS = (); }; }; - 2DE3CE0A1BEF7BE100DA0F2E /* MJUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CE001BEF7BE100DA0F2E /* MJUser.m */; settings = {ASSET_TAGS = (); }; }; + 2DE3CDE11BEF7B9F00DA0F2E /* MJExtensionConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDCD1BEF7B9F00DA0F2E /* MJExtensionConst.m */; }; + 2DE3CDE21BEF7B9F00DA0F2E /* MJFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDCF1BEF7B9F00DA0F2E /* MJFoundation.m */; }; + 2DE3CDE31BEF7B9F00DA0F2E /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD11BEF7B9F00DA0F2E /* MJProperty.m */; }; + 2DE3CDE41BEF7B9F00DA0F2E /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD31BEF7B9F00DA0F2E /* MJPropertyKey.m */; }; + 2DE3CDE51BEF7B9F00DA0F2E /* MJPropertyType.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD51BEF7B9F00DA0F2E /* MJPropertyType.m */; }; + 2DE3CDE61BEF7B9F00DA0F2E /* NSObject+MJClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD71BEF7B9F00DA0F2E /* NSObject+MJClass.m */; }; + 2DE3CDE71BEF7B9F00DA0F2E /* NSObject+MJCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDD91BEF7B9F00DA0F2E /* NSObject+MJCoding.m */; }; + 2DE3CDE81BEF7B9F00DA0F2E /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDB1BEF7B9F00DA0F2E /* NSObject+MJKeyValue.m */; }; + 2DE3CDE91BEF7B9F00DA0F2E /* NSObject+MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDD1BEF7B9F00DA0F2E /* NSObject+MJProperty.m */; }; + 2DE3CDEA1BEF7B9F00DA0F2E /* NSString+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDDF1BEF7B9F00DA0F2E /* NSString+MJExtension.m */; }; + 2DE3CE011BEF7BE100DA0F2E /* MJAd.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDEE1BEF7BE100DA0F2E /* MJAd.m */; }; + 2DE3CE021BEF7BE100DA0F2E /* MJBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF01BEF7BE100DA0F2E /* MJBag.m */; }; + 2DE3CE031BEF7BE100DA0F2E /* MJBaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF21BEF7BE100DA0F2E /* MJBaseObject.m */; }; + 2DE3CE041BEF7BE100DA0F2E /* MJBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF41BEF7BE100DA0F2E /* MJBook.m */; }; + 2DE3CE051BEF7BE100DA0F2E /* MJBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF61BEF7BE100DA0F2E /* MJBox.m */; }; + 2DE3CE061BEF7BE100DA0F2E /* MJDog.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDF81BEF7BE100DA0F2E /* MJDog.m */; }; + 2DE3CE071BEF7BE100DA0F2E /* MJStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFA1BEF7BE100DA0F2E /* MJStatus.m */; }; + 2DE3CE081BEF7BE100DA0F2E /* MJStatusResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFC1BEF7BE100DA0F2E /* MJStatusResult.m */; }; + 2DE3CE091BEF7BE100DA0F2E /* MJStudent.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CDFE1BEF7BE100DA0F2E /* MJStudent.m */; }; + 2DE3CE0A1BEF7BE100DA0F2E /* MJUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DE3CE001BEF7BE100DA0F2E /* MJUser.m */; }; + EF0A99911C745504003176D4 /* NSManagedObject+MJCoreData.m in Sources */ = {isa = PBXBuildFile; fileRef = EF0A99901C745504003176D4 /* NSManagedObject+MJCoreData.m */; }; + EF1DD9271C7E9FC90008F3C2 /* Platform+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = EF1DD91C1C7E9FC90008F3C2 /* Platform+CoreDataProperties.m */; }; + EF1DD9281C7E9FC90008F3C2 /* Platform.m in Sources */ = {isa = PBXBuildFile; fileRef = EF1DD91E1C7E9FC90008F3C2 /* Platform.m */; }; + EF1DD9291C7E9FC90008F3C2 /* Base+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = EF1DD9201C7E9FC90008F3C2 /* Base+CoreDataProperties.m */; }; + EF1DD92A1C7E9FC90008F3C2 /* Base.m in Sources */ = {isa = PBXBuildFile; fileRef = EF1DD9221C7E9FC90008F3C2 /* Base.m */; }; + EF1DD92C1C7E9FC90008F3C2 /* Games.m in Sources */ = {isa = PBXBuildFile; fileRef = EF1DD9261C7E9FC90008F3C2 /* Games.m */; }; + EF62564D1CA4E9D000AC6DAF /* Games+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = EF62564C1CA4E9D000AC6DAF /* Games+CoreDataProperties.m */; }; + EFF3C5981C746D820021C293 /* CoreData.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = EFF3C5961C746D820021C293 /* CoreData.xcdatamodeld */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -116,6 +124,21 @@ 2DE3CDFF1BEF7BE100DA0F2E /* MJUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJUser.h; sourceTree = ""; }; 2DE3CE001BEF7BE100DA0F2E /* MJUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJUser.m; sourceTree = ""; }; 2DE3CE0B1BEF7C2100DA0F2E /* main.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = ""; }; + EF0A998F1C745504003176D4 /* NSManagedObject+MJCoreData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MJCoreData.h"; sourceTree = ""; }; + EF0A99901C745504003176D4 /* NSManagedObject+MJCoreData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MJCoreData.m"; sourceTree = ""; }; + EF1DD91B1C7E9FC90008F3C2 /* Platform+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Platform+CoreDataProperties.h"; path = "CoreData/Platform+CoreDataProperties.h"; sourceTree = ""; }; + EF1DD91C1C7E9FC90008F3C2 /* Platform+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Platform+CoreDataProperties.m"; path = "CoreData/Platform+CoreDataProperties.m"; sourceTree = ""; }; + EF1DD91D1C7E9FC90008F3C2 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = CoreData/Platform.h; sourceTree = ""; }; + EF1DD91E1C7E9FC90008F3C2 /* Platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Platform.m; path = CoreData/Platform.m; sourceTree = ""; }; + EF1DD91F1C7E9FC90008F3C2 /* Base+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Base+CoreDataProperties.h"; path = "CoreData/Base+CoreDataProperties.h"; sourceTree = ""; }; + EF1DD9201C7E9FC90008F3C2 /* Base+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Base+CoreDataProperties.m"; path = "CoreData/Base+CoreDataProperties.m"; sourceTree = ""; }; + EF1DD9211C7E9FC90008F3C2 /* Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Base.h; path = CoreData/Base.h; sourceTree = ""; }; + EF1DD9221C7E9FC90008F3C2 /* Base.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Base.m; path = CoreData/Base.m; sourceTree = ""; }; + EF1DD9251C7E9FC90008F3C2 /* Games.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Games.h; path = CoreData/Games.h; sourceTree = ""; }; + EF1DD9261C7E9FC90008F3C2 /* Games.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Games.m; path = CoreData/Games.m; sourceTree = ""; }; + EF62564B1CA4E9D000AC6DAF /* Games+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Games+CoreDataProperties.h"; path = "CoreData/Games+CoreDataProperties.h"; sourceTree = ""; }; + EF62564C1CA4E9D000AC6DAF /* Games+CoreDataProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Games+CoreDataProperties.m"; path = "CoreData/Games+CoreDataProperties.m"; sourceTree = ""; }; + EFF3C5971C746D820021C293 /* CoreData.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreData.xcdatamodel; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -216,6 +239,8 @@ 2DE3CDC81BEF7B9F00DA0F2E /* MJExtension */ = { isa = PBXGroup; children = ( + EF0A998F1C745504003176D4 /* NSManagedObject+MJCoreData.h */, + EF0A99901C745504003176D4 /* NSManagedObject+MJCoreData.m */, 2DE3CDCB1BEF7B9F00DA0F2E /* MJExtension.h */, 2DE3CDCC1BEF7B9F00DA0F2E /* MJExtensionConst.h */, 2DE3CDCD1BEF7B9F00DA0F2E /* MJExtensionConst.m */, @@ -244,6 +269,7 @@ 2DE3CDEB1BEF7BA400DA0F2E /* Classes */ = { isa = PBXGroup; children = ( + EFF3C5951C746D630021C293 /* CoreData */, 2D8FC6B91BEF8082004471E9 /* Other */, 2DE3CE0C1BEF7C2A00DA0F2E /* Main */, 2DE3CDEC1BEF7BD000DA0F2E /* Model */, @@ -289,6 +315,26 @@ name = Main; sourceTree = ""; }; + EFF3C5951C746D630021C293 /* CoreData */ = { + isa = PBXGroup; + children = ( + EFF3C5961C746D820021C293 /* CoreData.xcdatamodeld */, + EF1DD91B1C7E9FC90008F3C2 /* Platform+CoreDataProperties.h */, + EF1DD91C1C7E9FC90008F3C2 /* Platform+CoreDataProperties.m */, + EF1DD91D1C7E9FC90008F3C2 /* Platform.h */, + EF1DD91E1C7E9FC90008F3C2 /* Platform.m */, + EF1DD91F1C7E9FC90008F3C2 /* Base+CoreDataProperties.h */, + EF1DD9201C7E9FC90008F3C2 /* Base+CoreDataProperties.m */, + EF1DD9211C7E9FC90008F3C2 /* Base.h */, + EF1DD9221C7E9FC90008F3C2 /* Base.m */, + EF62564B1CA4E9D000AC6DAF /* Games+CoreDataProperties.h */, + EF62564C1CA4E9D000AC6DAF /* Games+CoreDataProperties.m */, + EF1DD9251C7E9FC90008F3C2 /* Games.h */, + EF1DD9261C7E9FC90008F3C2 /* Games.m */, + ); + name = CoreData; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -424,26 +470,34 @@ files = ( 2DE3CDE51BEF7B9F00DA0F2E /* MJPropertyType.m in Sources */, 2DE3CD9D1BEF7B3800DA0F2E /* ViewController.m in Sources */, + EF1DD9281C7E9FC90008F3C2 /* Platform.m in Sources */, 2DE3CE091BEF7BE100DA0F2E /* MJStudent.m in Sources */, 2DE3CE061BEF7BE100DA0F2E /* MJDog.m in Sources */, 2DE3CDE11BEF7B9F00DA0F2E /* MJExtensionConst.m in Sources */, 2DE3CE031BEF7BE100DA0F2E /* MJBaseObject.m in Sources */, 2DE3CDE61BEF7B9F00DA0F2E /* NSObject+MJClass.m in Sources */, + EF0A99911C745504003176D4 /* NSManagedObject+MJCoreData.m in Sources */, 2DE3CDE91BEF7B9F00DA0F2E /* NSObject+MJProperty.m in Sources */, + EF1DD92A1C7E9FC90008F3C2 /* Base.m in Sources */, 2DE3CE0A1BEF7BE100DA0F2E /* MJUser.m in Sources */, 2DE3CDE81BEF7B9F00DA0F2E /* NSObject+MJKeyValue.m in Sources */, 2DE3CDE31BEF7B9F00DA0F2E /* MJProperty.m in Sources */, + EF1DD9291C7E9FC90008F3C2 /* Base+CoreDataProperties.m in Sources */, + EF1DD92C1C7E9FC90008F3C2 /* Games.m in Sources */, 2DE3CE011BEF7BE100DA0F2E /* MJAd.m in Sources */, 2DE3CD9A1BEF7B3800DA0F2E /* AppDelegate.m in Sources */, 2DE3CE041BEF7BE100DA0F2E /* MJBook.m in Sources */, 2DE3CDE71BEF7B9F00DA0F2E /* NSObject+MJCoding.m in Sources */, + EFF3C5981C746D820021C293 /* CoreData.xcdatamodeld in Sources */, 2DE3CE071BEF7BE100DA0F2E /* MJStatus.m in Sources */, + EF1DD9271C7E9FC90008F3C2 /* Platform+CoreDataProperties.m in Sources */, 2DE3CE051BEF7BE100DA0F2E /* MJBox.m in Sources */, 2DE3CE021BEF7BE100DA0F2E /* MJBag.m in Sources */, 2DE3CE081BEF7BE100DA0F2E /* MJStatusResult.m in Sources */, 2DE3CDE21BEF7B9F00DA0F2E /* MJFoundation.m in Sources */, 2DE3CDEA1BEF7B9F00DA0F2E /* NSString+MJExtension.m in Sources */, 2DE3CD971BEF7B3800DA0F2E /* main.m in Sources */, + EF62564D1CA4E9D000AC6DAF /* Games+CoreDataProperties.m in Sources */, 2D8FC6B81BEF7E89004471E9 /* MJExtensionConfig.m in Sources */, 2DE3CDE41BEF7B9F00DA0F2E /* MJPropertyKey.m in Sources */, ); @@ -690,6 +744,19 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + EFF3C5961C746D820021C293 /* CoreData.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + EFF3C5971C746D820021C293 /* CoreData.xcdatamodel */, + ); + currentVersion = EFF3C5971C746D820021C293 /* CoreData.xcdatamodel */; + path = CoreData.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ }; rootObject = 2DE3CD8A1BEF7B3800DA0F2E /* Project object */; } diff --git a/MJExtensionExample/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents b/MJExtensionExample/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents new file mode 100644 index 00000000..f8f24a8a --- /dev/null +++ b/MJExtensionExample/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MJExtensionExample/CoreData/Base+CoreDataProperties.h b/MJExtensionExample/CoreData/Base+CoreDataProperties.h new file mode 100644 index 00000000..b1389992 --- /dev/null +++ b/MJExtensionExample/CoreData/Base+CoreDataProperties.h @@ -0,0 +1,22 @@ +// +// Base+CoreDataProperties.h +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Base.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Base (CoreDataProperties) + +@property (nullable, nonatomic, retain) NSString *objectId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MJExtensionExample/CoreData/Base+CoreDataProperties.m b/MJExtensionExample/CoreData/Base+CoreDataProperties.m new file mode 100644 index 00000000..239667a3 --- /dev/null +++ b/MJExtensionExample/CoreData/Base+CoreDataProperties.m @@ -0,0 +1,18 @@ +// +// Base+CoreDataProperties.m +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Base+CoreDataProperties.h" + +@implementation Base (CoreDataProperties) + +@dynamic objectId; + +@end diff --git a/MJExtensionExample/CoreData/Base.h b/MJExtensionExample/CoreData/Base.h new file mode 100644 index 00000000..04b889da --- /dev/null +++ b/MJExtensionExample/CoreData/Base.h @@ -0,0 +1,23 @@ +// +// Base.h +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import +#import +#import "MJExtension.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Base : NSManagedObject + +// Insert code here to declare functionality of your managed object subclass + +@end + +NS_ASSUME_NONNULL_END + +#import "Base+CoreDataProperties.h" diff --git a/MJExtensionExample/CoreData/Base.m b/MJExtensionExample/CoreData/Base.m new file mode 100644 index 00000000..6b95fcce --- /dev/null +++ b/MJExtensionExample/CoreData/Base.m @@ -0,0 +1,21 @@ +// +// Base.m +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import "Base.h" + +@implementation Base + ++ (NSMutableArray *)mj_identityPropertyNames { + return [NSMutableArray arrayWithObjects:@"objectId", nil]; +} + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + return @{@"objectId": @"id"}; +} + +@end diff --git a/MJExtensionExample/CoreData/Games+CoreDataProperties.h b/MJExtensionExample/CoreData/Games+CoreDataProperties.h new file mode 100644 index 00000000..64b3c056 --- /dev/null +++ b/MJExtensionExample/CoreData/Games+CoreDataProperties.h @@ -0,0 +1,24 @@ +// +// Games+CoreDataProperties.h +// MJExtensionExample +// +// Created by 陆晖 on 16/3/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Games.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Games (CoreDataProperties) + +@property (nullable, nonatomic, retain) NSString *name; +@property (nullable, nonatomic, retain) NSNumber *isHot; +@property (nullable, nonatomic, retain) Platform *platform; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MJExtensionExample/CoreData/Games+CoreDataProperties.m b/MJExtensionExample/CoreData/Games+CoreDataProperties.m new file mode 100644 index 00000000..4fa36df1 --- /dev/null +++ b/MJExtensionExample/CoreData/Games+CoreDataProperties.m @@ -0,0 +1,20 @@ +// +// Games+CoreDataProperties.m +// MJExtensionExample +// +// Created by 陆晖 on 16/3/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Games+CoreDataProperties.h" + +@implementation Games (CoreDataProperties) + +@dynamic name; +@dynamic isHot; +@dynamic platform; + +@end diff --git a/MJExtensionExample/CoreData/Games.h b/MJExtensionExample/CoreData/Games.h new file mode 100644 index 00000000..6d2b280c --- /dev/null +++ b/MJExtensionExample/CoreData/Games.h @@ -0,0 +1,25 @@ +// +// Games.h +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import +#import "Base.h" +#import "MJExtension.h" + +@class Platform; + +NS_ASSUME_NONNULL_BEGIN + +@interface Games : Base + +// Insert code here to declare functionality of your managed object subclass + +@end + +NS_ASSUME_NONNULL_END + +#import "Games+CoreDataProperties.h" diff --git a/MJExtensionExample/CoreData/Games.m b/MJExtensionExample/CoreData/Games.m new file mode 100644 index 00000000..e0b20766 --- /dev/null +++ b/MJExtensionExample/CoreData/Games.m @@ -0,0 +1,30 @@ +// +// Games.m +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import "Games.h" +#import "Platform.h" + +@implementation Games + +//+ (void)initialize { +// if (self == [Games class]) { +// [self mj_setupIdentityPropertyNames:^NSArray *{ +// return @[@"name"]; +// }]; +// } +//} + ++ (NSMutableArray *)mj_identityPropertyNames { + return @[@"name"].mutableCopy; +} + ++ (NSArray *)mj_ignoredJSONSerializaitonPropertyNames { + return [NSMutableArray arrayWithObjects:@"objectId", nil]; +} + +@end diff --git a/MJExtensionExample/CoreData/Platform+CoreDataProperties.h b/MJExtensionExample/CoreData/Platform+CoreDataProperties.h new file mode 100644 index 00000000..7885a380 --- /dev/null +++ b/MJExtensionExample/CoreData/Platform+CoreDataProperties.h @@ -0,0 +1,33 @@ +// +// Platform+CoreDataProperties.h +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Platform.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface Platform (CoreDataProperties) + +@property (nullable, nonatomic, retain) NSString *ignore; +@property (nullable, nonatomic, retain) NSString *name; +@property (nullable, nonatomic, retain) NSSet *games; + +@end + +@interface Platform (CoreDataGeneratedAccessors) + +- (void)addGamesObject:(Games *)value; +- (void)removeGamesObject:(Games *)value; +- (void)addGames:(NSSet *)values; +- (void)removeGames:(NSSet *)values; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MJExtensionExample/CoreData/Platform+CoreDataProperties.m b/MJExtensionExample/CoreData/Platform+CoreDataProperties.m new file mode 100644 index 00000000..e04b88de --- /dev/null +++ b/MJExtensionExample/CoreData/Platform+CoreDataProperties.m @@ -0,0 +1,20 @@ +// +// Platform+CoreDataProperties.m +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// +// Choose "Create NSManagedObject Subclass…" from the Core Data editor menu +// to delete and recreate this implementation file for your updated model. +// + +#import "Platform+CoreDataProperties.h" + +@implementation Platform (CoreDataProperties) + +@dynamic ignore; +@dynamic name; +@dynamic games; + +@end diff --git a/MJExtensionExample/CoreData/Platform.h b/MJExtensionExample/CoreData/Platform.h new file mode 100644 index 00000000..e275e222 --- /dev/null +++ b/MJExtensionExample/CoreData/Platform.h @@ -0,0 +1,25 @@ +// +// Platform.h +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import +#import "Base.h" +#import "MJExtension.h" + +@class Games; + +NS_ASSUME_NONNULL_BEGIN + +@interface Platform : Base + +// Insert code here to declare functionality of your managed object subclass + +@end + +NS_ASSUME_NONNULL_END + +#import "Platform+CoreDataProperties.h" diff --git a/MJExtensionExample/CoreData/Platform.m b/MJExtensionExample/CoreData/Platform.m new file mode 100644 index 00000000..e8f5ce96 --- /dev/null +++ b/MJExtensionExample/CoreData/Platform.m @@ -0,0 +1,30 @@ +// +// Platform.m +// MJExtensionExample +// +// Created by 陆晖 on 16/2/25. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import "Platform.h" +#import "Games.h" + +@implementation Platform + ++ (void)initialize { + if (self == [Platform class]) { + [self mj_setupObjectMappingPropertyNames:^NSArray *{ + return @[@"objectId", @"name", @"games"]; + }]; + + [self mj_setupJSONSerializationPropertyNames:^NSArray *{ + return @[@"name", @"games"]; + }]; + + [self mj_setupObjectClassInArray:^NSDictionary *{ + return @{@"games": [Games class]}; + }]; + } +} + +@end diff --git a/MJExtensionExample/MJStatusResult.h b/MJExtensionExample/MJStatusResult.h index 11398f7b..ba7c239f 100644 --- a/MJExtensionExample/MJStatusResult.h +++ b/MJExtensionExample/MJStatusResult.h @@ -10,9 +10,9 @@ @interface MJStatusResult : MJBaseObject /** 存放着某一页微博数据(里面都是Status模型) */ -@property (strong, nonatomic) NSMutableArray *statuses; -/** 存放着一堆的广告数据(里面都是MJAd模型) */ -@property (strong, nonatomic) NSArray *ads; +@property (strong, nonatomic) NSSet *statuses; +/** 存放着一堆的广告数据(里面都是Ad模型) */ +@property (strong, nonatomic) NSSet *ads; /** 总数 */ @property (strong, nonatomic) NSNumber *totalNumber; /** 上一页的游标 */ diff --git a/MJExtensionExample/main.h b/MJExtensionExample/main.h index 40d9cf38..e158d669 100644 --- a/MJExtensionExample/main.h +++ b/MJExtensionExample/main.h @@ -20,6 +20,7 @@ void keyValuesArray2objectArray(); void object2keyValues(); void objectArray2keyValuesArray(); void coreData(); +void coreData2(); void coding(); void replacedKeyFromPropertyName121(); void newValueFromOldValue(); diff --git a/MJExtensionExample/main.m b/MJExtensionExample/main.m index 6bb4bea7..91178cc5 100644 --- a/MJExtensionExample/main.m +++ b/MJExtensionExample/main.m @@ -19,6 +19,8 @@ #import "MJBook.h" #import "MJBox.h" #import +#import "Platform.h" +#import "Games.h" /** @@ -37,19 +39,20 @@ int main(int argc, char * argv[]) { // 关于模型的具体配置可以参考:MJExtensionConfig.m // 或者参考每个模型的.m文件中被注释掉的配置 - execute(keyValues2object, @"简单的字典 -> 模型"); - execute(keyValues2object1, @"JSON字符串 -> 模型"); - execute(keyValues2object2, @"复杂的字典 -> 模型 (模型里面包含了模型)"); - execute(keyValues2object3, @"复杂的字典 -> 模型 (模型的数组属性里面又装着模型)"); - execute(keyValues2object4, @"简单的字典 -> 模型(key替换,比如ID和id,支持多级映射)"); - execute(keyValuesArray2objectArray, @"字典数组 -> 模型数组"); - execute(object2keyValues, @"模型转字典"); - execute(objectArray2keyValuesArray, @"模型数组 -> 字典数组"); +// execute(keyValues2object, @"简单的字典 -> 模型"); +// execute(keyValues2object1, @"JSON字符串 -> 模型"); +// execute(keyValues2object2, @"复杂的字典 -> 模型 (模型里面包含了模型)"); +// execute(keyValues2object3, @"复杂的字典 -> 模型 (模型的数组属性里面又装着模型)"); +// execute(keyValues2object4, @"简单的字典 -> 模型(key替换,比如ID和id,支持多级映射)"); +// execute(keyValuesArray2objectArray, @"字典数组 -> 模型数组"); +// execute(object2keyValues, @"模型转字典"); +// execute(objectArray2keyValuesArray, @"模型数组 -> 字典数组"); execute(coreData, @"CoreData示例"); - execute(coding, @"NSCoding示例"); - execute(replacedKeyFromPropertyName121, @"统一转换属性名(比如驼峰转下划线)"); - execute(newValueFromOldValue, @"过滤字典的值(比如字符串日期处理为NSDate、字符串nil处理为@"")"); - execute(logAllProperties, @"使用MJExtensionLog打印模型的所有属性"); + execute(coreData2, @"双向CoreData示例"); +// execute(coding, @"NSCoding示例"); +// execute(replacedKeyFromPropertyName121, @"统一转换属性名(比如驼峰转下划线)"); +// execute(newValueFromOldValue, @"过滤字典的值(比如字符串日期处理为NSDate、字符串nil处理为@"")"); +// execute(logAllProperties, @"使用MJExtensionLog打印模型的所有属性"); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } @@ -330,29 +333,108 @@ void objectArray2keyValuesArray() MJExtensionLog(@"%@", dictArray); } +static NSManagedObjectContext *moc; + +void initializeCoreData() +{ + NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData" withExtension:@"momd"]; + NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; + + NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; + moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; + [moc setPersistentStoreCoordinator:psc]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; + NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"DataModel.sqlite"]; + + dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + NSError *error = nil; + NSPersistentStoreCoordinator *psc = [moc persistentStoreCoordinator]; + [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]; + }); +} + /** * CoreData示例 */ void coreData() { - NSDictionary *dict = @{ - @"name" : @"Jack", - @"icon" : @"lufy.png", - @"age" : @20, - @"height" : @1.55, - @"money" : @"100.9", - @"sex" : @(SexFemale), - @"gay" : @"true" - }; - - // 这个Demo仅仅提供思路,具体的方法参数需要自己创建 - NSManagedObjectContext *context = nil; - MJUser *user = [MJUser mj_objectWithKeyValues:dict context:context]; + NSArray *games = @[@{ + @"name": @"火影忍者", + @"id": @"1" + }, + @{ + @"name": @"海贼王", + @"id": @"2", + @"isHot": @YES + }]; + NSDictionary *platform = @{ + @"name": @"QQ", + @"id": @"QQ", + @"ignore": @"ignore", + @"games": games + }; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + initializeCoreData(); + }); + + [Platform mj_objectWithKeyValues:platform context:moc]; // 利用CoreData保存模型 - [context save:nil]; + [moc save:nil]; + + MJExtensionLog(@"第一次映射core data数据: %@", platform); + NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Platform"]; + NSArray *platforms = [moc executeFetchRequest:request error:nil]; + for (Platform *p in platforms) { + MJExtensionLog(@"platformJSON = %@", p.mj_JSONString); + for (Games *g in p.games) { + MJExtensionLog(@"gameJson = %@", g.mj_JSONString); + } + } - MJExtensionLog(@"name=%@, icon=%@, age=%zd, height=%f, money=%@, sex=%d, gay=%d", user.name, user.icon, user.age, user.height, user.money, user.sex, user.gay); + NSMutableDictionary *newPlatform = (NSMutableDictionary *)platform.mutableCopy; + [newPlatform setObject:@"wechat" forKey:@"name"]; + [Platform mj_objectWithKeyValues:newPlatform context:moc]; + + [moc save:nil]; + + platforms = [moc executeFetchRequest:request error:nil]; + MJExtensionLog(@"第二次映射core data数据: %@", newPlatform); + for (Platform *p in platforms) { + MJExtensionLog(@"platformJSON = %@", p.mj_JSONString); + for (Games *g in p.games) { + MJExtensionLog(@"gameJson = %@", g.mj_JSONString); + } + } +} + +/** + * CoreData示例 + */ +void coreData2() +{ + NSDictionary *games = @{ + @"name": @"海贼王*改", + @"id": @"2", + @"platform": @{@"id": @"QQ"} + }; + + [Games mj_objectWithKeyValues:games context:moc]; + + // 利用CoreData保存模型 + [moc save:nil]; + + MJExtensionLog(@"双向映射core data数据: %@", games); + NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Platform"]; + NSArray *platforms = [moc executeFetchRequest:request error:nil]; + for (Platform *p in platforms) { + MJExtensionLog(@"platformJSON = %@", p.mj_JSONString); + for (Games *g in p.games) { + MJExtensionLog(@"gameJson = %@", g.mj_JSONString); + } + } } /**