Is it possible to open concrete viewcontroller when user tap on push notification?
I have news app, main view controller have a lot of news, and when user tap on some new I open next viewcontroller with description of this news.
When user tap push notification, how I can open second view controller?
I tried to send Notification to my UINavigationController and push two controllers, but it doesn't work fine, it open only first viewcontroller.
you can handle your app, when you tap a local or push notification, implementing the application:didReceiveLocalNotification: or application: didReceiveRemoteNotification: method in your AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
}
If your app it's closed (not in background) you can verify if you received a notification in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *userInfo = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if ( userInfo != nil )
[self application:application didReceiveRemoteNotification:userInfo];
}
I don't know how you are handling your news but you can post a notification to your main view controller informing that you have receive a notification, passing the "id" or the info of your new and then create your second view controller (you will need to verify if your MainViewController is already created in the stack of your NavigationController):
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[NSNotificationCenter defaultCenter] postNotificationName:#"IHaveReceivedANotification" object:nil userInfo:userInfo];
}
Related
I have implemented everything correctly in my app to receive push notifications, i'm receiving the notifications just fine, but how can i do something when the user clicks on it?
Here's my code regarding the matter:
AppDelegate.m:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"Received notification: %#", userInfo);
NSLog(#"Hello from appDelegate");
}
It's working, i'm getting the userInfo and the other message in my Xcode log.
Now i want to do something (go to a specific segue) when the user clicks on the notification. I have seen the docs but it's very complicated and hard to follow.
I just need to know what function to use in the MainViewController.m
Any hints? thanks in advance.
You can post notifications (Using NSNotificationCenter) from AppDelegate on different events and then add observer in particular classes where ever you want to perform a particular operation.
Code Implementation
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSString *aStrEventType = userInfo[#"eventType"];
if ([aStrEventType isEqualToString:#"callWebService"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"callWebService" object:nil];
}else{
// Implement other notification here
}
}
Now in your particular class you can handle notification as follows.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:#"" selector:#selector(callMyWebService) name:nil object:nil];
}
-(void)callMyWebService{
//Perform your action.
}
In my application I have two types of push notifications: remote silent notifications with content-available = 1 flag and usual push notifications with body, badge and other stuff.
I also define two delegate methods didReceiveRemoteNotification:fetchCompletionHandler and usual didReceiveRemoteNotification.
But when a push-notification without content-available flag arrives didReceiveRemoteNotification:fetchCompletionHandler is called, instead of didReceiveRemoteNotification.
How to fix this?
Why can't I have two delegate methods for background and usual pushes?
iOS 7 only calls the new one, this is how I handled it in my app:
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// Pass on
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:nil];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Check if in background
if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) {
// User opened the push notification
} else {
// User hasn't opened it, this was a silent update
}
}
Is there a way to know if the app was started by tapping message in notification center?
I want to make some calls to server only if the app is started by tapping on a message in notification center.
In - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method of the application delegate, you will receive the notification information in the launchOptions dictionary. That way you could get to know that the app was launched from the notification tray.
Yes you can find application launching reason in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// keys can be UIApplicationLaunchOptionsLocalNotificationKey
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if(notificationPayload)
{
// application launch because of notification
// do some stuff here
}
return YES;
}
You can handle push notification like
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *pushNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushNotification) {
//Application did started by clicking push notification. Do whatever you want to do
}
....//Your rest code
....
}
Some times application is in active state and still we want to handle push notification than below method will be called
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//Application did receive push notification. Do whatever you want to do
}
I want to make such function:
When the notification of my app is fired, like the following image:
I swipe the app icon in the bar to the right, and the app should run and show a certain view.
But I don't know how to do it.
In my application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions, I write:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSString *objectIDURL = [localNotif.userInfo objectForKey:#"objectIDURI"];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
EventViewController *eventViewController = [storyboard instantiateViewControllerWithIdentifier:#"EventViewController"];
[eventViewController setEvent:[Event getEventByObjectIDURL:objectIDURL]];
[(UINavigationController*)self.window.rootViewController pushViewController:eventViewController animated:NO];
}
return YES;
}
But after my swiping the icon to the right, my app does not run at all.
Can anyone help?
Plus, I'm using storyboard, I don't know is it relevant.
You never said if this was a local or remote notification, but the messaging works pretty much the same for both. You must keep in mind that the system notifies you differently if the app is running, or if its not running. That is, if you double click the home button and see the app's icon at the bottom, then its "running" (my terminology).
What you need to do is make sure you have all the relevant delegate methods implemented, and please, NSLog every one of them, so you can verify which are being messaged as you test. Copy and paste them from UIApplication.h, so that you don't have a typo (that is, a misspelling, as the system gives you no warnings on these!)
Implement all of the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// if launched due to a notification, you will get a non-nil launchOptions
NSLog(#"didFinishLaunchingWithOptions: launchOptions=%#", launchOptions);
...
}
// if using remote notifications
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// Better get this for remote notifications
NSLog(#"didRegisterForRemoteNotificationsWithDeviceToken: token=%#", deviceToken);
...
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"YIKES! didFailToRegisterForRemoteNotificationsWithError");
...
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// if already running, notification came in
NSLog(#"didReceiveRemoteNotification: userInfo=%#", userInfo);
...
}
// if using local notifications
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// if already running, notification came in
NSLog(#"didReceiveLocalNotification: notification=%#", notification);
...
}
Is there any way to redirect to a View once the user opens the App from the Notification Center considering that the App was just launched before the action. (App is still running in the background)
Example, I launch the App normally, press the home button. Then I received a number of remote notifications, and then I open the app anywhere from that push notification.
Since I have different push notifications that could redirect to any part of my App. I want that the redirect would still work not only in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
is it possible that I could still access the remote notification (json data within) during application becomes active? so that I could do some redirection. And also, so that the user can just run through the remote notifications he have in the center, and will be redirected to the proper view depending on what notification the user tapped.
Update
Another Example:
(1)User receives the 2 push notifications in application: didReceiveRemoteNotification: (2)User is redirected with the first push notification. (3)User goes to his notification center (4)taps the other notification. Will he still be redirected? I don't think the app won't go inside in either application:didReceiveRemoteNotification: or application: didFinishLaunchingWithOptions:
Yes, you can, here is a simple outline/sample
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//When notification is pressed on background it will enter here
//Get strings based on information on your json payload for example
if([[userInfo objectForKey:#"keyword"] isEqualToString:#"value"]){
//redirect/push a screen here for example
}
}
There is User info associated with DIDReceiveRemoteNotification Method... You can use it following delegate method.
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary* userInfo =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo) {
[self processRemoteNotification:userInfo];
}
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self processRemoteNotification:userInfo];
}
After that in user info there is key called APS and you can use that with following method.
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
After that you can get every element from the pay load of APNS and decide which view to redirect to.
Yes you could.
The following delegate method will be called once you receive the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;