Search code examples
iosmultithreadingapple-push-notificationsafnetworking-2

AFHTTPRequestOperationManager doesn't respond


I am using AFNetworking kit to develop an iOS app.

When the app is launching, it requests an access token from the server.

The code is simple as:

__block int status = 0;
[manager GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) 
{
    ...fetch access token from response json string
    status = 1;  //break the loop
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    ...networking error
}

and also, to make sure the other requests to the server own the access token, I have put a loop to block the thread until the server responses.

while (status == 0)
{
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                 beforeDate:[NSDate date]];
}

This worked before, until I imported a third party notification push library. And the async method:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

is continuing print deviceToken request in console and the access token request never responds anything, even the server actually provides the response.

I have been stuck for day, can someone helps me?

UPDATE I have tried to comment the device token stuff, the AFNetworking request still doesn't work, no success no failure and no timeout:

UPDATE2 Clarify my question. AFHTTPRequestOperationManager have sent a GET request to the server, and server responses. But the AFHTTPRequestOperationManager doesn't receive it, and no success no failure callback as well.


Solution

  • A couple of thoughts:

    1. If you're going to use this pattern:

      • you really should set status to 1 in the error block, too; and

      • Apple uses distantFuture in its examples, not date:

        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        
    2. You might have something else blocking the main thread. Try putting a NSLog inside the while loop and see if you see that loop running. If not, then identify where you're blocking the main thread.

    3. Needless to say, this overall pattern is inefficient. I'd suggest employing asynchronous patterns, such as adopting completion handlers in your own code:

      - (void)performSomeURL:(NSString *)url completionHandler:(void (^)(NSDictionary *response, NSError *error))completionHandler{
          NSDictionary *parameters = ...;
      
          [manager GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
              completionHandler(responseObject, nil);
          } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
              completionHandler(nil, error);
          }];
      }
      

      which could be called like:

      [self performSomeURL:url completionHandler:^(NSDictionary *response, NSError *error) {
          // use response and error here
      }];
      
      // but not here
      

      If you always adopt asynchronous patterns like this in all of your code, never doing anything that blocks the main thread, then not only will your code be more efficient, but you'll never have to fear about deadlocking on the main thread.