Using AFNetworking and HTTP Basic Authentication

前端 未结 1 744
终归单人心
终归单人心 2020-12-02 06:54

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

相关标签:
1条回答
  • 2020-12-02 07:24

    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
    }];
    
    0 讨论(0)
提交回复
热议问题