Skip to content

Commit 45952b4

Browse files
committed
Supporting array[index] replacedKey
You can use “other.info[1].name” key in replacedKeyForomPropertyName method
1 parent c06328a commit 45952b4

File tree

12 files changed

+210
-76
lines changed

12 files changed

+210
-76
lines changed

MJExtension.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "MJExtension"
3-
s.version = "2.3.8"
3+
s.version = "2.4.0"
44
s.ios.deployment_target = '6.0'
55
s.osx.deployment_target = '10.8'
66
s.summary = "The fastest and most convenient conversion between JSON and model"

MJExtension/MJProperty.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@
1010
#import <objc/runtime.h>
1111
#import "MJType.h"
1212

13+
typedef enum {
14+
MJPropertyKeyTypeDictionary = 0, // 字典的key
15+
MJPropertyKeyTypeArray // 数组的key
16+
} MJPropertyKeyType;
17+
/**
18+
* 属性的key
19+
*/
20+
@interface MJPropertyKey : NSObject
21+
@property (copy, nonatomic) NSString *name;
22+
@property (assign, nonatomic) MJPropertyKeyType type;
23+
/**
24+
* 根据当前的key从object(字典或者数组)中取值
25+
*/
26+
- (id)valueForObject:(id)object;
27+
@end
28+
1329
/**
1430
* 包装一个成员
1531
*/
@@ -27,10 +43,8 @@
2743
/**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/
2844
/** 对应着字典中的key */
2945
- (void)setKey:(NSString *)key forClass:(Class)c;
30-
- (NSString *)keyFromClass:(Class)c;
31-
3246
/** 对应着字典中的多级key */
33-
- (NSArray *)keysFromClass:(Class)c;
47+
- (NSArray *)propertyKeysFromClass:(Class)c;
3448

