0

I built a simple command line tool that fetches some data using an NSURLSessionDataTask. Now that I'm done coding, I find that the executable hangs when I switch to the Release build configuration in Xcode. I'm using a while loop that waits for the NSURLSessionData completionHandler to complete. The while loop works with Debug, but not with Release. If instead I use [NSThread sleepForTimeInterval:2.0f] to pause the code to wait for the completionHandler to complete, everything works fine in both Release and Debug, however I'd prefer to use the while loop as it is quicker and more logical.

Here is the relevant code:

// Configure Session
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
// Authentication for the session
NSString *auth = [[[NSString stringWithFormat:@"%@:%@",cpanelUser, WxWaPpIUPA] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
config.HTTPAdditionalHeaders = @{@"Authorization":[NSString stringWithFormat:@"Basic %@",auth]};
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

// Run Data Task
__block BOOL taskComplete = NO;
NSURLSessionDataTask *task = [session dataTaskWithURL:urlComponents.URL
                                        completionHandler:
    ^(NSData *data, NSURLResponse *response, NSError *error) {
    
    if(error) {
        // *HTTP response failed
        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
        [result addEntriesFromDictionary:queryReturn(EMAIL_TYPE_ERROR, [NSString stringWithFormat:@"There was a connection issue with the session data task.<br><br>Error: %@ HTTP Status Code for the <a href='%@'>URL</a> requested: %li.",error,urlComponents.URL,statusCode])];
    } else {
        NSError *jsonError;
        NSDictionary *jsonObject = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:data
        options:NSJSONReadingAllowFragments
          error: &jsonError];
        
        if(!jsonObject){
            // *JSON parsing Error
            [result addEntriesFromDictionary:queryReturn(EMAIL_TYPE_ERROR, [NSString stringWithFormat:@"There was an error while parsing the JSON data returned from cPanel.<br><br>Error: %@",jsonError])];
        } else {
            if([jsonObject[@"cpanelresult"] objectForKey:@"error"] != nil) {
                // *cPanel API returned an Error
                NSString *cpanelError = [NSString stringWithFormat:@"%@",[jsonObject[@"cpanelresult"] objectForKey:@"error"]];
                if(verbose) NSLog(@"cPanel API 2 Error: %@\n", cpanelError);
                [result addEntriesFromDictionary:queryReturn(EMAIL_TYPE_ERROR, [NSString stringWithFormat:@"cPanel API 2 returned an error while executing function '%@'.<br><br>Error: %@",funct, cpanelError])];
            } else {
                [result addEntriesFromDictionary:jsonObject];
            }
        }
    }
    taskComplete = YES;
}];
[task resume];

// Wait for task to complete
while(!taskComplete);
//[NSThread sleepForTimeInterval:2.0f];
  • 2
    I think it is not a good idea to use a wait loop for the termination of an async task, since this will block the executing thread. I hope it is not the main thread that will block the UI. But it you really want to do so (I cannot imagine a reason, except for testing), you may find an answer [here](https://stackoverflow.com/q/3615939/1987726). – Reinhard Männer Feb 22 '22 at 21:47
  • You should not be using a while loop to wait on the API call to complete. It suggest that there is a larger problem with your design and the code relevant to your problem is actually in whatever code is invoking this behavior. – Scott Thompson Feb 24 '22 at 23:28

0 Answers0