Skip to content

Commit 6dfd38b

Browse files
committed
ParseModel can now handle ParseModel objects inside arrays and dicts. ParseModel objects must now register themselves before use.
1 parent b68e68d commit 6dfd38b

File tree

5 files changed

+82
-16
lines changed

5 files changed

+82
-16
lines changed

ParseModel/ParseModel.h

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
/** This needs to be overriden if you are going to create new models. */
2020
+ (NSString *)parseModelClass;
2121

22+
+ (void)registerParseModel;
23+
2224
+ (instancetype)parseModelWithParseObject:(PFObject *)parseObject;
2325

2426
- (id)initWithParseObject:(PFObject *)parseObject;

ParseModel/ParseModel.m

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#import <Parse/Parse.h>
1111
#import "ParseModel.h"
1212
#import "ParseModelUser.h"
13+
#import "ParseModelUtils.h"
1314

1415
@implementation ParseModel
1516

@@ -31,6 +32,12 @@ + (instancetype)parseModel
3132
return [[[self class] alloc] init];
3233
}
3334

35+
+ (void)registerParseModel
36+
{
37+
[[[ParseModelUtils sharedUtilities] registeredParseModels] setObject:[self parseModelClass]
38+
forKey:NSStringFromClass([self class])];
39+
}
40+
3441
- (id)init
3542
{
3643
self = [super init];

ParseModel/ParseModelBase.m

+4-12
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,16 @@ - (BOOL)setValue:(id)value ofProperty:(NSString *)property
5252

5353
- (id)performBoxingIfNecessary:(id)object
5454
{
55-
return [ParseModelUtils performBoxingIfNecessary:object];
55+
return [[ParseModelUtils sharedUtilities] performBoxingIfNecessary:object];
5656
}
5757

5858
- (id)performUnboxingIfNecessary:(id)object targetClass:(Class)targetClass
5959
{
60-
return [ParseModelUtils performUnboxingIfNecessary:object targetClass:targetClass];
60+
return [[ParseModelUtils sharedUtilities] performUnboxingIfNecessary:object targetClass:targetClass];
6161
}
6262

6363
#pragma mark - SELECTOR-TO-PROPERTY NAME MAPPING:
6464

65-
6665
NS_INLINE BOOL isGetter(const char* name) {
6766
if (!name[0] || name[0]=='_' || name[strlen(name)-1] == ':')
6867
return NO; // If it has parameters it's not a getter
@@ -96,8 +95,6 @@ NS_INLINE BOOL isSetter(const char* name) {
9695
+ (NSString*) getterKey: (SEL)sel {return getterKey(sel);}
9796
+ (NSString*) setterKey: (SEL)sel {return setterKey(sel);}
9897

99-
100-
10198
#pragma mark - GENERIC ACCESSOR METHOD IMPS:
10299

103100
static inline void setIdProperty(ParseModelBase *self, NSString* property, id value) {
@@ -107,7 +104,6 @@ static inline void setIdProperty(ParseModelBase *self, NSString* property, id va
107104

108105
#pragma mark - PROPERTY INTROSPECTION:
109106

110-
111107
+ (NSSet*) propertyNames {
112108
static NSMutableDictionary* classToNames;
113109
if (!classToNames)
@@ -160,7 +156,6 @@ + (NSSet*) propertyNames {
160156
return result;
161157
}
162158

163-
164159
// Look up a class's property by name, and find its type and which class declared it
165160
static BOOL getPropertyInfo(Class cls,
166161
NSString *propertyName,
@@ -195,7 +190,6 @@ static BOOL getPropertyInfo(Class cls,
195190
return YES;
196191
}
197192

198-
199193
static Class classFromType(const char* propertyType) {
200194
size_t len = strlen(propertyType);
201195
if (propertyType[0] != _C_ID || propertyType[1] != '"' || propertyType[len-1] != '"')
@@ -205,7 +199,6 @@ static Class classFromType(const char* propertyType) {
205199
return objc_getClass(className);
206200
}
207201

208-
209202
+ (Class) classOfProperty: (NSString*)propertyName {
210203
Class declaredInClass;
211204
const char* propertyType;
@@ -229,7 +222,6 @@ + (IMP)impForSetterOfProperty:(NSString *)property ofClass:(Class)propertyClass
229222
});
230223
}
231224

232-
233225
+ (IMP)impForGetterOfProperty:(NSString*)property ofType:(const char *)propertyType {
234226
switch (propertyType[0]) {
235227
case _C_ID:
@@ -322,9 +314,9 @@ + (BOOL)resolveInstanceMethod:(SEL)sel {
322314
else {
323315
return NO;
324316
}
325-
317+
318+
// Create dynamic property method
326319
if (accessor) {
327-
// NSLog(@"Creating dynamic accessor method -[%@ %s]", declaredInClass, selectorName);
328320
class_addMethod(declaredInClass, sel, accessor, signature);
329321
return YES;
330322
}

ParseModel/ParseModelUtils.h

+12-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@
1010

1111
@interface ParseModelUtils : NSObject
1212

13+
/**
14+
Registered Parse Models help Parse Model know what kind of class to instantiate
15+
when doing things like unboxing array/dictionary values from the backend.
16+
Registering your Parse Models on start-up is highly recommended. If you don't,
17+
bad things may happen.
18+
*/
19+
@property (nonatomic, strong) NSMutableDictionary *registeredParseModels;
20+
21+
+ (instancetype)sharedUtilities;
22+
1323
// Generic boxing/unboxing methods.
14-
+ (id)performBoxingIfNecessary:(id)object;
15-
+ (id)performUnboxingIfNecessary:(id)object
24+
- (id)performBoxingIfNecessary:(id)object;
25+
- (id)performUnboxingIfNecessary:(id)object
1626
targetClass:(Class)targetClass;
1727

1828
@end

ParseModel/ParseModelUtils.m

+57-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,21 @@
1414

1515
@implementation ParseModelUtils
1616

17-
+ (id)performBoxingIfNecessary:(id)object
17+
+ (instancetype)sharedUtilities
18+
{
19+
static dispatch_once_t onceToken;
20+
static ParseModelUtils *parseModelUtils;
21+
22+
if (!parseModelUtils) {
23+
dispatch_once(&onceToken, ^{
24+
parseModelUtils = [[ParseModelUtils alloc] init];
25+
});
26+
}
27+
28+
return parseModelUtils;
29+
}
30+
31+
- (id)performBoxingIfNecessary:(id)object
1832
{
1933
id boxedObject = object;
2034

@@ -31,10 +45,30 @@ + (id)performBoxingIfNecessary:(id)object
3145
boxedObject = [(ParseModelUser *)object parseUser];
3246
}
3347

48+
// Let's get recursive
49+
// Handle arrays and dictionaries...
50+
else if ([object isKindOfClass:[NSArray class]]) {
51+
NSMutableArray *boxedArray = [NSMutableArray array];
52+
for (id interalObject in object) {
53+
[boxedArray addObject:[[ParseModelUtils sharedUtilities] performBoxingIfNecessary:interalObject]];
54+
}
55+
boxedObject = boxedArray;
56+
}
57+
else if ([object isKindOfClass:[NSDictionary class]]) {
58+
NSMutableDictionary *boxedDictionary = [NSMutableDictionary dictionary];
59+
NSArray *keys = [object allKeys];
60+
for (id key in keys) {
61+
id boxedKey = [[ParseModelUtils sharedUtilities] performBoxingIfNecessary:key];
62+
id boxedValue = [[ParseModelUtils sharedUtilities] performBoxingIfNecessary:[object objectForKey:key]];
63+
[boxedDictionary setObject:boxedValue forKey:boxedKey];
64+
}
65+
boxedObject = boxedDictionary;
66+
}
67+
3468
return boxedObject;
3569
}
3670

37-
+ (id)performUnboxingIfNecessary:(id)object targetClass:(Class)targetClass
71+
- (id)performUnboxingIfNecessary:(id)object targetClass:(Class)targetClass
3872
{
3973
id unboxedObject = object;
4074

@@ -51,6 +85,27 @@ + (id)performUnboxingIfNecessary:(id)object targetClass:(Class)targetClass
5185
unboxedObject = [((ParseModelUser *)[targetClass alloc]) initWithParseUser:object];
5286
}
5387

88+
// Let's get recursive
89+
// Handle arrays and dictionaries...
90+
else if ([targetClass isKindOfClass:[NSArray class]]) {
91+
NSMutableArray *unboxedArray = [NSMutableArray array];
92+
for (id interalObject in object) {
93+
[unboxedArray addObject:[[ParseModelUtils sharedUtilities] performUnboxingIfNecessary:object targetClass:targetClass]];
94+
}
95+
unboxedObject = unboxedArray;
96+
}
97+
else if ([targetClass isKindOfClass:[NSDictionary class]]) {
98+
NSMutableDictionary *unboxedDictionary = [NSMutableDictionary dictionary];
99+
NSArray *keys = [object allKeys];
100+
for (id key in keys) {
101+
id unboxedKey = [[ParseModelUtils sharedUtilities] performUnboxingIfNecessary:key targetClass:[key class]];
102+
id unboxedValue = [[ParseModelUtils sharedUtilities] performUnboxingIfNecessary:[object objectForKey:key]
103+
targetClass:[[object objectForKey:key] class]];
104+
[unboxedDictionary setObject:unboxedValue forKey:unboxedKey];
105+
}
106+
unboxedObject = unboxedDictionary;
107+
}
108+
54109
return unboxedObject;
55110
}
56111

0 commit comments

Comments
 (0)