質問

XML Rest Webサービスを照会する小さなiOSアプリを書いています。使用中のネットワークフレームワークはです アフネットワーキング.

状況

WebServiceを照会するには、afhttpclientをサブクラス化しました。

@interface MyApiClient : AFHTTPClient

そして、実装では、それをシングルトンとして利用できるようにします。

+ (MyApiClient *)sharedClient {
    static MySharedClient *_sharedClient = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedClient = [[self alloc] initWithBaseUrl:[NSUrl URLWithString:@"http://url.to.the.webservice"]];
    });

    return self;
} 

そして、initwithbaseurlでは、私はafnetworkingにXMLコンテンツを期待するように言います。

[self registerHTTPOperationClass:[AFXMLRequestOperation class]];

これで、ViewControllerからSingletonのGetPatchを呼び出し、成功ブロックで返されたXMLの解析を開始できます。 nsxmlparserdelegateメソッドでは、viewcontrollerでXMLの部分を選択して、それを行うことができます。

問題

XMLの代わりに、Webサービスに関連するすべてを処理し、データモデルまたはモデルのリストを返すすべてのものを処理するHTTPClient Singletonにメソッドが必要です。

たとえば、私はこのようなことをしたい:

ServerModel *status = [[MyApiClient sharedClient] getServerStatus];

その後、ApiclientはWebサービスを内部的に呼び出し、XMLを解析し、モデルを返します。どうやってやるの?通常、XMLが解析されたら呼ばれる代表者を使用しますが、アピカリエントのシングルトンの性質により、複数の代表者がいる可能性がありますか?

誰かがこれに光を当てることができることを願っています、ありがとう!

役に立ちましたか?

解決

(この「ある種の」答えについて事前に謝罪しますが、私たちはより良い解決策に向けて取り組んでいます...)

一歩下がって、デザインについて注意深く考える必要があります。

あなたはあなたのデザインの何かがシングルトンである必要があるという考えを持っているので、あなたは問題を抱えていますが、どちらも次のとおりです。

1) それは実際には必要ありません、

2) あなたのためにその仕事をする何かがすでに存在するかもしれません(例えば、あなたが使用しているhttp lib)、

また

3) あなたは間違ったものをシングルトンにしているか、シングルトンのアイデアでうまく機能するためにあなたのデザインを適切な部分に分けていません

それで、なぜあなたがシングルトンアプローチに行くのかを明確に教えてもらえますか? 1つのネットワークリクエストのみが一度に発生できることを確認するためだけですか?あなたのシングルトンオブジェクトに局所性の概念はありますか?次に、この回答やコメントなどを更新します。

(余談: また、場合によっては、真の必要性があるかもしれないと付け加えます。強い'Singleton-つまり、実際に1つの可能なインスタンスしか存在しないことを意味し、そのメカニズムはあなたがしているようにあなたのオブジェクトにすぐに焼き付けられていますが、これはそうではありません。代替手段は '弱い'シングルトン、それは私が実際に作品を行うあなたのコアオブジェクトを意味していることを意味します init 通常どおりの方法ですが、共通オブジェクトへの共有アクセスは別のオブジェクトを介して行われます。これは、共有インスタンスをインスタンス/保持する一種の単純な「工場」です。この弱いシングルトンのアイデアの利点は、あなたのコードがさまざまなコンテキストでより再利用可能であることです - 例えば、あなたは後で複数のHTTP要求/セッションを同時に実行することを決定することができます - そして、それは時々書き込みテストの問題を減らします)。

他のヒント

デリゲートの代わりにブロックを使用します。

私の頂点クラスから:

- (void)getPath:(NSString *)path 
     parameters:(NSDictionary *)parameters 
        success:(void (^)(id response))success 
        failure:(void (^)(NSError *error))failure 
{   
    NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
    [self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}

-(void)fetchAllUsersSuccess:(void (^)(id))success 
                     failure:(void (^)(NSError *))failure
{
    [self getPath:@"/api/mobile/user/" 
       parameters:nil 
          success:^(id response) {  

                      if([response isKindOfClass:[NSXMLParser class]]){
                          //parse here to new dict
                          success(newDict);
                      } else
                          success(response);

          } failure:^(NSError *error) {
              failure(error);
          }];
}

今、私はそれを次のように使用できます:

ServiceApiClient *apiClient = [ServiceApiClient sharedClient];

[apiClient fetchAllUsersSuccess:^(id dict) {
    for (NSDictionary *object in [dict objectForKey:@"objects"]) {
        [ServiceUser addUserFromDictionary:object
                                 inContext:self.managedObjectContext];
    }
    NSError *error= nil;
    [self.managedObjectContext save:&error];
    if (error) {
        NSLog(@"%@", error);
    }
} failure:^(NSError * error) {
    NSLog(@"%@", error);
}];
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top