Skip to content

Instantly share code, notes, and snippets.

@moflo
Created March 21, 2016 15:57
Show Gist options
  • Save moflo/204d63a5e98f64547226 to your computer and use it in GitHub Desktop.
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
//
// 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