Search code examples
iosobjective-crestkit

Subclassing RKObjectManager multiple times


I have a subclass called MyObjectManager which inherits from RKObjectManager in MyObjectManager I initialize RestKit (set base url etc etc)

I then subclass MyObjectManager into two different classes: UserManager and GameManager. Each implement different functions

at first I call UserManager sharedManager and it works fine. I later called GameManager sharedManager with a relevant function, but I get a "unrecognized selector sent to instance" error as it refers to the latter as a UserManager.

I read in the guidelines that it's accepted to subclass RKObjectManager several times, what am I missing?

MyObjectManager implementation:

static MyObjectManager *sharedManager = nil;

@implementation MyObjectManager

+ (instancetype)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *baseUrl = [NSString stringWithFormat:@"http://ip/api"];
        NSURL *url = [NSURL URLWithString:baseUrl];

        sharedManager = [self managerWithBaseURL:url];
        sharedManager.requestSerializationMIMEType = RKMIMETypeJSON;

        [sharedManager setupRequestDescriptors];
        [sharedManager setupResponseDescriptors];
    });

    return sharedManager;
}

Solution

  • That's because RKObjectManager +sharedManager is a class method. It will instantiate the shared manager on first call and then return it on further calls. Your first call to sharedManager did instantiate a RKObjectManager and your call to GameManager sharedManager did return the same instance. This instance being of class RKObjectManager , it doesn't implement GameManager's functions - thus the unrecognized selector sent to instance error.

    That's perfectly acceptable to subclass RKObjectManager but you should probably also subclass the class method +sharedManager inside GameManager to return your own static instance instead of relying on RKObjectManager's one.

    EDIT : Based on your edit, you should try to subclass +managerWithBaseURL inside GameManager so that is returns an instance of GameManager instead of RKObjectManager.