0

Use the following standard calls to get data from a server - and standard Alert if there's an error - like no internet access. If I turn off the network the app crashes, never hitting the NSLog calls for *response or *error, never entering the alert.

dispatch_queue_t concurrentQueue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//this will start the URL call and download in bg

dispatch_async(concurrentQueue, ^{

   NSURLSession *session = [NSURLSession sharedSession];
   NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.websitethatdownloadsdata.com"] completionHandler:^(NSData *myData, NSURLResponse *response, NSError *error) {

       NSLog(@"Resp value from NSURL task: %@", response);
       NSLog(@"Error value from NSURL task: %@", error);

       if (error == nil) {

       NSLog(@"Downloading data...");

       }

       if (error != nil) {

       UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Network Problem" message:@"Cannot download data" preferredStyle:UIAlertControllerStyleAlert];
         UIAlertAction * actionOK = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                            //Here Add Your Action
             abort();
                        }];

                    [alert addAction:actionOK];

       [self presentViewController:alert animated:YES completion:nil];

       }
shim
  • 9,289
  • 12
  • 69
  • 108
user3741598
  • 297
  • 1
  • 12
  • 1
    "If I turn off the network the app crashes" Do you have a crash log in console when this happens? – Larme Jan 08 '20 at 15:28
  • Also you are presenting a `UIAlertViewController` from a a thread that is not the main thread, this will cause issues. – rckoenes Jan 08 '20 at 15:40
  • @rckoenes - using an async queue is the only way to get data then update UI - I fought that for days.... – user3741598 Jan 08 '20 at 15:44
  • So it was just missing a dispatch in main thread for the UI? I think that would have been stated in the console. And that's why I often ask the question's author do give that message, pointing out to read them. It's an important peace of info to debug by yourself. – Larme Jan 08 '20 at 15:47
  • There are many issue with the posted code. You should not perform any UI off the main thread. – rckoenes Jan 08 '20 at 15:47

1 Answers1

2

The background queue is redundant because NSURLSession dispatches its tasks on a background thread anyway.

But you have to present the alert controller on the main thread

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.websitethatdownloadsdata.com"] completionHandler:^(NSData *myData, NSURLResponse *response, NSError *error) {

   NSLog(@"Resp value from NSURL task: %@", response);
   NSLog(@"Error value from NSURL task: %@", error);

   if (error == nil) {

      NSLog(@"Downloading data...");

   } else {
      UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Network Problem" message:@"Cannot download data" preferredStyle:UIAlertControllerStyleAlert];
      UIAlertAction * actionOK = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
         //Here Add Your Action
         abort();
      }];

      [alert addAction:actionOK];
      dispatch_async(dispatch_get_main_queue()) {
          [self presentViewController:alert animated:YES completion:nil];
      }
   }

}

And you should display also the reason of the error in the NSError instance

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Alert flashes but doesn't stop for the user to press OK. So it continues and crashes when the parser is invoked in the code below. – user3741598 Jan 09 '20 at 01:15