Created
March 21, 2016 15:57
-
-
Save moflo/204d63a5e98f64547226 to your computer and use it in GitHub Desktop.
ORM to map Parse PFObject to native Swift 2.0 class structure, allowing easier migration from CoreData
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ParseORM.swift | |
// | |
// Copyright © 2016 Mobile Flow LLC. All rights reserved. | |
// | |
import UIKit | |
import Parse | |
class ParseORM : NSObject { | |
var class_name: String | |
var uuid: String | |
var createdAt : NSDate | |
var parseObj: PFObject? = nil | |
override init() { | |
self.uuid = NSUUID().UUIDString | |
self.class_name = String(self.dynamicType) | |
self.createdAt = NSDate() | |
} | |
// Initialize object with Parse object | |
required convenience init(newParseObj:PFObject){ | |
self.init() | |
self.parseObj = newParseObj | |
let newUUID = newParseObj["uuid"] | |
self.uuid = String(newUUID) | |
let newCreatedAt = newParseObj["createdAt"] as? NSDate | |
self.createdAt = newCreatedAt ?? NSDate() | |
self.parseObj!.pinInBackground() | |
for keyName in self.props() { | |
let keyValue = self.parseObj![keyName] | |
if keyValue == nil || keyValue is NSNull { break } // If nil or NSNull, skip | |
if !(keyValue is PFObject) { | |
// If property exists | |
if (self.respondsToSelector(NSSelectorFromString(keyName))) { | |
self.setValue(keyValue, forKey: keyName) | |
} | |
} | |
else { | |
print(keyValue) | |
} | |
} | |
} | |
func save() { | |
// Synchronous save method | |
if self.parseObj == nil { | |
self.parseObj = PFObject(className: self.class_name) | |
self.parseObj!["uuid"] = self.uuid | |
self.parseObj!["createdAt"] = self.createdAt | |
self.parseObj!.pinInBackground() | |
} | |
for keyName in self.props() { | |
// If property exists | |
if (self.respondsToSelector(NSSelectorFromString(keyName))) { | |
var valueObj = self.valueForKey(keyName) | |
if valueObj == nil || valueObj is NSNull { valueObj = NSNull() } | |
if valueObj is ParseORM { | |
valueObj = valueObj?.parseObj | |
} | |
self.parseObj!.setValue(valueObj, forKey: keyName) | |
} | |
} | |
} | |
class func fetchAll() -> [ParseORM] { | |
let query = PFQuery(className: String(self)) | |
query.fromLocalDatastore() | |
query.orderByDescending("createdAt") | |
let results = try! query.findObjects() | |
var objects = [ParseORM]() | |
for obj in results { | |
let nativeObj = self.init(newParseObj: obj) | |
objects.append(nativeObj) | |
} | |
return objects | |
} | |
class func fetchAllInBackground( completionHandler: ([ParseORM]?, NSError?) -> () ) { | |
let query = PFQuery(className: String(self)) | |
query.fromLocalDatastore() | |
query.orderByDescending("createdAt") | |
query.findObjectsInBackgroundWithBlock { (results: [PFObject]?, error: NSError?) -> Void in | |
guard error != nil else { completionHandler(nil, error); return } | |
guard results != nil else { completionHandler(nil, nil); return } | |
var objects = [ParseORM]() | |
for obj in results! { | |
let nativeObj = self.init(newParseObj: obj) | |
objects.append(nativeObj) | |
} | |
completionHandler(objects,nil) | |
} | |
} | |
// Utilities | |
// Method to determine the properties of a given subclass | |
func props()->[String]{ | |
var s = [String]() | |
for c in Mirror(reflecting: self).children | |
{ | |
if let name = c.label{ | |
s.append(name) | |
} | |
} | |
return s | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment