Search code examples
iosobjective-cparse-platformpfuser

Error when trying to access a dynamic property of a PFUser subclass


I'm using Parse.com and I have a PFUser subclass called NPUser.

Here's the code:

NPUser.h

#import <Foundation/Foundation.h>
#import <Parse/Parse.h>

@interface NPUser : PFUser <PFSubclassing>

@property (nonatomic) NSString *facebookId;

- (NSURL *)profileImageURL;

@end

NPUser.m

#import "NPUser.h"
#import <Parse/PFObject+Subclass.h>

@implementation NPUser

@dynamic facebookId;

+ (void)load {
    [self registerSubclass];
}

- (NSURL *)profileImageURL {
    // -- This is where things blow up -- 
    NSString *urlString = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large", self.facebookId];
    return [NSURL URLWithString:urlString];
}

@end

When I call profileImageURL something weird happens, it seems like execution just aborts but the app doesn't freeze. I put a breakpoint on the first line and narrowed it down to self.facebookId failing.

When I call self.facebookId or self[@"facebookId"] or [self objectForKey:@"facebookId"] (which I believe are all the same thing) I get this error:

error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.

I've read this question on Parse about subclassing PFUser but I didn't find anything in there that could help me. I also read the docs on subclassing PFObject and followed whatever was said there.

The thing is all the functionality works otherwise (my NPUser class seems to get called properly and all its properties get set properly). The facebookId property is also saved properly when I inspect the data dashboard on Parse.com.

I should mention that when I inspect the called user object it says it's a PFUser not a NPUser but the profileImageURL method (which is only defined in NPUser) does get called.

I'm puzzled by this. Any thoughts or tips?


Solution

  • So I slept on it and found the problem, it was a silly oversight on my part.

    Basically in this case I wasn't accessing the user object directly. Instead, it was a pointer association to another object I had. So the problem was I wasn't calling:

    [query includeKey:@"user"];
    

    when querying that other object so it wasn't actually including the full object. It was sneaky because there was an actual object there and its methods were being called but its dynamic properties weren't implemented (from what I could tell).

    Hopefully this helps someone else out in the future.