aporat
aporat

Reputation: 5932

AFHTTPClient subclass with custom NSMutableURLRequest objects

My app is using AFNetworking for twitter API access and I've created a twitter api client by subclassing AFHTTPClient:

#import "AFHTTPClient.h"

@interface TwitterAPIClient : AFHTTPClient

+ (TwitterAPIClient *)sharedClient;

@end

#import "TwitterAPIClient.h"
#import "AFJSONRequestOperation.h"

static NSString * const kAFTwitterAPIBaseURLString = @"http://api.twitter.com/1/";

@implementation TwitterAPIClient

+ (TwitterAPIClient *)sharedClient {
    static TwitterAPIClient *_sharedClient = nil;
    static dispatch_once_t TwitterAPIClientToken;
    dispatch_once(&TwitterAPIClientToken, ^{
        _sharedClient = [[TwitterAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kAFTwitterAPIBaseURLString]];
    });

    return _sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url {
    self = [super initWithBaseURL:url];
    if (!self) {
        return nil;
    }

    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [self setDefaultHeader:@"Accept" value:@"application/json"];

    return self;
}

@end

If I use getPath's & postPath's on the TwitterAPIClient, the API client returns JSON responses correctly, as I register a AFJSONRequestOperation as the operation class.

However, Sometimes, I need to create custom NSMutableURLRequest requests and not use the getPath's & postPath's AFHTTPClient functions.

When I use these requests, the response is getting back from the client is standard NSData and not NSDictionary as I get from AFJSONRequestOperation.

 NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/1.1/account/verify_credentials.json"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [self.auth authorizeRequest:request];

    AFHTTPRequestOperation* apiRequest = [[TwitterAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, NSDictionary* responseObject) {
        [self createAccount];

        self.account.username = [responseObject objectForKey:@"screen_name"];

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate didProfileLoaded:self.account];
        });


    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (error!=nil) {
            NSString* errorMessage = nil;
            NSString* errorData = [error.userInfo objectForKey:NSLocalizedRecoverySuggestionErrorKey];

            if (errorData!=nil) {
                NSError* error;
                NSDictionary* json = [NSJSONSerialization JSONObjectWithData:[errorData dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
                if (json!=nil && error==nil) {
                    NSArray* errorMeta = [json objectForKey:@"errors"];
                    if (errorMeta!=nil) {
                        errorMessage = [[errorMeta objectAtIndex:0] objectForKey:@"message"];
                    }
                } else {
                    errorMessage = errorData;
                }
            }

            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate didUpdateFailed:errorMessage];
            });
        }

    }];

    [[TwitterAPIClient sharedClient] enqueueHTTPRequestOperation:apiRequest];

Is there a way I can force these AFHTTPRequestOperation to be created as AFJSONRequestOperation objects?

Upvotes: 0

Views: 1568

Answers (1)

Andres Kievsky
Andres Kievsky

Reputation: 3491

Just create an AFJSONRequestOperation directly, like so:

    AFJSONRequestOperation* apiRequest = [[AFJSONRequestOperation alloc] initWithRequest:request];
[apiRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

// ....

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

// ...

}];

More examples here and here.

Upvotes: 1

Related Questions