0

I have a situation where i need to alert users that the next view controller accessed is "Data Loading".

I added this to the FirstViewController button action:

- (IBAction)showCurl:(id)sender {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Please Wait" message:@"Acquiring data from server" delegate:self cancelButtonTitle:@"OK!" otherButtonTitles:nil];
    [alert show];
    SecondViewController *sampleView = [[SecondViewController alloc] init];
    [sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
    [self presentModalViewController:sampleView animated:YES];
}

it doesn't work. It loads to SecondViewController and only pops up after the SecondViewController is loaded.

So i tried on the SecondViewController itself. The SecondViewController extracts data from a remote server which is the reason its going to take a while to download depending on Internet connectivity. So i decided to add the UIAlertView in the function:

- (NSMutableArray*)qBlock{
    UIAlertView *alert_initial = [[UIAlertView alloc]initWithTitle:@"Loading" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert_initial show];

    NSURL *url = [NSURL URLWithString:@"http://www.somelink.php"];
    NSError *error;
    NSStringEncoding encoding;
    NSString *response = [[NSString alloc] initWithContentsOfURL:url 
                                                    usedEncoding:&encoding 
                                                           error:&error];
    if (response) {
        const char *convert = [response UTF8String];
        NSString *responseString = [NSString stringWithUTF8String:convert];
        NSMutableArray *sample = [responseString JSONValue];
        return sample;
    }
    else {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"ALERT" message:@"Internet Connection cannot be established." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }
    return NULL;
}

This doesn't work too. And to top it off, i tried to off internet connection to see if the second alert pops up to alert user that there's no internet connection. The second alert doesn't work too.

Joe Shamuraq
  • 1,245
  • 3
  • 18
  • 32

1 Answers1

1

For the first part of the question: the show method of UIAlertView does not blocks the current thread, so the execution continues and the behavior you have is expected. What you have to do is implement one of the UIAlertViewDelegate's methods and set the alert's delegate property to self. So when the alert is dismissed, you can show your SecondViewController.


For the second part if you're having your qBlock method executed in a background thread then it's normal you alert not to be shown again - you need to show your alert in the main thread, where the UI is running. To do that change your else statement with the following:

else
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"ALERT" message:@"Internet Connection cannot be established." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show]; 
    });
}

Hope this helps.

Bart
  • 19,692
  • 7
  • 68
  • 77
graver
  • 15,183
  • 4
  • 46
  • 62
  • Where do i implement the first method? in the SecondViewController of the FirstViewController? – Joe Shamuraq May 06 '12 at 20:06
  • In the FirstViewController. The show method should show the UIAlertView, and when the alert view is dismissed (you can catch this by implementing some of the UIAlertViewDelegate methods and setting the alert's delegate to self) you initialize and present the SecondViewController. – graver May 07 '12 at 05:58
  • That i can achieve when i set the cancel button. But what i want is without the cancel button. I want the alert to just pop up to show tt – Joe Shamuraq May 09 '12 at 19:29
  • So you need to restructure a little bit. Declare a property of your UIAlertView and initialize it (without showing it). When starting your background work, show the alert with [self.myLoadingAlert show] **in the main thread** and when your background work finishes call [self.myLoadingAlert dismissWithClickedButtonIndex:0 animated:YES] again in the **main thread** – graver May 09 '12 at 19:34
  • That i can achieve when i set the cancel button. But what i want is without the cancel button. I want the alert to just pop up to show tt its loading something. When i set the cancel button to nil, it freezes (assuming secondViewController is loading) and after the secondViewController is loaded then it pops up. By this time, it can no longer dismiss the alertview since the dismiss is located at firstViewController. – Joe Shamuraq May 09 '12 at 19:37
  • This is the structure. 1. Show alert on the main thread. 2. start your background operation in background thread. 3. When operation from the background thread finished you hide your alert by calling [alert dismissWithClickedButtonIndex:0 animated:YES] **on the main thread**. 4. You push the SecondViewController on the **main thread**. – graver May 09 '12 at 19:42
  • Is there a way to post my code here for the codes involved so that you can spot the error in the method? – Joe Shamuraq May 09 '12 at 19:49