48

私が開発している大規模なアプリケーションのリクエストアーキテクチャに私のアプローチを再考する過程にあります。私は現在ASIHTTPRequestを使って実際にリクエストを行っていますが、異なるView Controllerで行われる多くの異なるアクションの結果として、多くの異なるタイプのリクエストが必要なので、これらのリクエストを整理するための最良のシステムを試しています。多くのネットワーク要求を行うiOSアプリケーションのための最善のアーキテクチャ?

私は現在、アプリケーションデリゲートによって保持されているリクエストを作成する必要があることを知らせるNSNotificationsをリッスンしながらシングルトン "リクエスター"を構築しています。彼らは要求を行い、応答を聞いて、応答データとともに新しいNSNotificationを送信します。これは私の問題のほとんどを解決しますが、失敗した要求や同じ要求を同じシングルトンリクエスタにエレガントに処理しません。

iOSアプリケーションでさまざまな種類のリクエストを作成するための明確なオブジェクト指向アーキテクチャーの開発に成功した人は誰ですか?

+2

良い質問:NSURLConnectionの接続マネージャーを作成して、ある接続ではうまく動作するが、いくつかの接続ではうまく動作しない人として、これについての回答を探しています。 –

答えて

69

、これは私に優れた結果を与えている1つのアーキテクチャでは、文書を理解し、維持し、拡張が容易である:

  • 私は聞かせての、ネットワーク接続の世話をして、単一のオブジェクトを持っていますそれを「ネットワークマネージャー」と呼んでください。通常、このオブジェクトはシングルトン(Matt Gallagher's Cocoa singleton macroを使用して作成されます)です。
  • ASIHTTPRequest(私はいつもすばらしいAPIです)を使用しているので、ネットワークマネージャーにASINetworkQueue ivarを追加します。ネットワークマネージャをそのキューの代理人にします。
  • 私は自分のアプリケーションが必要とするネットワーク要求の種類ごとにASIHTTPRequestのサブクラスを作成します(通常、各バックエンドのRESTインタラクションまたはSOAPエンドポイント用に)。
  • ネットワーク・マネージャは、必要なASIHTTPRequestサブクラスのインスタンスを作成し、それをキューに追加します(リフレッシュ、viewDidAppearなど)。 。
  • ASINetworkQueueは、3G、EDGE、GPRS、またはWifiのいずれであるかに応じて帯域幅の問題を処理し、より多くの帯域幅を持ち、より多くの要求を処理できます。これはキューで行われますが、これはクールです(少なくとも、このキューが理解していることの1つですが、間違いないと思います:)。
  • 要求が完了するか失敗するたびに、ネットワークマネージャが呼び出されます(ネットワークマネージャはキューのデリゲートであることに注意してください)。
  • ネットワークマネージャーは、各リクエストの結果をどうしたらいいか分からない。したがって、要求に応じてメソッドを呼び出します。!リクエストはASIHTTPRequestのサブクラスなので、リクエストの結果を管理するコード(通常はJSONやXMLを実際のオブジェクトに逆シリアル化したり、他のネットワーク接続をトリガーしたり、Core Dataストアを更新するなど)を置くことができます。要求クラスごとに共通の名前を持つ多相メソッドを使用して、コードをそれぞれの別々の要求サブクラスに置くことで、IMHOのデバッグと管理が非常に簡単になります。
  • 最後に、通知を使用して興味深いイベントについて上のコントローラに通知します。デリゲートプロトコルを使用するのは良い考えではありません。なぜなら、あなたのアプリケーションでは、通常、ネットワークマネージャーと話しているコントローラがたくさんあり、通知はより柔軟です(複数のコントローラが同じ通知に応答するなど)。

とにかく、これは私がしばらくしてきた方法です。率直に言えば、それはかなりうまくいきます。私はシステムを水平に拡張し、必要に応じてより多くのASIHTTPRequestサブクラスを追加することができ、ネットワークマネージャのコアは元のままです。

希望すると助かります!

+0

良い答え!どのようにシステムをテストしますか?私の別の大きな懸念は、単体テストに簡単なアーキテクチャが登場していることです。 – kevboh

+0

ありがとう、優れた説明。 – Epaga

+5

あなたの応答に興味のあるクラスが1つしかない場合は、気にすることが簡単なことです。通知の代わりにブロックを使用する可能性があります。 –

0

fully-loadedプロジェクトは読みやすいです。いくつかのアプローチを試した後

+0

私は完全にロードされている前に、特定の問題をうまく処理していますが、私は、異なる応答を持つさまざまなタイプのリクエストを扱うソリューションを探しています。完全にロードされたハンドルリクエストの方法は、nsnotificationsとasihttprequestを使用して、私の質問で詳細を説明したものと似ています。私は通知と要求を構成する単なる創造的な方法であっても、より拡張性と堅牢性を求めています。 – kevboh

+1

もう一つのコード例は、AppleのMVCNetworkingサンプルの 'Networking'フォルダです。これは私が何かコメントを書く経験はありません。 – ohho

+0

興味深い。私はこれをチェックしなければならないでしょう。 – kevboh

1

ここで私は一般的にそうしています。私も、ネットワーク要求を行うために使用されるシングルトンオブジェクトを持っています。頻繁に行う必要があるリクエストの場合、私は一般的にAFNetworkingをリクエストするためにAFHTTPRequestOperations(またはAFJSONRequestOperations)を受け入れるNSOperationQueueを持っています。これらのために、要求の成功または失敗時に実行されるcompletionBlockおよびfailureBlockプロパティがあります。私のシングルトンオブジェクトでは、特定のネットワーク要求を開始する方法があり、そのメソッドのパラメータとして、メソッドで定義されたブロックに渡すことができる成功と失敗のブロックが含まれます。この方法では、アプリケーション全体がネットワーク要求を行うことができ、その時点でのアプリケーションのスコープは、メソッドに渡されるブロック内のシングルトンで使用可能です。たとえば...(ARCを使用)

 @implementation NetworkManager 

    -(void)makeRequestWithSuccess:(void(^)(void))successBlock failure:(void(^)(NSError *error))failureBlock 

    { 
     NSURL *url = [NSURL URLWithString:@"some URL"]; 

     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

     AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 

     [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
      [responseObject doSomething]; 

      if (successBlock) 
       dispatch_async(dispatch_get_main_queue(), successBlock); 

     } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

      if (failureBlock) 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        failureBlock(error); 
       }); 
     }]; 

     [self.operationQueue addOperation:op]; 
    } 
@end 

また、成功ブロックには、何かパラメータを渡す必要があります。

0

STNetTaskQueueを試してください。リクエストが再利用可能でメンテナンス可能になります。

関連する問題