Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8710569
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T04:39:32+00:00 2026-06-13T04:39:32+00:00

XCode 4.5, iPad development, iOS6 Hi, I hope you can help a novice developer!

  • 0

XCode 4.5, iPad development, iOS6

Hi, I hope you can help a novice developer! Apologies in advance if this has already been answered but I could not find during my searches!

I am developing an app that needs to import a large amount of data into Core Data. The import routine works fine (alert shows ‘Please wait’ with activity monitor while routine works in the background) but I want to give the users more detailed feedback on the progress of the import (such as ‘XX% imported’). The following code kicks the process off and –

- (IBAction)import:(id)sender{

[self showWaiting];

[self performSelectorInBackground:(@selector(callGrouper)) withObject:nil];


}

-(void)showWaiting{

alertMsg = @"Please Wait....";
waitAlert = [[UIAlertView alloc] initWithTitle:alertMsg message:nil delegate:self  cancelButtonTitle:nil otherButtonTitles: nil];


[waitAlert show];     

UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

indicator.center = CGPointMake(waitAlert.bounds.size.width / 2, waitAlert.bounds.size.height - 50); 

[indicator startAnimating];
[waitAlert addSubview:indicator];    

}


-(void)callGrouper{

ImportRoutine *firstTest = [[ImportRoutine alloc] init];

[firstTest runImport:managedObjectContext];


 [waitAlert dismissWithClickedButtonIndex:0 animated:TRUE];

UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"iPad Application"
                                               message: @"Import complete!"
                                              delegate: self
                                     cancelButtonTitle:@"Ok"
                                     otherButtonTitles:nil];

[alert show];

}

Within ImportRoutine (separate class) I have code that gathers data on percentage imported but how can I pass this message back to the main thread so I can update ‘alertMsg’ and in turn update the UIAlertView?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T04:39:34+00:00Added an answer on June 13, 2026 at 4:39 am

    You can dispatch blocks of code back onto the main thread using GCD (grand central dispatch):

    dispatch_async(dispatch_get_main_queue(), ^{
    
        // code here to update UI
    });
    

    Any object in the scope of the method that contains the dispatch call gets retained which makes it easy to pass objects back into the main thread without worrying about the background thread being deallocated along with its objects before you’ve had a chance to process the data. Primitive values in the local scope (aka int, float, double, etc) are copied, so if you set an int to 5, dispatch a block where you print the value of the int, and then right after set the int to 10, even if the block executes after you set the int to 10 it’ll still print 5. Note that You can’t mutate the same mutable object (such as `NSMutableArray or NSMutableDictionary) in two threads at the same time or mutate in one and enumerate in another without crashing so you’ll want to be careful about doing something like that (thanks goes to @andrewmadsen for reminding me to warn you).

    dispatch_async(), unlike dispatch_sync(), will not wait for the code that’s dispatched to complete before continuing execution which is nice since your background thread doesn’t need to care if things in the UI have finished.

    You could stick the dispatch call inside of the method on the ImportRoutine class that calculates the progress as long as your UIAlertView is addressable outside of your view controller class. Or if you want to follow model-view-controller design principals more closely, you could create a method like so in your view controller:

    - (void)updateProgressToPercentComplete:(double)percent {
        if ([NSThread currentThread] != [NSThread mainThread]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // update code or call to method that is guaranteed to be on the main thread.
            }
        }
        else {
            // update code or call to method that is guaranteed to be on the main thread.
        }
    }
    

    If you’ve gone into the documentation and now you’re all like “oh my gosh Objective-C blocks are the coolest thing ever” you could modify the method above so you don’t need to write the same update code twice:

    - (void)updateProgressToPercentComplete:(double)percent {
        void (^updateProgressBlock)(void) = ^{
            // update code
        };
        if ([NSThread currentThread] != [NSThread mainThread]) {
            dispatch_async(dispatch_get_main_queue(), updateProgressBlock());
        }
        else {
            updateProgressBlock();
        }
    }
    

    By the way I noticed in your -callGrouper code that you’re using an existing managedObjectContext that I assume you created on the main thread in a background thread… most of core data isn’t threadsafe so you need to be extremely careful or you will crash all over the place. You might be better off creating a secondary managed object context on the background thread and then merging changes into the context on the main thread (or save on the background thread and re-fetch on the main thread).

    Edit:
    Basic flow: Begin your background process from your view controller and pass in a progress block. -> Import class in the background thread executes your progress block periodically -> Inside your progress block you dispatch back to the main thread to update UI.

    In your ImportRoutine class add a property declaration like so:

    @property (nonatomic, strong) void (^progressBlock)(NSUInteger);
    

    Which means a property called progressBlock that takes an unsigned integer (0-100) and doesn’t return anything (void). You should make this property private by using a class extension.

    Then you’ll want to create a method in your import class like so:

    - (void)callGrouper:(void (^)(NSUInteger))progress {
        [self setProgressBlock:progress];
        // Your import code
    }
    

    In your method where you receive progress updates, call the progressBlock and pass in your progress as a number between 0 and 100:

    if ([self progressBlock] != nil) {
        [self progressBlock](progressValue);
    }
    

    Notice that I check to make sure the progress block isn’t nil. You would crash and burn if you tried to execute a NULL block.

    Then you can pass in a block as the object in your import routine call you already have in the view controller and inside the block dispatch back to the main queue and update your progress.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

As Objective-C has evolved (I use it exclusively with xcode/ios for iPhone/iPad development), there
In Xcode, how can I create a simple iPad application that uses Storyboards such
I recently upgrade iPad to iOS 5.1.1. Organizer prompted the Xcode can not find
How can I run my XCode SDK application on my iPad without key and
The interface of my iPad app has multiple section boxes (looks similar to this
We are new to iOS development and this is our first application for iPad
i'v been looking to kick start my app development for the new iPad(iPad-3). But
I'm learning iPad development and I'm refactoring my project to use Kobold2d. It's been
How to use NavigationController in iPad using Interface Builder for Xcode 3.2? Is this
I have iPad 2 with 4.3.2, can I run an App built on xcode

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.