CocoaPods trunk is moving to be read-only. Read more on the blog, there are 17 months to go.
TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | Custom |
ReleasedLast Release | Dec 2014 |
Maintained by Chris Constable.
Hassel-free data models for the Parse iOS SDK.
The ParseModel
class automatically maps the properties of your subclass to entries in an underlying PFObject
and handles any neccesary conversions (e.g. if your property is an int
it is converted to an NSNumber
for storage).
via CocoaPods: pod 'ParseModel'
The Parse iOS SDK, as of March 2013, has this functionality built in. Check out this blog post for more info. Regardless, this repo has been helpful for me and I will continute to add features to it if they are not found in the native Parse iOS SDK.
Parse is a cloud backend as-a-service (or BaaS) that allows developers to quickly get their apps up and running with little or no backend setup.
More often than not, we developers like to work with out own classes and not use the out-of-the-box data models that come with many of these services. Regardless of our approach there comes a time when we need to map the properties of our objects to the backend object. Sometimes we accomplish this by overriding the getters and setters of our properties like this:
@interface MyObject : NSObject
@property (nonatomic, strong) NSString *someString;
@property (nonatomic, strong) PFObject *parseObject;
@end
@implementation MyObject
- (NSString *)someString
{
return [self.parseObject objectForKey:kSomeStringKey];
}
- (NSString *)setSomeString:(NSString *)someString
{
[self.parseObject setObject:someString forKey:kSomeStringKey];
}
@end
The benefits to this approach is that we can define an Objective-C protocol
to house these properties and have our model objects conform to this protocol:
@interface MyObject : NSObject <MyObjectProtocol>
@property (nonatomic, strong) PFObject *parseObject;
@end
Now in our app code, we can just deal with id<MyObjectProtocol>
pointers instead of worrying about specifics. The benefits of this are pretty obvious…
Setting up models like this, however, can be time consuming. Nobody likes typing out getters/setters, creating lots of static keys, etc.
This is where ParseModel comes in.
Parse Model was based off an idea from CouchCocoa where to create a model object all you would need to do is create some properties
and set them as dynamic
. That's it. In our case, all of our properties
get mapped to an underlying PFObject
as values with the same key.
Here's an example:
@interface MyObject : ParseModel
@property (nonatomic, strong) NSString *someString;
@property (nonatomic, strong) NSString *someOtherString;
@end
@implementation MyObject
@dynamic someString;
@dynamic someOtherString;
+ (NSString *)parseModelClass
{
return @"MyObject";
}
@end
Afer declaring the MyObject
class above we can do things like this:
MyObject *myObject = [MyObject parseModel];
myObject.someString = @"Hello there";
[myObject.parseObject saveInBackground];
When someString
is set it is automatically mapped to the underlying PFObject
.
Lastly, you can created models with existing the following method:
+ (id)modelWithParseObject:(PFObject *)parseObject;
A PFUser
flavored object is also available called ParseModelUser
.
ParseModel currently works with all types that PFObject
supports. This means don't try using a UIImage and expect it to work! If you need to store UIImage data (or something that is unsupported) you have a few alternatives:
First off, let me say that this probably wouldn't have happened if it wasn't for Jens Alfke. He wrote almost all of this code. I simply adapted it for Parse. Most of the code was pulled from his CouchModel class.
Under the hood, when a property is accessed that has not been created (because of the dynamic
keyword in our case), we catch a last-ditch message to our class that says: "Hey, we couldn't find this instance method". If we can detect that it is a setter or getter method for a property that was declared as dynamic, we then create the getter/setter on the fly using a pre-defined block of code that uses a PFObject
to store/retrieve the values. That's the gist. Check out Dynamic Method Resolution for more information.
The original code Jens wrote was released under the Apache license, version 2.0.