2

I'm pretty new to iOS development and been wrestling to tasks for a while. Decided to ask for help eventually.

I have some data to be loaded from internet before I let the app to be launched. I've decided to use didFinishLaunchingWithOptions in AppDelegate

There it is:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    // Override point for customization after application launch.

    //loading configuration
    [Configuration downloadConfiguration:^(NSMutableArray *currencies, double refreshIntervalInMilis, double timeDifferenceInMilis, NSError *error)  {
        if (error) {
            //displaying error dialog
        } else {
            //doing some stuff with data loaded          
        }
    }];    

    return YES;
}

It's obvious that the method will return YES before the data is loaded, because it doesn't wait for data to be loaded. My question is How do I make this method wait for this block be completed before I return YES (or NO if configuration was not loaded properly)?

Jacek Kwiecień
  • 12,397
  • 20
  • 85
  • 157

4 Answers4

5

Don't wait for the data to be downloaded before returning YES. iOS has watchdog daemon that kills the application if it hasn't started in 30 seconds. So if your user has really bad internet connection that causes the download to exceed 30 seconds - your application will get killed before it started.

My suggestion is to use notifications to notify needed parties of configuration's download. Setup needed root view controller that listed to, say MYApplicationDidDownloadConfigurationNotification and once that notification is received it reload the UI or pushes some other view controllers that depend on the configuration in question.

In case of unsuccessful download - update the UI instead of returning NO from delegate method. After all your application did launch, just didn't have the luck to download the configuration.

Eimantas
  • 48,927
  • 17
  • 132
  • 168
1

My suggestion is you add a splash screen where it shows it is loading with a progress bar. The progress bar indicates you are waiting for data to be downloaded and when it is done, you could show the next screen. So in your appdelegate.h

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    // Override point for customization after application launch.

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];


    self.splashviewController = [[SplashViewController alloc] init];
    navigationController = [[NavigationController alloc] initWithRootViewController:self.splashviewController];

 self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

in your splashview controller, include your code:

[Configuration downloadConfiguration:^(NSMutableArray *currencies, double refreshIntervalInMilis, double timeDifferenceInMilis, NSError *error)  {
        if (error) {
            //displaying error dialog
        } else {
            //doing some stuff with data loaded          
        }
    }];  
lakshmen
  • 28,346
  • 66
  • 178
  • 276
0

Never wait for network access on the main thread. Just add the code to initialize the rest of your application for the data returned, to the call-back block of downloadConfiguration:

diederikh
  • 25,221
  • 5
  • 36
  • 49
-3

Are you downloading from a REST API?

if yes use this light weight lib: JNRestClient

And it will do the loading in the background

João Nunes
  • 3,751
  • 31
  • 32