I'm trying to improve the responsiveness of my app but am a complete newbie to threading and have become confused.
On launch an alert is shown:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
NSString *user = [[alertView textFieldAtIndex:0] text];
NSString *pass = [[alertView textFieldAtIndex:1] text];
[self loginToServerWithUsername:user andPassword:pass];
}
}
within the loginToServerWithUsername:
method, the app calls a method:
[self checkFiles:sessionID];
This can take several seconds so I tried to execute it in the background:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self checkFiles:sessionID];
});
checkFiles method:
fileList = [[NSMutableString alloc] init];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [directoryPaths objectAtIndex:0];
NSString *downloadsFolderString = [documentsDirectory stringByAppendingPathComponent:DOWNLOADS_FOLDER];
NSError *error = nil;
NSString* file;
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:downloadsFolderString];
while (file = [enumerator nextObject])
{
BOOL isDirectory = NO;
[[NSFileManager defaultManager] fileExistsAtPath: [NSString stringWithFormat:@"%@/%@",downloadsFolderString,file]
isDirectory: &isDirectory];
if (!isDirectory)
{
[fileList appendString:[NSString stringWithFormat:@"%@|", file]];
}
}
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd/MM/yyyy HH:mm"];
NSString *timeOpened = [formatter stringFromDate:[NSDate date]];
NSString *post = [NSString stringWithFormat:@"sessionID=%@&fileList=%@&dateTime=%@&userID=%@", sessionID, fileList, timeOpened, userID];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSString *comparisonURLString = SERVER_COMPARE_URL_STRING;
NSURL *comparisonURL = [NSURL URLWithString:comparisonURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:comparisonURL];
[request setHTTPMethod:@"POST"];
[request addValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];
NSHTTPURLResponse *urlResponse = nil;
error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
if (responseData)
{
NSString *requiredFilesList = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *lines = [requiredFilesList componentsSeparatedByString: @"\n"];
if (lines.count > 2)
{
dispatch_async(dispatch_get_main_queue(), ^(void){
NSRange theRange;
theRange.location = 2;
theRange.length = [lines count] -3;
numberOfFilesToBeDownloaded = theRange.length;
if (numberOfFilesToBeDownloaded <= 0)
{
_jobStatusLabel.text = @"Documents up to date"; // is this the issue?
}
if (numberOfFilesToBeDownloaded > 0)
{
NSArray *subArray = [lines subarrayWithRange:theRange];
[self animateProgressBar];
if (![eraseDevice isEqualToString:@"true"])
{
[self getFiles:subArray];
}
}
});
}
}
else
{
NSLog(@"no response data from check files");
}
However, the alertView
is not dismissed until the checkFiles
method is complete.
Can anyone tell me how to have the alert dismiss whilst checkFiles
runs in the background?
The UI operations should be done in the main thread.
For instance :
_jobStatusLabel.text = @"Documents up to date"; // is this the issue?
should be
dispatch_async(dispatch_get_main_queue(), ^(void){
_jobStatusLabel.text = @"Documents up to date"; // is this the issue?
});
change all such possible cases.