Skip to content

Commit 2fc003a

Browse files
committed
ParseModel now unboxes/boxes NSURL (to NSString) and CLLocation (to PFGeoPoint) out of the box (no pun intended).
1 parent b33646a commit 2fc003a

File tree

5 files changed

+47
-83
lines changed

5 files changed

+47
-83
lines changed

ParseModel-iOS-Demo/ParseModel-iOS-Demo/AppDelegate.m

+6
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
2727
// Create a new object and save it to our Parse account.
2828
TestObject *testObject = [TestObject parseModel];
2929
testObject.someString = @"Hello there";
30+
testObject.someUrl = [NSURL URLWithString:@"http://parse.com"];
3031
testObject.anInteger = 1255389;
3132
testObject.aDate = [NSDate date];
33+
testObject.location = [[CLLocation alloc] initWithLatitude:24.0 longitude:-80.0];
34+
35+
// Try getting back values we've stored...
36+
NSURL *url = testObject.someUrl;
37+
NSLog(@"Got url: %@", [url absoluteString]);
3238

3339
// The underlying parse objects are exposed so you can save
3440
// however you'd like.

ParseModel-iOS-Demo/ParseModel-iOS-Demo/TestObject.h

+3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
//
88

99
#import "ParseModel.h"
10+
#import <CoreLocation/CoreLocation.h>
1011

1112
@interface TestObject : ParseModel
1213

1314
// Simply declare your properties like usual...
1415
@property (nonatomic, strong) NSString *someString;
1516
@property (nonatomic, strong) NSString *someOtherString;
17+
@property (nonatomic, strong) NSURL *someUrl;
1618
@property (nonatomic) NSInteger anInteger;
1719
@property (nonatomic, strong) NSDate *aDate;
20+
@property (nonatomic, strong) CLLocation *location;
1821

1922
@end

ParseModel-iOS-Demo/ParseModel-iOS-Demo/TestObject.m

+2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ @implementation TestObject
1414
// PFObject as dynamic!
1515
@dynamic someString;
1616
@dynamic someOtherString;
17+
@dynamic someUrl;
1718
@dynamic anInteger;
1819
@dynamic aDate;
20+
@dynamic location;
1921

2022
// When you "init" your object, this string is used to initialize
2123
// the PFObject.

ParseModel/ParseModel.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ - (id)initWithParseObject:(PFObject *)parseObject
5252

5353
- (id)getValueOfProperty:(NSString *)property
5454
{
55-
return [self.parseObject objectForKey: property];
55+
return [self.parseObject objectForKey:property];
5656
}
5757

5858
- (BOOL)setValue:(id)value ofProperty:(NSString *)property

ParseModel/ParseModelBase.m

+35-82
Original file line numberDiff line numberDiff line change
@@ -89,55 +89,12 @@ + (NSString*) setterKey: (SEL)sel {return setterKey(sel);}
8989

9090
#pragma mark - GENERIC ACCESSOR METHOD IMPS:
9191

92-
93-
#if USE_BLOCKS
94-
9592
static inline void setIdProperty(ParseModelBase *self, NSString* property, id value) {
9693
// TODO: Add support for UIImage
9794
BOOL result = [self setValue: value ofProperty: property];
9895
NSCAssert(result, @"Property %@.%@ is not settable", [self class], property);
9996
}
10097

101-
#else
102-
103-
static id getIdProperty(CouchDynamicObject *self, SEL _cmd) {
104-
return [self getValueOfProperty: getterKey(_cmd)];
105-
}
106-
107-
static void setIdProperty(CouchDynamicObject *self, SEL _cmd, id value) {
108-
NSString* property = setterKey(_cmd);
109-
BOOL result = [self setValue: value ofProperty: property];
110-
NSCAssert(result, @"Property %@.%@ is not settable", [self class], property);
111-
}
112-
113-
static int getIntProperty(CouchDynamicObject *self, SEL _cmd) {
114-
return [getIdProperty(self,_cmd) intValue];
115-
}
116-
117-
static void setIntProperty(CouchDynamicObject *self, SEL _cmd, int value) {
118-
setIdProperty(self, _cmd, [NSNumber numberWithInt:value]);
119-
}
120-
121-
static bool getBoolProperty(CouchDynamicObject *self, SEL _cmd) {
122-
return [getIdProperty(self,_cmd) boolValue];
123-
}
124-
125-
static void setBoolProperty(CouchDynamicObject *self, SEL _cmd, bool value) {
126-
setIdProperty(self, _cmd, [NSNumber numberWithBool:value]);
127-
}
128-
129-
static double getDoubleProperty(CouchDynamicObject *self, SEL _cmd) {
130-
id number = getIdProperty(self,_cmd);
131-
return number ?[number doubleValue] :0.0;
132-
}
133-
134-
static void setDoubleProperty(CouchDynamicObject *self, SEL _cmd, double value) {
135-
setIdProperty(self, _cmd, [NSNumber numberWithDouble:value]);
136-
}
137-
138-
#endif // USE_BLOCKS
139-
140-
14198
#pragma mark - PROPERTY INTROSPECTION:
14299

143100

@@ -247,67 +204,75 @@ + (Class) classOfProperty: (NSString*)propertyName {
247204
return classFromType(propertyType);
248205
}
249206

207+
+ (id)performBoxingIfNecessary:(id)object
208+
{
209+
id boxedObject = object;
210+
if ([object isKindOfClass:[CLLocation class]]) {
211+
boxedObject = [PFGeoPoint geoPointWithLocation:object];
212+
}
213+
else if([object isKindOfClass:[NSURL class]]) {
214+
boxedObject = [(NSURL *)object absoluteString];
215+
}
216+
217+
return boxedObject;
218+
}
250219

