0

現在、ユーザーがHTTPリクエスト(JSON形式)を使用してリモートサーバーに対して認証できるようにするアプリに取り組んでいます。

APIリクエストを処理するための別のクラスを作成しました。これは、アプリケーション全体で多くのことを行うためです。

ほとんどの魔法が行われるAPIRequestのメソッドは次のとおりです。

-(void)send
{
    self.isLoading = YES;
    request_obj = [[self httpClient] requestWithMethod:method path:extendedResourcePath parameters:params];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation 
                                         JSONRequestOperationWithRequest:request_obj 
                                        success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
                                            self.response = [[APIResponse alloc] initWithResponse:response andJSON:JSON];
                                            self.isLoading = NO;
                                        } 
                                        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
                                            self.isLoading = NO;
                                        }];

    // queue is defined elsewhere in the class as an instance of NSOperationQueue
    [queue addOperation:operation];
}

私のコントローラーでは、ボタンが押されたときに次のように呼び出します。

// set the session params from the form values
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: 
                        self.usernameField.text, @"session[username]", 
                        self.passwordField.text, @"session[password]", nil];

// create a new API request object
api_request = [[APIRequest alloc] initWithReourcePath:@"sessions" andMethod:HTTPMethodPOST andParams:params];

// send the request
[api_request send];

私がうまくいかないように見えるのは、リクエストが完了したことをコントローラーに通知する方法です。

APIRequestにisLoadingというプロパティがあり、リクエストがまだ行われている限り「YES」になります。だから、私はそれを尋ねることによってapi_requestが行われたかどうかを確認できることを知っています。

ただし、api_requestが完了したかどうかを確認するために、コントローラーが数秒後に応答するイベントは考えられません。

誰かがここで良いアプローチをアドバイスできますか?

4

4 に答える 4

0

2つの簡単な解決策:

  1. NSNotificationCenter(iOSで利用可能)を使用して、完了処理ブロックにメッセージを投稿します。コントローラは適切なメッセージをサブスクライブして、動作ステータスについて通知を受けることができます。
  2. AFJSONRequestOperationをサブクラス化し、「デリゲート」プロパティを追加します。 [[self delegate] performSelectorOnMainThread:@selector(operationSucceded:) withObject:self waitUntilDone:NO];ハンドリングブロックにのようなものを追加します。

このような単純な状況ではサブクラス化を避けようとするので、私は個人的に最初の方法を好みます。

于 2012-02-14T13:16:59.060 に答える
0

別の方法はKVOを使用することだと思います。

// Add observer for your key
[api_request addObserver:self forKeyPath:@"isLoading" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOption) context:NULL];

// Add below method into your implementation
- (void)observeValueForKeyPath:(NSString *)keyPath  
                      ofObject:(id)object  
                        change:(NSDictionary *)change  
                       context:(void *)context
{
    // put your stuffs here...
}
于 2012-02-14T13:36:41.753 に答える
0

これらのグローバルブール値を使用して接続状態を追跡するのではなく、-send:メソッドシグネチャを、ブロックを取得し、完了時にブロックを呼び出すメソッドに変更してください。私はこれをかなり頻繁に行います。私が取り組んでいるプロジェクトの例:

- (void)getDealsWithSuccess:(void (^)(NSArray *deals))success failure:(void (^)(NSError *error))failure
{
    // lots of OAuth + Request creation code here ...

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
     success:^ (NSURLRequest *request, NSURLResponse *response, id json) {
        NSLog(@"%@", json);

        // handle result here, e.g. 
        // I convert the json to a array with custom objects here ...

        if (success) 
            success(deals);

    } failure:^ (NSURLRequest *request, NSURLResponse *response, NSError *error, id json) {
        NSLog(@"%@", error);

        // handle error here ..

        if (failure)
            failure(error);
    }];

    [operation start];
}
于 2012-02-14T14:45:04.253 に答える
0

私は2日前にこれと同じ質問をしました...私がこれを最初に見ていたらよかったのに。これを実装する方法は2つあります。1つは、ViewControllerのメソッドをトリガーするデリゲートをServicesクラスに作成します(この回答を参照してください)。

または2つ、コールバックブロックを含むメソッドを作成します...この質問の答えと同様です。

于 2012-06-14T16:30:20.397 に答える