title: AFNetworking AFHTTPClient Subclassing, Singleton Client and Delegates
body: <p>I'm writing a REST API layer with AFNetworking for an iOS project.  I have some questions about what I have written so far, so I'm turning to stackoverflow for some guidance/answers.</p>
  
  <p>Here are the guidelines of what I'm trying to achieve:</p>
  
  <ul>
  <li>A base class (DRAPI : AFHTTPClient) that will initialize a singleton client, just as the cocoadocs for AFHTTPClient recommend.</li>
  <li>A "base" delegate for DRAPI: DRAPIDelegate, that holds methods for displaying errors in an unified format.</li>
  <li>Subclasses of DRAPI that deal with certain routes of my REST API.  For example, CRUD operations on Users are responsability of DRUserAPI, which is a child class of DRAPI.</li>
  <li>Each subclass of DRAPI has its own delegate.  For DRUserAPI, there's DRUserAPIDelegate, which extends DRAPIDelegate.</li>
  </ul>
  
  <p>Here is a quick example of how things are written so far:</p>
  
  <p><strong>DRAPI.h</strong></p>
  
  <pre><code>@interface DRAPI : AFHTTPClient
  
  - (void) apiGetCallWithRoute:(NSString*)route
                    parameters:(NSDictionary*)parameters
                     onSuccess:(void(^)(id))successBlock
                       onError:(void(^)(NSArray* errors))errorBlock;
  
  @end
  
  @protocol DRAPIDelegate &lt;NSObject&gt;
  
  -(void) DRAPIErrorFromServer:(NSArray*)errors;
  
  @end
  </code></pre>
  
  <p><strong>DRAPI.m</strong></p>
  
  <pre><code>@implementation DRAPI
  
  +(DRAPI*) sharedClient
  {
    static DRAPI *aSharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&amp;once_token, ^{
      _sharedClient = [DRAPI alloc] initWithBaseURL:[NSURL URLWithString:@"http://127.0.0.1:3000/api"];
    });
    return aSharedClient;
  }
  
  -(id) initWithBaseURL:(NSURL *)url
  {
    self = [super initWithBaseURL:url];
    if (self) {
       // configuration goes here... skipping because it is not important.
    }
    return self;
  }
  
  #pragma mark - Helper methods for Server Calls
  
  - (void) apiGetCallWithRoute:(NSString*)route
                    parameters:(NSDictionary*)parameters
                     onSuccess:(void(^)(id))successBlock
                       onError:(void(^)(NSArray* errors))errorBlock 
  {
    [[DRAPI sharedClient] getPath:route
                      parameters:addAuthenticationParametersTo(parameters)
                         success:^(AFHTTPRequestOperation *operation, id responseObject) {
                           successBlock(responseObject);
                         }
                         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                           errorBlock( processError() );
                         }];
  }
  
  @end
  </code></pre>
  
  <p><strong>DRUserAPI.h</strong></p>
  
  <pre><code>@interface DRUserAPI: DRAPI
  
  @property (weak, nonatomic) id&lt;DRUserAPIDelegate&gt;delegate;
  
  +(DRUserAPI*) APIWithDelegate:(id&lt;DRUserAPIDelegate&gt;)delegate;
  
  -(void) createUser:(NSString*)username password:(NSString*)password;
  
  // ... more methods would be declared here...
  
  @end
  
  @protocol DRUserAPIDelegate &lt;NSObject, DRAPIDelegate&gt;
  
  -(void) DRUserAPIOnUserCreated:(MyUserModel*)newUser;
  
  // more delegate methods would be here...
  
  @end
  </code></pre>
  
  <p><strong>DRUserAPI.m</strong></p>
  
  <pre><code>@implementation DRUserAPI
  
  @synthesize delegate;
  
  +(DRUserAPI*) APIWithDelegate:(id&lt;DRUserAPIDelegate&gt;)delegate 
  {
    DRUserAPI * client = [DRUserAPI new];
    client.delegate = delegate;
    return client;
  }
  
  -(void) createUser:(NSString*)username password:(NSString*)password
  {
    [self apiGetCallWithRoute:@"users/create"
                   parameters:@{@"username" : username, @"password": password}
                    onSuccess:^(id response) {
                      NSDictionary *parsedJSON = response;
                      [delegate DRUserAPIOnUserCreated:[MyUserModel newModelFromDictionary:parsedJSON];
                    }
                    onError:^(NSArray *errors) {
                      [delegate DRAPIErrorFromServer:errors];
                    }];
  }
  
  @end
  </code></pre>
  
  <p>A fellow co-worker brought to my attention that delegates and singletons do not mix.  I still want to manage delegates, though.  I'm thinking that good solution would be pass the singleton instance of the delegate to the method I'm calling inside the API subclass.  </p>
  
  <p>Is this a good idea?  </p>
  
  <p>Thanks!</p>