2014/01/31

SimpleAuthにIIJMioクーポンAPIを追加してみる

SimpleAuthでは他のウェブサイトのOAuth認証もある程度簡単に追加できるようになっているみたいなので、試しにIIJmioクーポンスイッチAPIを追加してみました。

SimpleAuthにプロバイダ (認証する対象のサービス) を追加するには、podspecを修正する必要があります。

そのために、まずSimpleAuthをフォークしておき、それをcloneします。

cd ~/src
git clone https://github.com/safx/SimpleAuth.git

続いて、とりあえずInstagramを雛形として、ソースコードをコピーしておきます。

cd SimpleAuth
mkdir Providers/IIJMio
cp Providers/Instagram/*.{m,h} Providers/IIJMio
cd Providers/IIJMio
for i in * ; do mv $i SimpleAuthIIJMio${i#SimpleAuthInstagram} ; done

続いて、SimpleAuth.podspecに次のようなサブスペックを追加します。

  s.subspec 'IIJMio' do |ss|
    ss.dependency 'SimpleAuth/Core'

    ss.source_files = 'Providers/IIJMio/**/*.{h,m}'
    ss.frameworks = 'UIKit'
  end

そして、ソースコードを修正していきます。ヘッダは中身がないので変更はなく、実装のみ変更します。

まずは、SimpleAuthIIJMioLoginViewController.mを変更します。

-initWithOptions:requestToken:では表示タイトルを変更するだけです。

 - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken {
     if ((self = [super initWithOptions:options requestToken:requestToken])) {
!        self.title = @"IIJMio";
     }
     return self;
 }

initialRequestでは送信先をIIJMioのOAuth認証サーバに変更するなどしています。

!    if (self.options[@"state"]) {
!        parameters[@"state"] = self.options[@"state"];
     }
     NSString *URLString = [NSString stringWithFormat:
!                           @"https://api.iijmio.jp/mobile/d/v1/authorization/?%@",
                            [CMDQueryStringSerialization queryStringWithDictionary:parameters]];

続いて、SimpleAuthIIJMioProvider.mを変更します。

 + (NSString *)type {
!    return @"iijmio";
 }

IIJMioクーポンAPIではInstagramと異なり、ユーザアカウント情報のAPIがありませんので、-accountWithAccessToken:を削除します。 そして、それにともなって、-authorizeWithCompletion:rac_liftSelectorまわりのコードを修正します。

 - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion {
     [[[self accessToken]
       flattenMap:^RACStream *(NSString *response) {
!          NSArray *signals = @[[RACSignal return:response]];
!          return [self rac_liftSelector:@selector(dictionaryWithAccessToken:) withSignalsFromArray:signals];
       }]

-accessTokenはビューコントローラのクラスを変更するだけです。

 - (RACSignal *)accessToken {
     return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         dispatch_async(dispatch_get_main_queue(), ^{
!            SimpleAuthIIJMioLoginViewController *login = [[SimpleAuthIIJMioLoginViewController alloc] initWithOptions:self.options];

-dictionaryWithAccessToken:は引数も減ってシンプルになりました。

!- (NSDictionary *)dictionaryWithAccessToken:(NSString *)accessToken {
     NSMutableDictionary *dictionary = [NSMutableDictionary new];
     // Provider
     dictionary[@"provider"] = [[self class] type];

     // Credentials
!    dictionary[@"credentials"] = @{@"token" : accessToken};

     return dictionary;
 }

以上で修正は完了です。

なお、https://github.com/safx/SimpleAuth/tree/master/Providers/IIJMioもありますので、詳細はそちらを参照してください。

利用してみる

以前作成した、IIJmioのクーポンスイッチAPIのサンプルアプリを改変して、SimpleAuthを使うようにしてみます。

まず、Podfileに次のように追加して、Pod installします。

pod 'SimpleAuth/IIJMio', :path => "~/src/SimpleAuth/SimpleAuth.podspec"

そして、MioHelper.mのOAuth関連のメソッドをすべて削除して、次のようなコードを追加するだけです。

- (RACSignal*)authorize {
    SimpleAuth.configuration[@"iijmio"] = @{
        @"client_id": self.clientID,
        SimpleAuthRedirectURIKey: self.redirectURI,
        @"state": @"foobar"
    };

    self.authSignal = [RACSubject subject];
    [SimpleAuth authorize:@"iijmio" completion:^(id responseObject, NSError *error) {
        if (error) {
            [self.authSignal sendError:error];
        } else {
            self.accessToken = [responseObject valueForKeyPath:@"credentials.token"];
            [self.authSignal sendCompleted];
        }
    }];
    return self.authSignal;
}

ウェブページ関連の処理はSimpleAuthに任せられるので非常にコードが短くなりました。

おわりに

SimpleAuthにIIJmioクーポンスイッチAPIを追加してみました。

SimpleAuthは中でReactiveCocoaを使っているんですね。始めに見たときはちょっと驚きました。

関連リンク

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。