AFNetworking でベーシック認証に対応する方法

久しぶりの Objective-C

定番通信ライブラリ『AFNetworking』で、ベーシック認証が設定された Web API にアクセスする方法を README や Github の Wiki で調べてみた。

f:id:griefworker:20130729203044j:plain

さっぱりわからない。

仕方ないので、ソースコード読んだり、StackOverflow 漁ったりして なんとか対応できた。以下、自分用メモ。

Web API のクライアントを定義

#import <Foundation/Foundation>
#import <AFNetworking/AFHTTPClient.h>

@interface WebAPIClient : AFHTTPClient

- (void)setUsername:(NSString*)username
           password:(NSString*)password;

@end

AFHTTPClient はサブクラスを作って使うのが定石みたいだ。

Web API のクライアントを実装

#import <AFNetworking/AFNetworkActivityIndicatorManager.h>
#import "WebAPIClient.h"

@implements WebAPIClient

- (id)initWithBaseURL:(NSURL*)url
{
  self = [super initWithBaseURL:url];
  if (self)
  {
      // AFJSONRequestOperation を使って通信する
      [self registerHTTPOperationClass:[AFJSONRequestOperation class]];

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

      // パラメータを JSON にエンコードする
      // Web API によっては不要かも
      [self setParameterEncoding:AFJSONParameterEncoding];

      // 通信時、ステータスバーにインジケーターを表示する
      [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
  }
  return self;
}

- (void)setUsername:(NSString*)username password:(NSString*)password
{
  // 古い認証用ヘッダを削除
  [self clearAuthorizationHeader];

  // ベーシック認証のユーザー名とパスワードを設定
  [self setAuthorizationHeaderWithUsername:username password:password];
}

@end

Web API 呼び出し

WebAPIClient *client = [[WebAPIClient alloc] initWithBaseURL:@"https://web-api-base-url/"];

// ベーシック認証のユーザー名とパスワードをセット
[client setUsername:@"username" password:@"password"];

// 非同期に Web API 呼び出し
[client getPath:@"/path/to/resources"
     parameters:nil
        success:^(AFHTTPRequestOperation *operation, id responseObject) {
          // TODO: responseObject を NSArray または NSDictionary にキャストして操作
        }
        failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          // TODO: エラーを表示
        }];

通信で AFJSONRequestOperation を使うように設定したから、responseObject には JSON にパースされたあとの NSArray または NSDictionary が渡される。