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

我认为另一种方法是使用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

两个快速解决方案:

  1. 使用NSNotificationCenter(它在 iOS 上可用)在完成处理块中发布消息。您的控制器可以订阅适当的消息并收到有关操作状态的通知。
  2. 子类 AFJSONRequestOperation 并添加一个“委托”属性。 [[self delegate] performSelectorOnMainThread:@selector(operationSucceded:) withObject:self waitUntilDone:NO];在处理块中添加类似的东西。

我个人更喜欢第一种方式,因为我尽量避免在这种简单的情况下进行子类化。

于 2012-02-14T13:16:59.060 回答
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

两天前我问了同样的问题......希望我先看到这个。我将尝试两种方法来实现这一点。一,在我的 Services 类中创建一个委托,它将触发我的 ViewController 中的方法(参见这个答案)......

或二,创建一个包含回调块的方法......类似于这个问题的答案。

于 2012-06-14T16:30:20.397 回答