I am trying to subclass PFUser in Parse on iOS. I can create a subclass, using the following code:
// MyUser.h
#import <Parse/PFUser.h>
#import <Parse/PFObject+Subclass.h>
#import <Parse/PFFile.h>
@interface MyUser : PFUser<PFSubclassing>
@property PFFile *avatar;
...etc...
@end
// MyUser.m
#import "MyUser.h"
@implementation MyUser
@dynamic avatar;
...etc...
@end
When I call [MyUser currentUser]
, the object I get back is of type PFUser
, but is not of type MyUser
. Casting it to MyUser*
does not help, it just throws the error "unrecognized selector sent to instance 0xce9c0c0" when I try to use any of the custom properties, e.g. user.avatar
that is defined in MyUser.
How can I get the cached currentUser
object of my custom type?
The key turned out to be the ordering of registering subclasses and setting the application ID.
[Parse setApplicationId:@"FOO" clientKey:@"BAR"];
[MyUser registerSubclass];
Causes the problem to occur. However, if you set the application ID after registering subclasses, it works as expected.
[MyUser registerSubclass];
[Parse setApplicationId:@"FOO" clientKey:@"BAR"];
When you create a new class in Parse, you control the name of that class. For example let's say you create a new class named "Armor."
When you create a subclass in Objective-C you're assigning the created Objective-C class to the Parse class. The code below is the implementation file for this Armor subclass. As you can see the Objective-C class name is "Armor" and the Parse class name is also "Armor."
#import "Armor.h"
#import <Parse/PFObject+Subclass.h>
@implementation Armor
@dynamic displayName;
@dynamic rupees;
@dynamic fireproof;
+ (NSString *)parseClassName {
return @"Armor";
}
@end
In this case, both the Objective-C class name and the Parse class name are the same. However, this doesn't have to be the case. If I were to change the name of my Objective-C class to "BrandonsAwesomeClass" this could still be assigned to the Parse "Armor" class. If I were to create a new instance of BrandonsAwesomeClass it would still return the Parse class type of "Armor"
#import "BrandonsAwesomeClass.h"
#import <Parse/PFObject+Subclass.h>
@implementation BrandonsAwesomeClass
@dynamic displayName;
@dynamic rupees;
@dynamic fireproof;
+ (NSString *)parseClassName {
return @"Armor";
}
@end
In your case the Parse User class is always named "_User" You can't change this name and it doesn't matter what the name of your Objective-C subclass is, it will always return PFUser as the class.
This won't really have much effect on your code or your project, because you can still add custom properties to the Parse "_User" class through the website and add the @dynamic properties to your Objective-C subclass.
As long as you set up your subclass correctly [MyUser currentUser].avatar is the same as accessing [[PFUser currentUser] objectForKey:@"avatar"]
I've linked to the Parse blog post explaining subclasses for reference.
http://blog.parse.com/2013/03/22/stay-classy-objective-c-introducing-native-subclasses-for-parse-objects/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With