koogawa blog

iOS、Android、foursquareに関する話題

foursquareが提供するネットワークライブラリFSNetworkingを使ってみた

f:id:koogawa:20131104041839p:plain

今さらですが、foursquareが提供するネットワークライブラリ FSNetworking を使ってみました。

FSNetworking という名前から、このライブラリはてっきり foursquareAPI にアクセスするための専用ライブラリだと思い込んでいたのですが、そういうわけではなく、他の API にも汎用的に使えるようです(^^;

使い方

GETの例

まずは、GET の例です。

    NSURL *url                = ...; // required
    NSDictionary *headers     = ...; // optional
    NSDictionary *parameters  = ...; // optional

    FSNConnection *connection =
    [FSNConnection withUrl:url
                    method:FSNRequestMethodGET
                   headers:headers
                parameters:parameters
                parseBlock:^id(FSNConnection *c, NSError **error) {
                    return [c.responseData dictionaryFromJSONWithError:error];
                }
           completionBlock:^(FSNConnection *c) {
               NSLog(@"complete: %@\n  error: %@\n  parseResult: %@\n", c, c.error, c.parseResult);
           }
             progressBlock:^(FSNConnection *c) {
                 NSLog(@"progress: %@: %.2f/%.2f", c, c.uploadProgress, c.downloadProgress);
             }];
    
    [connection start];

要点だけ解説すると、

  • method には、FSNRequestMethodGETFSNRequestMethodPOST が設定できる
  • header には、User-Agent や Accept-Language などの情報が設定できる
  • parameters には、OAuth token など API に必要なパラメータを付加できる
  • parseBlock にてレスポンスのパースをおこなう
  • completionBlock にてパース完了後の処理をおこなう
  • progressBlock では、アップロード/ダウンロードの進捗状況が取得できる

この例では parseBlock にて、JSON 形式で返ってきたレスポンス(NSData)を NSDictionary 型にパースしています。パースには、dictionaryFromJSONWithError メソッド*1を使用しています。

パース後のデータは、completionBlock 内で c.parseResult のように取り出すことができます。

上の例だとエラー処理は省略していますが、実際には parseBlock 内で

NSDictionary *d = [c.responseData dictionaryFromJSONWithError:error];
if (!d) return nil;

if (c.response.statusCode != 200) {
    *error = [NSError errorWithDomain:@"FSAPIErrorDomain"
                   code:1
              userInfo:[d objectForKey:@"meta"]];
}

return d;

といった感じに、エラー判定・レスポンスコード判定などの処理を記述することになると思います。

POSTの例

次に POST の例です。POST の場合も FSNConnection クラスで簡単にリクエストを投げることができます。ここでは、画像をアップロードする例を挙げてみます。

UIImage *originalImage = ...;

// form file name and parameter name would be determined by the web API
NSDictionary *parameters =
[NSDictionary dictionaryWithObjectsAndKeys:
 [FSNData withImage:originalImage jpegQuality:.75 fileName:@"fileName"],  @"paramName",
 nil];

FSNConnection *connection =
[FSNConnection withUrl:url
                method:FSNRequestMethodPOST
               headers:headers
            parameters:parameters
            parseBlock:nil
       completionBlock:nil
         progressBlock:nil];

ここで注目したいのは FSNData というクラスです。

[FSNData withImage:originalImage jpegQuality:.75 fileName:@"fileName"]

こんな感じにパラメータに指定してあげることで、面倒な multipart/form-data 等の処理を、すべて内部でやってくれるようです*2。これは便利ですね。

まとめ

とてもシンプルにできているなぁ、というのが率直な感想でした。簡単な非同期通信ならこのライブラリで十分かと思いました。

個人的には、アップロード/ダウンロードの進捗率が、他のネットワークライブラリと比較して簡単に取得できるのが便利だと思いました。これを SVProgressHUD の showProgress メソッドなんかと組み合わせれば、面白いことができるんじゃないかなぁ、と。

しばらくは自分のアプリで使い込んでみて、また何かわかったことがあれば追記していきます!

2014.7.7 追記

FSNetworkingを使ったサンプルコードを書きました。

https://github.com/koogawa/NearbyVenues

*1:FSN_categories 内で定義されている

*2:詳細は FSNData.h を参照