How do I access a view controller from AppDelegate.m during a background refresh

206 Views Asked by At

I am trying to implement background refresh in my app. I have a method refreshMessages that is inside one of my UIViewControllers (I am using a UINavigationController). I need to access this controller from AppDelegate.m.

Usually I would do something like this:

UINavigationController *navigationController = [self.window.rootViewController navigationController];

to get the navigation controller and I can then access them from there. But surely this won't work now. The app is in the BACKGROUND and no window is showing. Any thoughts on how to get around this? Thanks!

Here is my background refresh:

-(void)application:(UIApplication *)application
performFetchWithCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {



    NSLog(@"Doing the background refresh");

    UINavigationController *navigationController = [self.window.rootViewController navigationController];
    NSLog(@"Number of controllers is %d", [[navigationController viewControllers] count]);
    //There are zero controllers?!!! Must be because no window is showing
    completionHandler(UIBackgroundFetchResultNewData);



}
1

There are 1 best solutions below

1
On BEST ANSWER

Yes, you are right. The window will be nil since it will no longer be in the view hierarchy.

A cheeky solution would be to hold the reference of the view controller in the AppDelegate by creating a property in it. You can assign this when the application goes to the background by subscribing to the relevant notification in the view controller.

Edit: Code added

In your AppDelegate.h

@property (nonatomic, weak) YourViewController *yourViewController;

In YourViewController.m, somewhere in viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];

appWillResignActive's implementation

-(void)appWillResignActive:(id)sender {
    YourAppDelegate *delegate = [UIApplication sharedApplication].delegate;
    delegate.yourViewController = self;
}

In your completion handler

[self.yourViewController refreshMessages]

Also, make sure you remove the observer once the view controller is deallocated.