Q:

Download file on device is blocking interface

Use this code for download file on my device.  But on 99% loading interface stop(I can’t click on button).  After 20 second everything works fine and loading = 100%.  Why interface stop on 99% loading?  How to fix it? 
- (void)viewDidLoad
{
 dispatch_async(dispatch_get_main_queue(), ^{

    _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        });

    [self.progressView setProgress:0 animated:NO];
}

- (IBAction)btnClicked:(id)sender {
    if(_downloadTask == nil){

        _url =[NSURL URLWithString:@"https://www.nsw.gov.au/sites/default/files/bg-view-nsw-media.png"];

        _downloadTask = [_session downloadTaskWithURL:_url1];

        [_downloadTask resume];

    }

    else

    [_downloadTask resume];
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    dispatch_async(dispatch_get_main_queue(), ^{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"image1.mp3"];
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO];

    NSData *urlData = [NSData dataWithContentsOfURL:_url];
    [urlData writeToFile:filePath atomically:YES];
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten  totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
{
dispatch_async(dispatch_get_main_queue(), ^{
  [ _progressView setProgress:totalBytesWritten/totalBytesExpectedToWrite animated:YES];

    NSString *percentage = [NSString stringWithFormat:@"%d%%", (int)((totalBytesWritten/totalBytesExpectedToWrite)*100)];
    [_label setText:[NSString stringWithFormat:@"%@%%", percentage]];

    NSLog(@"%lld", totalBytesWritten);

    _label = [[UILabel alloc]initWithFrame:CGRectMake(91, 15, 500, 50)];
    [_label setText: percentage];
    _label.numberOfLines = 1;
    _label.backgroundColor = [UIColor blackColor];
    _label.textColor = [UIColor whiteColor];
    _label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_label];

    }); 

UPD
Then I remove this code
NSData *urlData = [NSData dataWithContentsOfURL:_url];
    [urlData writeToFile:filePath atomically:YES];

everything works fine

A:

You shouldn't put everything in main thread.  The only things to keep in main thread are UI updates.  
Indeed, every action made in main thread will block the interface until the action finishes.  What you want is having your download performing in background, and having only your UI updates in main thread.  
What you have to do is following this code : 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Do background work
    dispatch_async(dispatch_get_main_queue(), ^{
        //Update UI
    });
});

For your case the code should look like : 
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"image1.mp3"];
        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO];

        NSData *urlData = [NSData dataWithContentsOfURL:_url];
        [urlData writeToFile:filePath atomically:YES];
    });
}

