Question

How can I get an indication to main UI thread in an iPhone app IOS program, when background task has completed?

Background

  • I'm trying to setup a loading indicator per the concept at How to add a UIActivityIndicator to a splash screen in a iphone application?
  • was going to in AppDelete use "performSelectorInBackground" to load up the model data
  • what I need therefore is in the RootViewController some way of telling when the data has finished loading in the background so that it can (a) update the tableview with the data and (b) remove any activity indicator
  • I'm assuming way to do things here is as followings:
    • in App Delegate didFinishLaunchingWithOptions pass off Model data loading to background
    • AppDelegate loads up RootViewController and it immediately setup up an activity indicator
    • once data is loaded in background, it somehow has to indicate this back to the RootViewController (? reason for this question) that it's finished
    • 2nd question is probably also when background task does inidicate its finished, how can the RootviewController check that the UI did get setup (with activity indicator etc) before it tries to disable the activity indicator
Was it helpful?

Solution

You can call back into the main thread from your background selector using -performSelectorOnMainThread:withObject:waithUntilDone: like so:

- (void)loadModel
{
    // Load the model in the background
    Model *aModel = /* load from some source */;

    [self setModel:aModel];
    [self performSelectorOnMainThread:@selector(finishedLoadingModel) withObject:nil waitUntilDone:YES];
}

- (void)finishedLoadingModel
{
    // Notify your view controller that the model has been loaded
    [[self controller] modelLoaded:[self model]];
}

Update: an even safer way to do this would be to check in -finishedLoadingModel to make sure you're running on the main thread:

- (void)finishedLoadingModel
{
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:YES];
    }
    // Notify your view controller that the model has been loaded
    [[self controller] modelLoaded:[self model]];
}

OTHER TIPS

Once you're finished loading in the background, call the following from your background thread:

[self performSelectorOnMainThread:@selector(backgroundLoadingDidFinish:) withObject:nil waitUntilDone:NO];

And then implement -(void)backgroundLoadingDidFinish:(id)sender in your RootViewController. If you need to, you can pass data back in the above method (the withObject: part).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top