Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing PFObject in Swift

The Parse documentation for adding properties and methods on PFObject subclasses conveniently skips the Swift syntax in their sample code listing just the Objective-C syntax:

https://parse.com/docs/ios_guide#subclasses-properties/iOS

// Armor.h
@interface Armor : PFObject<PFSubclassing>
+ (NSString *)parseClassName;
@property (retain) NSString *displayName;
@end

// Armor.m
@dynamic displayName;

Has anyone figured out a work around for Swift's lack of dynamic synthesizers in order to implement properties and methods with PFSubclassing? I want to be able to do something like:

class Armor : PFObject, PFSubclassing {
    class func parseClassName() -> String! {
        return "Armor"
    }
}

var armor = Armor()
armor.displayName = "Iron Clad"
like image 303
user3806775 Avatar asked Jul 05 '14 00:07

user3806775


3 Answers

I had this same problem. Had to add @NSManaged to the properties I wanted saved:

class Armor : PFObject, PFSubclassing {
    @NSManaged var displayName: String

    class func parseClassName() -> String! {
        return "Armor"
    }
}

var armor = Armor.object()
armor.displayName = "Iron Clad"

Hopefully this is resolved in the next update.

like image 61
Prototypic Avatar answered Oct 16 '22 08:10

Prototypic


The solution is to use computed properties instead of stored properties:

class Armor : PFObject, PFSubclassing {

    var displayName: String? {
        get {
            return self["displayName"] as? String
        }
        set {
            self["displayName"] = newValue
        }
    }


    class func parseClassName() -> String {
        return "Armor"
    }
}
like image 44
Andrew Toth Avatar answered Oct 16 '22 08:10

Andrew Toth


Swift 1.2

First: Create a swift file and define the subclass. Don't forget to import Parse! (for example Armor)

import Foundation
import Parse


class Armor: PFObject, PFSubclassing {

    // MARK: - PFSubclassing

    override class func initialize() {
        struct Static {
            static var onceToken: dispatch_once_t = 0;
        }
        dispatch_once(&Static.onceToken) {
            self.registerSubclass()
        }
    }

    class func parseClassName() -> String {
        return "Armor"
    }


    // MARK: - Parse Core Properties

    @NSManaged var displayName: String?

}

Note: You can define your properties as optionals. Every "undefined" value inside the Parse Core Manager will be translated to "nil".

Second: Register all subclasses, inside your AppDelegate.swift.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    // MARK: - Parse Setup
    Parse.setApplicationId("YOUR_ID", clientKey: "YOUR_KEY")

    // MARK: - Parse Register Subclasses
    Armor.registerSubclass()

    return true
}
like image 6
user3378170 Avatar answered Oct 16 '22 07:10

user3378170