I am recieving push notification from backend but unable to go to specific controller from the click of push notification.
My Code is:
In appDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary* payLoad = [[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:#"appsInfo"];
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
// [self.window makeKeyAndVisible];
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
//[self.window makeKeyAndVisible];
}
In didReceiveRemoteNotification method I have Written:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(#"didReceiveRemoteNotification");
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
// [self.window makeKeyAndVisible];
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"]; //or the homeController
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:loginController];
self.window.rootViewController = navController;
//[self.window makeKeyAndVisible];
}
}
On - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions you should set the root view controller.
And then on - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo you should use pushViewController or performSegue.
For e.g. -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *loginController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"];
self.window.rootViewController = navController;
}
And now when you receive notification -
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ([[payLoad objectForKey:#"type"] isEqual: #"COURSE_DISTRIBUTE"]){
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"EPAnalyticsViewController"];
[self.navigationController pushViewController:viewController]
} else if ([[payLoad objectForKey:#"type"] isEqual: #"ASSESSMENT_DISTRIBUTE"]){
UIViewController * viewController = [[UIStoryboard storyboardWithName:#"iphone_Storyboard" bundle:nil] instantiateViewControllerWithIdentifier:#"OUSTCardsViewController"];
[self.navigationController pushViewController:viewController]
}
}
Related
For messaging application.
The structure is
TabBarController -> NavigationController->View_One -> View_Two. Whenever user tab on notification, i need to redirect to View_2 from appdelegate.m [DidReceiveRemoteNotification method].
This current code helps me to land on View_One. How can i goto View_Two without affecting NavigationController and Tabbar controller functionality?
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateInactive||application.applicationState == UIApplicationStateBackground){
UIStoryboard *mainSB = [UIStoryboard storyboardWithName:MAIN_STORYBOARD bundle:nil];
UITabBarController *tabBarController = [mainSB instantiateViewControllerWithIdentifier:TAB_BAR_ID];
tabBarController.selectedIndex = 0;
[[UIApplication sharedApplication].keyWindow setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
}
Thanks in advance.
try this
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateInactive||application.applicationState == UIApplicationStateBackground){
UIStoryboard *mainSB = [UIStoryboard storyboardWithName:MAIN_STORYBOARD bundle:nil];
UITabBarController *tabBarController = [mainSB instantiateViewControllerWithIdentifier:TAB_BAR_ID];
tabBarController.selectedIndex = 0;
UINavigationController *nav = [tabBarController.viewControllers objectAtIndex:0];
View2 *destViewController = (View2*) [self.nav.viewControllers objectAtIndex:0];
[nav pushViewController:destViewController animated:YES];
}
Choice-2
I am not sure above method will work, in here we go for some hacky methods , In here as per your code follows we use NSUSerdefault concept
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateInactive||application.applicationState == UIApplicationStateBackground){
UIStoryboard *mainSB = [UIStoryboard storyboardWithName:MAIN_STORYBOARD bundle:nil];
UITabBarController *tabBarController = [mainSB instantiateViewControllerWithIdentifier:TAB_BAR_ID];
tabBarController.selectedIndex = 0;
[[NSUserDefaults standardUserDefaults]setObject:#"APNS" forKey:#"openVC"]
[[UIApplication sharedApplication].keyWindow setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
}
retrieve Like
- (void)viewDidLoad // or call in loadView Method
{
if ([[[NSUserDefaults standardUserDefaults]objectForKey:#"openVC"]isEqualToString:#"APNS"])
{
// Navigate to second VC
}
}
finally
on your secondVC
-(void)viewWillDisappear:(BOOL)animated
{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"openVC"];
[super viewWillDisappear:animated];
}
When user open the app it show login UIViewController. When user log in it redirect to next mapkit UIViewController. But when user open app again I would like that he will skip login UIViewController. How can I do that? I tried programatically redirect in login method viewWillAppear but it works bad(It show controller for second).
A better way is to add this check in the AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(isLoggedin) {
Storyboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *mapViewController = [storyboard instantiateViewControllerWithIdentifier:#"mapViewController" ];
self.rootViewController = [[UINavigationCotroller alloc] initWithRootViewController:mapViewController];
}
return YES;
}
Instead of checking the login in the viewWillAppear: method of the first view controller, do it in the didFinishLaunchingWithOptions: method of your application delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (loggedIn) {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController.topViewController performSegueWithIdentifier:#"1to2" sender:navigationController.topViewController];
return YES;
}
}
where 1to2 is the identifier of the segue from view controller 1 to 2.
You can do it like this:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// replace with your real auth-checking
if ([self wasAuthorized] == NO) {
[self showLoginController];
}
return YES;
}
- (UIViewController *)mainController {
UINavigationController *rootNavigationController = (UINavigationController *)[[self window] rootViewController];
return [[rootNavigationController viewControllers] firstObject];
}
- (void)showLoginController {
UIViewController *loginController = [self loginController];
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainController presentViewController:loginController animated:YES completion:nil];
});
}
- (UIViewController *)loginController {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
return [mainStoryboard instantiateViewControllerWithIdentifier:#"LoginNavController"];
}
I'm trying to select which ViewController the AppDelegate should display based in a NSUserDefaults BOOL. But the HomeViewController does not display.
I'm using Storyboards and I have my own class of UINavigationController.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
MeuNavigationController *nav = [[MeuNavigationController alloc]init];
if ([NSUD boolForChave:#"firstLogin"]==false) {
ViewController *viewC = [[ViewController alloc]init];
[nav pushViewController:viewC animated:NO];
}else{
HomeViewController *viewP = [[HomeViewController alloc]init];
[nav pushViewController:viewP animated:NO];
}
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
}else{
controller = [[HomeViewController alloc]init];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
You noted that you're doing this off of storyboard. You might want to consider making this change as well:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBLoginView class];
[FBProfilePictureView class];
// Name of storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = nil;
if ([NSUD boolForChave:#"firstLogin"]==false) {
controller = [[ViewController alloc]init];
// Set this in the storyboard's identity inspector
controller = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
}else{
controller = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
}
self.window.rootViewController = [[MenuNavigationController alloc] initWithRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
But you ask... Mr. jakenberg, how does one set their unique view controller identifier?
Cheers
Hi i am trying to make UINavigationController but not in mainViewController(first viewControllerClass) , i need to put UINavigationController in second class. But If i will write these codes in appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
// [window addSubview:[navigationController view]];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
Then UINavigationController appears in mainView. I am trying to put it in other class like that
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// strWhichTaleOnScreen=[masivTaleNames objectAtIndex:indexPath.row];
NSString *selectDay;
selectDay=#"first string";
NSLog(#"selecDay=%#",selectDay);
classDetailOfMessagesViewController *nesneDetailOfMessagesViewController = [[classDetailOfMessagesViewController alloc] initWithNibName:#"classDetailOfMessagesViewController" bundle:nil];
nesneDetailOfMessagesViewController.selectDay = selectDay;
[navigation pushViewController: nesneDetailOfMessagesViewController animated:YES];
nesneDetailOfMessagesViewController = nil;
}
But it doesn't work, I guess i have to create rootViewController in this second view but i dont know how.
I ll be happy if someone can show me way to solve it out.
The first mistake i saw was you are trying to set the window rootviewcontroller twice. The view hierarchy needs to be like window->navigation controller->view controller. so I made some changes with your code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
In the second code sample I couldn't find the reference to the navigation. And also if you push (in your case initWithRootViewController) a view controller to navigationcontroller stack you can access the navigation controller by self.navigationController so your second part of the code should be like this;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectDay;
selectDay=#"first string";
NSLog(#"selecDay=%#",selectDay);
classDetailOfMessagesViewController *nesneDetailOfMessagesViewController = [[classDetailOfMessagesViewController alloc] initWithNibName:#"classDetailOfMessagesViewController" bundle:nil];
nesneDetailOfMessagesViewController.selectDay = selectDay;
[self.navigationController pushViewController: nesneDetailOfMessagesViewController animated:YES];
}
I have 2 ViewController. loginViewControl which sets to rootViewControoler :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = loginViewControl;
[self.window makeKeyAndVisible];
return YES;
}
And I create StatusViewController :
*.h
#interface StatusViewController : UIViewController<UITabBarControllerDelegate>
{
IBOutlet UITabBarController *tabBarController;
IBOutlet UIButton *UploadButton;
IBOutlet UIButton *ConvertorButton;
IBOutlet UIButton *CompletedButton;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Now I want to push StatusViewController from loginViewControl(rootviewcontroller).I used below code but it not work.
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]init];
[self.navigationController pushViewController:statusView animated:YES];
[statusView release];
}
Do you have any suggestions? Thanks in advance
You not setting UINavigationViewcontroller at the didFinishLaunchingWithOptions of Window's RootViewcontroller, We can't Push a UIViewController without UINavigationViewcontroller
So First Set LoginViewController as a RootViewController of UINavigationViewcontroller like Bellow:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[YourLoinViewcontroller alloc] initWithNibName:#"YourLoinViewcontroller" bundle:nil];
UINavigationController *objNavigationController=[[UINavigationController alloc]initWithRootViewController:loginViewControl];
self.window.rootViewController = objNavigationController;
[self.window makeKeyAndVisible];
return YES;
}
EDIT
Connect your StatusViewcontroller's view with File owner like bellow:-
your push method like this:-
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES];
}
Unless your login view controller is a navigation controller, self.navigationController in statusButtonClick will return nil and so this won't work.
Maybe you can try:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:loginViewControl];
[self.window makeKeyAndVisible];
return YES;
}
This will enclose a loginViewController in a navigationController which will permit you to push another viewController in the navigationController's stack.
- (IBAction)statusButtonClick:(id)sender; {
// If used StoryBoard
UIStoryboard *story=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
StatusViewController *statusView = [story instantiateViewControllerWithIdentifier:#"StatusViewController"];
[self.navigationController pushViewController:statusView animated:YES];
// If used XIB
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES]; }