251-
+ (IMP) impForGetterOfProperty: (NSString*)property ofClass: (Class)propertyClass {
252-
#if USE_BLOCKS
220+
+ (id)performUnboxingIfNecessary:(id)object targetClass:(Class)targetClass
221+
{
222+
id unboxedObject = object;
223+
if ((targetClass == [CLLocation class]) && [object isKindOfClass:[PFGeoPoint class]]) {
224+
unboxedObject = [[CLLocation alloc] initWithLatitude:[(PFGeoPoint *)object latitude] longitude:[(PFGeoPoint *)object longitude]];
225+
}
226+
else if((targetClass == [NSURL class]) && [object isKindOfClass:[NSString class]]) {
227+
unboxedObject = [NSURL URLWithString:object];
228+
}
229+
230+
return unboxedObject;
231+
}
232+
233+
+ (IMP)impForGetterOfProperty:(NSString *)property ofClass:(Class)propertyClass {
253234
return imp_implementationWithBlock(^id(ParseModelBase* receiver) {
254-
return [receiver getValueOfProperty: property];
235+
id object = [receiver getValueOfProperty:property];
236+
object = [ParseModelBase performUnboxingIfNecessary:object targetClass:propertyClass];
237+
return object;
255238
});
256-
#else
257-
return (IMP)getIdProperty;
258-
#endif
259239
}
260240

261-
+ (IMP) impForSetterOfProperty: (NSString*)property ofClass: (Class)propertyClass {
262-
#if USE_BLOCKS
241+
+ (IMP)impForSetterOfProperty:(NSString *)property ofClass:(Class)propertyClass {
263242
return imp_implementationWithBlock(^(ParseModelBase* receiver, id value) {
264-
setIdProperty(receiver, property, value);
243+
id boxedValue = [ParseModelBase performBoxingIfNecessary:value];
244+
setIdProperty(receiver, property, boxedValue);
265245
});
266-
#else
267-
return (IMP)setIdProperty;
268-
#endif
269246
}
270247

271248

272-
+ (IMP) impForGetterOfProperty: (NSString*)property ofType: (const char*)propertyType {
249+
+ (IMP)impForGetterOfProperty:(NSString*)property ofType:(const char *)propertyType {
273250
switch (propertyType[0]) {
274251
case _C_ID:
275-
return [self impForGetterOfProperty: property ofClass: classFromType(propertyType)];
252+
return [self impForGetterOfProperty:property ofClass:classFromType(propertyType)];
276253
case _C_INT:
277254
case _C_SHT:
278255
case _C_USHT:
279256
case _C_CHR:
280257
case _C_UCHR:
281-
#if USE_BLOCKS
282258
return imp_implementationWithBlock(^int(ParseModelBase* receiver) {
283259
return [[receiver getValueOfProperty: property] intValue];
284260
});
285-
#else
286-
return (IMP)getIntProperty;
287-
#endif
288261
case _C_BOOL:
289-
#if USE_BLOCKS
290262
return imp_implementationWithBlock(^bool(ParseModelBase* receiver) {
291263
return [[receiver getValueOfProperty: property] boolValue];
292264
});
293-
#else
294-
return (IMP)getBoolProperty;
295-
#endif
296265
case _C_DBL:
297-
#if USE_BLOCKS
298266
return imp_implementationWithBlock(^double(ParseModelBase* receiver) {
299267
return [[receiver getValueOfProperty: property] doubleValue];
300268
});
301-
#else
302-
return (IMP)getDoubleProperty;
303-
#endif
304269
default:
305270
// TODO: handle more scalar property types.
306271
return NULL;
307272
}
308273
}
309274

310-
+ (IMP) impForSetterOfProperty: (NSString*)property ofType: (const char*)propertyType {
275+
+ (IMP)impForSetterOfProperty:(NSString*)property ofType:(const char *)propertyType {
311276
switch (propertyType[0]) {
312277
case _C_ID:
313278
return [self impForSetterOfProperty: property ofClass: classFromType(propertyType)];
@@ -316,29 +281,17 @@ + (IMP) impForSetterOfProperty: (NSString*)property ofType: (const char*)propert
316281
case _C_USHT:
317282
case _C_CHR: // Note that "BOOL" is a typedef so it compiles to 'char'
318283
case _C_UCHR:
319-
#if USE_BLOCKS
320284
return imp_implementationWithBlock(^(ParseModelBase* receiver, int value) {
321285
setIdProperty(receiver, property, [NSNumber numberWithInt: value]);
322286
});
323-
#else
324-
return (IMP)setIntProperty;
325-
#endif
326287
case _C_BOOL: // This is the true native C99/C++ "bool" type
327-
#if USE_BLOCKS
328288
return imp_implementationWithBlock(^(ParseModelBase* receiver, bool value) {
329289
setIdProperty(receiver, property, [NSNumber numberWithBool: value]);
330290
});
331-
#else
332-
return (IMP)setBoolProperty;
333-
#endif
334291
case _C_DBL:
335-
#if USE_BLOCKS
336292
return imp_implementationWithBlock(^(ParseModelBase* receiver, double value) {
337293
setIdProperty(receiver, property, [NSNumber numberWithDouble: value]);
338294
});
339-
#else
340-
return (IMP)setDoubleProperty;
341-
#endif
342295
default:
343296
// TODO: handle more scalar property types.
344297
return NULL;

0 commit comments

Comments
 (0)