3549
/** 模型数组中的模型类型 */
3650
- (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c;

MJExtension/MJProperty.m

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,33 @@
1010
#import "MJFoundation.h"
1111
#import "MJConst.h"
1212

13+
@implementation MJPropertyKey
14+
15+
- (id)valueForObject:(id)object
16+
{
17+
if ([object isKindOfClass:[NSDictionary class]] && self.type == MJPropertyKeyTypeDictionary) {
18+
return object[self.name];
19+
} else if ([object isKindOfClass:[NSArray class]] && self.type == MJPropertyKeyTypeArray) {
20+
return object[self.name.intValue];
21+
}
22+
return nil;
23+
}
24+
25+
@end
26+
1327
@interface MJProperty()
14-
@property (strong, nonatomic) NSMutableDictionary *keyDict;
15-
@property (strong, nonatomic) NSMutableDictionary *keysDict;
28+
@property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
1629
@property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
1730
@end
1831

1932
@implementation MJProperty
2033

21-
- (NSMutableDictionary *)keyDict
22-
{
23-
if (!_keyDict) {
24-
self.keyDict = [NSMutableDictionary dictionary];
25-
}
26-
return _keyDict;
27-
}
28-
29-
- (NSMutableDictionary *)keysDict
34+
- (NSMutableDictionary *)propertyKeysDict
3035
{
31-
if (!_keysDict) {
32-
self.keysDict = [NSMutableDictionary dictionary];
36+
if (!_propertyKeysDict) {
37+
self.propertyKeysDict = [NSMutableDictionary dictionary];
3338
}
34-
return _keysDict;
39+
return _propertyKeysDict;
3540
}
3641

3742
- (NSMutableDictionary *)objectClassInArrayDict
@@ -91,24 +96,51 @@ - (void)setValue:(id)value forObject:(id)object
9196
- (void)setKey:(NSString *)key forClass:(Class)c
9297
{
9398
if (!key) return;
94-
self.keyDict[NSStringFromClass(c)] = key;
99+
95100
// 如果有多级映射
96-
[self setKeys:[key componentsSeparatedByString:@"."] forClass:c];
97-
}
98-
- (NSString *)keyFromClass:(Class)c
99-
{
100-
return self.keyDict[NSStringFromClass(c)];
101+
NSArray *oldKeys = [key componentsSeparatedByString:@"."];
102+
NSMutableArray *propertyKeys = [NSMutableArray array];
103+
104+
for (NSString *oldKey in oldKeys) {
105+
NSUInteger start = [oldKey rangeOfString:@"["].location;
106+
if (start != NSNotFound) { // 有索引的key
107+
NSString *prefixKey = [oldKey substringToIndex:start];
108+
if (prefixKey.length) {
109+
MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
110+
propertyKey.name = prefixKey;
111+
[propertyKeys addObject:propertyKey];
112+
}
113+
114+
/** 解析索引 **/
115+
// 去除前面的key,剩下数字
116+
NSString *indexKey = [oldKey stringByReplacingOccurrencesOfString:prefixKey withString:@""];
117+
118+
// 元素
119+
NSArray *cmps = [[indexKey stringByReplacingOccurrencesOfString:@"[" withString:@""] componentsSeparatedByString:@"]"];
120+
for (NSInteger i = 0; i<cmps.count - 1; i++) {
121+
MJPropertyKey *subPropertyKey = [[MJPropertyKey alloc] init];
122+
subPropertyKey.type = MJPropertyKeyTypeArray;
123+
subPropertyKey.name = cmps[i];
124+
[propertyKeys addObject:subPropertyKey];
125+
}
126+
} else { // 没有索引的key
127+
MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
128+
propertyKey.name = oldKey;
129+
[propertyKeys addObject:propertyKey];
130+
}
131+
}
132+
[self setPorpertyKeys:propertyKeys forClass:c];
101133
}
102134

103135
/** 对应着字典中的多级key */
104-
- (void)setKeys:(NSArray *)keys forClass:(Class)c
136+
- (void)setPorpertyKeys:(NSArray *)propertyKeys forClass:(Class)c
105137
{
106-
if (!keys) return;
107-
self.keysDict[NSStringFromClass(c)] = keys;
138+
if (!propertyKeys) return;
139+
self.propertyKeysDict[NSStringFromClass(c)] = propertyKeys;
108140
}
109-
- (NSArray *)keysFromClass:(Class)c
141+
- (NSArray *)propertyKeysFromClass:(Class)c
110142
{
111-
return self.keysDict[NSStringFromClass(c)];
143+
return self.propertyKeysDict[NSStringFromClass(c)];
112144
}
113145

114146
/** 模型数组中的模型类型 */

MJExtension/NSObject+MJKeyValue.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,18 @@
8383
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
8484
- (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
8585

86+
/** 是否在模型转字典时,忽略替换过的key */
87+
@property (nonatomic, assign, getter=isIgnoreReplacedKeyWhenGettingKeyValues) BOOL ignoreReplacedKeyWhenGettingKeyValues;
8688
/**
8789
* 将模型转成字典
8890
* @return 字典
8991
*/
90-
- (NSMutableDictionary *)keyValues;
91-
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys;
92-
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
93-
- (NSMutableDictionary *)keyValuesWithError:(NSError **)error;
94-
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error;
95-
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
92+
- (id)keyValues;
93+
- (id)keyValuesWithKeys:(NSArray *)keys;
94+
- (id)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
95+
- (id)keyValuesWithError:(NSError **)error;
96+
- (id)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error;
97+
- (id)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
9698

9799
/**
98100
* 通过模型数组来创建一个字典数组

MJExtension/NSObject+MJKeyValue.m

Lines changed: 96 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@
1515

1616
@implementation NSObject (MJKeyValue)
1717

18+
static const char MJIgnoreReplacedKeyWhenGettingKeyValuesKey = '\0';
19+
20+
- (void)setIgnoreReplacedKeyWhenGettingKeyValues:(BOOL)ignoreReplacedKeyWhenGettingKeyValues
21+
{
22+
objc_setAssociatedObject(self, &MJIgnoreReplacedKeyWhenGettingKeyValuesKey, @(ignoreReplacedKeyWhenGettingKeyValues), OBJC_ASSOCIATION_ASSIGN);
23+
}
24+
25+
- (BOOL)isIgnoreReplacedKeyWhenGettingKeyValues
26+
{
27+
return [objc_getAssociatedObject(self, &MJIgnoreReplacedKeyWhenGettingKeyValuesKey) boolValue];
28+
}
29+
1830
#pragma mark - --常用的对象--
1931
static NSNumberFormatter *_numberFormatter;
2032
+ (void)load
@@ -99,7 +111,7 @@ - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)con
99111
keyValues = [NSJSONSerialization JSONObjectWithData:keyValues options:kNilOptions error:nil];
100112
}
101113

102-
MJAssertError([keyValues isKindOfClass:[NSDictionary class]], self, error, @"keyValues参数不是一个字典");
114+
MJAssertError([keyValues isKindOfClass:[NSDictionary class]] || [keyValues isKindOfClass:[NSArray class]], self, error, @"keyValues参数不是一个字典或者数组");
103115

104116
@try {
105117
Class aClass = [self class];
@@ -114,10 +126,9 @@ - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)con
114126

115127
// 1.取出属性值
116128
id value = keyValues ;
117-
NSArray *keys = [property keysFromClass:[self class]];
118-
for (NSString *key in keys) {
119-
if (![value isKindOfClass:[NSDictionary class]]) continue;
120-
value = value[key];
129+
NSArray *propertyKeys = [property propertyKeysFromClass:[self class]];
130+
for (MJPropertyKey *propertyKey in propertyKeys) {
131+
value = [propertyKey valueForObject:value];
121132
}
122133

123134
// 值的过滤
@@ -259,42 +270,46 @@ + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError *__autor
259270
}
260271

261272
#pragma mark - 模型 -> 字典
262-
- (NSMutableDictionary *)keyValues
273+
- (id)keyValues
263274
{
264275
return [self keyValuesWithError:nil];
265276
}
266277

267-
- (NSMutableDictionary *)keyValuesWithError:(NSError *__autoreleasing *)error
278+
- (id)keyValuesWithError:(NSError *__autoreleasing *)error
268279
{
269280
return [self keyValuesWithIgnoredKeys:nil error:error];
270281
}
271282

272-
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys
283+
- (id)keyValuesWithKeys:(NSArray *)keys
273284
{
274285
return [self keyValuesWithKeys:keys error:nil];
275286
}
276287

277-
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys
288+
- (id)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys
278289
{
279290
return [self keyValuesWithIgnoredKeys:ignoredKeys error:nil];
280291
}
281292

282-
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError *__autoreleasing *)error
293+
- (id)keyValuesWithKeys:(NSArray *)keys error:(NSError *__autoreleasing *)error
283294
{
284295
return [self keyValuesWithKeys:keys ignoredKeys:nil error:error];
285296
}
286297

287-
- (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
298+
- (id)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
288299
{
289300
return [self keyValuesWithKeys:nil ignoredKeys:ignoredKeys error:error];
290301
}
291302

292-
- (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
303+
- (id)keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray *)ignoredKeys error:(NSError *__autoreleasing *)error
293304
{
294305
// 如果自己不是模型类
295306
if ([MJFoundation isClassFromFoundation:[self class]]) return (NSMutableDictionary *)self;
296307

297-
__block NSMutableDictionary *keyValues = [NSMutableDictionary dictionary];
308+
__block id keyValues = nil;
309+
310+
if (self.isIgnoreReplacedKeyWhenGettingKeyValues) {
311+
keyValues = [NSMutableDictionary dictionary];
312+
}
298313

299314
@try {
300315
Class aClass = [self class];
@@ -325,26 +340,78 @@ - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys ignoredKeys:(NSArray
325340
}
326341

327342
// 4.赋值
328-
NSArray *keys = [property keysFromClass:[self class]];
329-
NSUInteger keyCount = keys.count;
330-
// 创建字典
331-
__block NSMutableDictionary *innerDict = keyValues;
332-
[keys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
333-
if (idx == keyCount - 1) { // 最后一个属性
334-
innerDict[key] = value;
335-
} else { // 字典
336-
NSMutableDictionary *tempDict = innerDict[key];
337-
if (tempDict == nil) {
338-
tempDict = [NSMutableDictionary dictionary];
339-
innerDict[key] = tempDict;
343+
if (self.isIgnoreReplacedKeyWhenGettingKeyValues) {
344+
keyValues[property.name] = value;
345+
} else {
346+
NSArray *propertyKeys = [property propertyKeysFromClass:[self class]];
347+
NSUInteger keyCount = propertyKeys.count;
348+
// 创建字典
349+
__block id innerContainer = nil;
350+
[propertyKeys enumerateObjectsUsingBlock:^(MJPropertyKey *propertyKey, NSUInteger idx, BOOL *stop) {
351+
// 创建keyValues
352+
if (!keyValues) {
353+
if (propertyKey.type == MJPropertyKeyTypeDictionary) {
354+
keyValues = [NSMutableDictionary dictionary];
355+
} else {
356+
keyValues = [NSMutableArray array];
357+
}
340358
}
341-
innerDict = tempDict;
342-
}
343-
}];
359+
// 创建innerContainer
360+
if (!innerContainer) {
361+
innerContainer = keyValues;
362+
if ([innerContainer isKindOfClass:[NSMutableArray class]]) {
363+
int index = propertyKey.name.intValue;
364+
while ([innerContainer count] < index + 1) {
365+
[innerContainer addObject:[NSNull null]];
366+
}
367+
}
368+
}
369+
370+
// 下一个属性
371+
MJPropertyKey *nextPropertyKey = nil;
372+
if (idx != keyCount - 1) {
373+
nextPropertyKey = propertyKeys[idx + 1];
374+
}
375+
376+
if (nextPropertyKey) { // 不是最后一个key
377+
// 当前propertyKey对应的字典或者数组
378+
id tempInnerContainer = [propertyKey valueForObject:innerContainer];
379+
if (tempInnerContainer == nil || [tempInnerContainer isKindOfClass:[NSNull class]]) {
380+
if (nextPropertyKey.type == MJPropertyKeyTypeDictionary) {
381+
tempInnerContainer = [NSMutableDictionary dictionary];
382+
} else {
383+
tempInnerContainer = [NSMutableArray array];
384+
}
385+
if (propertyKey.type == MJPropertyKeyTypeDictionary) {
386+
innerContainer[propertyKey.name] = tempInnerContainer;
387+
} else {
388+
innerContainer[propertyKey.name.intValue] = tempInnerContainer;
389+
}
390+
}
391+
392+
if ([tempInnerContainer isKindOfClass:[NSMutableArray class]]) {
393+
int index = nextPropertyKey.name.intValue;
394+
while ([tempInnerContainer count] < index + 1) {
395+
[tempInnerContainer addObject:[NSNull null]];
396+
}
397+
}
398+
399+
innerContainer = tempInnerContainer;
400+
} else { // 最后一个key
401+
if (propertyKey.type == MJPropertyKeyTypeDictionary) {
402+
innerContainer[propertyKey.name] = value;
403+
} else {
404+
innerContainer[propertyKey.name.intValue] = value;
405+
}
406+
}
407+
}];
408+
}
344409
}];
345410

346411
// 去除系统自动增加的元素
347-
[keyValues removeObjectsForKeys:@[@"superclass", @"debugDescription", @"description", @"hash"]];
412+
if ([keyValues isKindOfClass:[NSMutableDictionary class]]) {
413+
[keyValues removeObjectsForKeys:@[@"superclass", @"debugDescription", @"description", @"hash"]];
414+
}
348415

349416
// 转换完毕
350417
if ([self respondsToSelector:@selector(objectDidFinishConvertingToKeyValues)]) {

MJExtension/NSString+MJExtension.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@
2525
* 首字母变小写
2626
*/
2727
- (NSString *)firstCharLower;
28+
29+
- (BOOL)isPureInt;
2830
@end

MJExtension/NSString+MJExtension.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,11 @@ - (NSString *)firstCharUpper
6161
if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
6262
return string;
6363
}
64+
65+
- (BOOL)isPureInt
66+
{
67+
NSScanner *scan = [NSScanner scannerWithString:self];
68+
int val;
69+
return [scan scanInt:&val] && [scan isAtEnd];
70+
}
6471
@end

MJExtensionExample/MJExtensionExample/Classes/MJExtensionConfig.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ + (void)load
6060
@"desc" : @"desciption",
6161
@"oldName" : @"name.oldName",
6262
@"nowName" : @"name.newName",
63-
@"nameChangedTime" : @"name.info.nameChangedTime",
63+
@"nameChangedTime" : @"name.info[1].nameChangedTime",
6464
@"bag" : @"other.bag"
6565
};
6666
}];

0 commit comments

Comments
 (0)