Using AFNetworking and HTTP Basic Authentication
Answer updated for AFNetworking 2.x
For AFNetworking 2.x:
In 2.x, they did away with AFHTTPClient, so you'll need to extend AFHTTPRequestOperationManager with your own class. Then, you can call that class from other code. For example, here's a sample class that extends the AFHTTPRequestOperationManager:
SBAPIManager.h:
#import "AFHTTPRequestOperationManager.h"
@interface SBAPIManager : AFHTTPRequestOperationManager
- (void)setUsername:(NSString *)username andPassword:(NSString *)password;
+ (SBAPIManager *)sharedManager;
@end
SBAPIManager.m:
#import "SBAPIManager.h"
#import "AFNetworkActivityIndicatorManager.h"
@implementation SBAPIManager
#pragma mark - Methods
- (void)setUsername:(NSString *)username andPassword:(NSString *)password
{
[self.requestSerializer clearAuthorizationHeader];
[self.requestSerializer setAuthorizationHeaderFieldWithUsername:username password:password];
}
#pragma mark - Initialization
- (id)initWithBaseURL:(NSURL *)url
{
self = [super initWithBaseURL:url];
if(!self)
return nil;
self.requestSerializer = [AFJSONRequestSerializer serializer];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
return self;
}
#pragma mark - Singleton Methods
+ (SBAPIManager *)sharedManager
{
static dispatch_once_t pred;
static SBAPIManager *_sharedManager = nil;
dispatch_once(&pred, ^{ _sharedManager = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"http://localhost:3000"]]; }); // You should probably make this a constant somewhere
return _sharedManager;
}
@end
Then, in your code, you can call it like this:
[[SBAPIManager sharedManager] setUsername:yourUsernameVariableHere andPassword:yourPasswordVariableHere];
[[SBAPIManager sharedManager] GET:@"/tasks.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.tasks = [responseObject objectForKey:@"results"];
[self.activityIndicatorView stopAnimating];
[self.tableView setHidden:NO];
[self.tableView reloadData];
NSLog(@"JSON");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// error stuff here
}];
For AFNetworking 1.x:
The best practice for this in AFNetworking is to extend the AFHTTPClient with your own class. Then, you can call that class from other code. For example, here's a sample class that extends the AFHTTPClient:
SBAPIManager.h:
#import "AFNetworking/AFHTTPClient.h"
@interface SBAPIManager : AFHTTPClient
- (void)setUsername:(NSString *)username andPassword:(NSString *)password;
+ (SBAPIManager *)sharedManager;
@end
SBAPIManager.m:
#import "SBAPIManager.h"
#import "AFJSONRequestOperation.h"
#import "AFNetworkActivityIndicatorManager.h"
@implementation SBAPIManager
#pragma mark - Methods
- (void)setUsername:(NSString *)username andPassword:(NSString *)password
{
[self clearAuthorizationHeader];
[self setAuthorizationHeaderWithUsername:username password:password];
}
#pragma mark - Initialization
- (id)initWithBaseURL:(NSURL *)url
{
self = [super initWithBaseURL:url];
if(!self)
return nil;
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:@"Accept" value:@"application/json"];
[self setParameterEncoding:AFJSONParameterEncoding];
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
return self;
}
#pragma mark - Singleton Methods
+ (SBAPIManager *)sharedManager
{
static dispatch_once_t pred;
static SBAPIManager *_sharedManager = nil;
dispatch_once(&pred, ^{ _sharedManager = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"http://localhost:3000"]]; }); // You should probably make this a constant somewhere
return _sharedManager;
}
@end
Then, in your code, you can call it like this:
[[SBAPIManager sharedManager] setUsername:yourUsernameVariableHere andPassword:yourPasswordVariableHere];
[[SBAPIManager sharedManager] getPath:@"/tasks.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.tasks = [responseObject objectForKey:@"results"];
[self.activityIndicatorView stopAnimating];
[self.tableView setHidden:NO];
[self.tableView reloadData];
NSLog(@"JSON");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// error stuff here
}];
Related videos on Youtube
Paul Sylling
Building things. Running experiments. Growing @Vouchful. Always UI UX.
Updated on July 09, 2022Comments
-
Paul Sylling almost 2 years
The following code successfully connects to my Ruby on Rails API and returns JSON using AFNetworking. What do I need to do to edit this to pass in a username and password so my API can use HTTP Basic Authentication?
I've read their documentation, but I am new to both Objective-C and AFNetworking and it isn't currently making sense.
NSURL *url = [[NSURL alloc] initWithString:@"http://localhost:3000/tasks.json"]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request , NSHTTPURLResponse *response , id JSON) { self.tasks = [JSON objectForKey:@"results"]; [self.activityIndicatorView stopAnimating]; [self.tableView setHidden:NO]; [self.tableView reloadData]; NSLog(@"JSON"); } failure:^(NSURLRequest *request , NSHTTPURLResponse *response , NSError *error , id JSON) { NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo); }]; [operation start];
-
Paul Sylling over 11 yearsWow, awesome code sample! I will try and implement this into my project today. You are certainly at a much higher level than I, so it might take a bit.
-
GeneralMike about 11 yearsSmall note: in the code for SBAPIManager.m, you have
- (void)setUsername:(NSString *)username andPassword:(NSString *)password;
, I think you need to remove that semicolon from the end. -
FluffulousChimp about 11 yearsIn Objective-C, the semicolon before the method implementation's opening brace is superfluous; but it compiles. Sometimes it's an artifact of cutting-and-pasting between header and implementation. No harm.
-
gilletty about 11 yearsThanks guys. It was a copy/paste error and I have removed the semicolon.
-
Legoless over 10 yearsWhat is in v2.x method different from calling
setCredentials
onAFHTTPRequestOperationManager
?