MKSG-MugunthKumar / MKNetworkKit

Modern NSURLSession based Networking Framework with built in authentication and HTTP 1.1 caching standards support for iOS 8+ devices
http://mk.sg/8w
3.06k stars 755 forks source link

Data Not Available After Operation Completes Successfully #453

Open kglee79 opened 9 years ago

kglee79 commented 9 years ago

During testing I've found that it is possible that the operation state may be set to finished then back to executing due to the connection start occurring in a dispatch_async block and the operation state being updated to executing outside the block afterwards. Even though the operation completed successfully, the response data will not be made available since the responseData function checks for whether or not the state of the operation is finished. If it isn't, it will return nil.

Every so often during unit testing the operation will be executed, finish, and set the operation state to finished before control returns back to the dispatching function which then sets the state back to executing. I moved setting the state inside the dispatch_async function before the call to [self.connection start] to ensure it does not finish before being set to execute, however this seems a little off and am wondering if there is a better way to do this. I should also add that I am testing against a mock web server (Nocilla) so responses are much faster than they would be in a real world scenario, so it is highly unlikely this would happen in production and might only be an issue during testing.

In MKNetworkOperation:

    dispatch_async(dispatch_get_main_queue(), ^{
      self.connection = [[NSURLConnection alloc] initWithRequest:self.request
                                                        delegate:self
                                                startImmediately:NO];

      [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                 forMode:NSRunLoopCommonModes];

      [self.connection start];
    });

    self.state = MKNetworkOperationStateExecuting;