Is there a way for me to determine the ViewController that was active when a user hits the Home button and the app delegate function applicationDidEnterBackground function is called?
So this line:
let vc: UIViewController = self.window!.rootViewController!
will give you the root view controller in Swift (assuming that you use that line in some method inside AppDelegate), but if you have containers (such as UITabBarController) -- you may need to go on that hierarchy for additional checks/inspections...
Related
I have an widget that calls its corresponding app through NSURL and extensionContext to activate a specific action in the app.
In AppDelegate's application:openURL:options: method I have:
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
if let path = url.path{
if path.containsString("action"){
NSNotificationCenter.defaultCenter().postNotificationName(MyViewController.purchasmyActionKey, object: nil)
}
}
return true
}
When the app is open, and has MyViewController active, the action is executed perfectly. But, if I am on another view controller in the app or the app is closed, the action is not executed.
Can somebody set me on the right track?
NB: My main controller is a UITabBarController with various child view controllers. Some are UINavigationControllers (which contain grid controllers) and the other one is a ListViewController.
The simplest option is to show your view controller which handles this as a modal over the tab controller. This is generally the least complex and the cleanest as the user can be easily returned to what they were doing before this interaction when they're done.
If you can't do that for some reason:
You need to designate some class the responsibility of ensuring that the correct view controller is shown and told to action the request when the notification is seen. That could be the app delegate directly, the tab bar controller or some other specific class that you create and provide with a reference to the tab controller.
It's job is to check the state of the tab controller and show the correct view controller if required, then tell that view controller to begin some action.
This class who owns this logic could be the one that observes your notification, or you could just pass the message directly as your app delegate will likely know the instance or be creating a new instance.
I need to respond to a LocalNotification on my app on the main viewController. My problem is that the system seems to be the catch it in didRecieveLocalNotification which I am but I then need to take some action in the main view.
My problem is that that action differs depending on a global class variable (Boolean) and from what I can tell the only way to access the viewController from the didRecieveLocalNotification is to recreate the view class as a new init alloc which would destroy the current value of said variable.
How do I call a viewController method from the appdelegate's didRecieveLocalNotification without destroying the variable or any content on the view.
Assuming the main viewController which you are referring to is the root view controller of your UIWindow which you should have in your app delegate, you can do the following.
[(viewController*)[self.window rootViewController] themethodyouwanttocall];
From the phrasing of your question, that should call a method on the root view controller from the app delegate.
I am building an iOS 5 app with oauth integrated. My storyboard consists of a container NavigationController, with a rootViewController, and two viewControllers segueing from the rootView. When the app is launched, i perform a check to see if an access token is present, and direct the user accordingly.
// rootViewController.m viewDidAppear (i need to perform this check anytime the user is brought to the root view, say for e.g. he logs-out.)
if (accessToken) {
BOOL didAuth = [GTMOAuthViewControllerTouch authorizeFromKeychainForName:#"app name: service" authentication:accessToken
if (didAuth){
//perform segue to main User View (which is a TableViewController)
}
else{
//perform segue to sign-in controller, and direct the user to main view from there.
}
}
I have a couple of questions:
Is such a setup 'valid' as per Apple's Interface Guidelines?
I noticed that the prepareForSegue method in rootViewController gets called after the mainUserView's (which is a TableViewController) viewDidLoad. Is this standard behavior? I understand that this is the case for popovers, but for segues from a standard ViewController to a TableViewController?
Thanks!
I need to launch a view from the delegate (and switch the selectedViewController).After the view switching I need to execute a view method from the delegate....How I can do that.
For mor precision this is the app delegate method.
-(void)launchOtherView{
NavigationCtrl *navCtrl = [self.rootController.viewControllers objectAtIndex:3];
PrimaryView *prmView;
//Need to lauch the view(navCtrl) .. for that it's ok..
//Now I need to get the first view of the navCtrl...
//After I need to execute a view method (someMethod:)
}
Thanks
Drop the navigation controller from the tools--->Library-->objects.
connect the navigation controller to its instance created in appdelegate class.
open MainWindow.xib and connect the file's owner delegate to instance of UINavigationController.
Drop the navigation controller object and inside atttach the view contoller which view you want to launch first.
All inside the implementation file of the will get executed.
In iOS4.2/iPhone4
Click icon to launch app (some view
controllers view is displayed)
Click iPhone Home button (return to
home screen)
double click Home button
Select previously launched app from
the selection
Now I can see that my app delegate gets a message "applicationDidBecomeActive" when its selected after the last step, but how does my viewController (the one who's view is currently displayed) know?
viewDidLoad was already called, so that isn't called again. viewWillLoad is not called again.
Can't seem to figure it out. Reason I'm asking is I want to check to see if any Settings changes were made, but would like to do that in the view controller cause that's the thing that cares.
The answer is here: Handling applicationDidBecomeActive - "How can a view controller respond to the app becoming Active?"
Use NSNotificationCenter to get notified of UIApplicationDidBecomeActiveNotification events in your view controller.
in you're appDelegate applicationDidBecomeActive put this :
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UINavigationController *navc = (UINavigationController *)[tabBarController selectedViewController];
UIViewController *topvc = [navc topViewController];
if ([topvc respondsToSelector:#selector(viewControllerDidBecomeActive)])
{
[topvc performSelector:#selector(viewControllerDidBecomeActive)];
}
}
This gets the viewController that is being seen on screen. You just have to implement viewControllerDidBecomeActive on every viewControllers ;)
In the appDelegate applicationDidBecomeActive set a boolean property marking that it just appeared from background.
Then in your viewcontroller, specifically in the viewDidAppear override, check for the appDelegate property, if its true then you know it has come from the background, otherwise it has just appeared as normal. BTW Afterwards, set the boolean property to false for neatness.
EDIT-
You would have to call viewDidAppear manually in the applicationDidBecomeActive unless you were re-creating your navigation stack. If you were able to get a pointer to the current visible view controller, then calling viewDidAppear should be a no fuss approach as all view controllers have this method. You wouldn't need any delegates or etc.