Navigate to particular view controller when user tap the notification IOS7 - ios

Hi i have added push notification in my application and I want to view particular ViewControllers when the user tap the notification. In my app delegate m file I'm trying to get the register the device token to my server and from my server I'm using the php script to get the device token from server and I'm sending the notification.
The problem here I'm trying to view a particular view controller when the user taps on the notification its not working i have tried many different methods nothing had worked.
Here I'm view the popup like to send notification from the app when user trying to install application for the first time.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)];
return YES;
}
- (void) clearNotifications {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
Here I'm storing the device to token to my server.
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
const char* data = [deviceToken bytes];
NSMutableString * token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
NSString *urlString = [NSString stringWithFormat:#"url?token=%#",token];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSLog(#"token %#",urlString);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSLog(#"request %# ",urlRequest);
NSData *urlData;
NSURLResponse *response;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
NSLog(#"data %#",urlData);
[self clearNotifications];
// NSLog(#"token ",sendUserToken);
}
Here I'm trying to view the particular method when user tap the notification.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
updatepoliticalViewController *ringingVC = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"updatepoliticalViewController"];
[self.window.rootViewController presentViewController:ringingVC animated:YES completion:NULL];
}
My particular view controller name is updatepoliticalViewController its a navigation view controller please tell me in this above code where I'm doing wrong how to resolve this issue.
Thanks

When the app is in foreground state it call
application:didReceiveRemoteNotification:
but if it's not and the app is launched, for example, by swiping the alert in notification center
application:didFinishLaunchingWithOptions:
is called with key.
The good way is to call
application:didReceiveRemoteNotification:
from
application:didFinishLaunchingWithOptions:
I believe this should help
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
// YOUR CODE...
return YES;
}
// EXTENDED
Try get storyboard like that:
// Make sure the name match
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
Create your object from mainstoryboard:
updatepoliticalViewController *ringingVC = [mainstoryboard instantiateViewControllerWithIdentifier:#"updatepoliticalViewController"];
And try set new root view controller
[self.window setRootViewController: ringingVC];

1) When application is running in background and When application is running in foreground
application:didReceiveRemoteNotification: method will called as below.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive)
{
//opened from a push notification when the app was on background
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
else if(application.applicationState == UIApplicationStateActive)
{
// a push notification when the app is running. So that you can display an alert and push in any view
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
}
2) When application is not launched (close) than application:didFinishedLaunchWithOptionsmethod will called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions != nil)
{
//opened from a push notification when the app is closed
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil)
{
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
}
else{
//opened app without a push notification.
}
}

Related

iOS, force quit app first, after tapping the receiving notification banner, app launch failed

I use APNs to send the notifications to my app. But my app does not work well when I did the following steps:
steps
swipe the app to force quit (app is not running, not in background mode ..)
send the notification from APNs
got the notification on my iPhone and I tapped the notification banner
app seemed to try to launch(showed the launch image), but launched fail (crash?)
my app can receive notification foreground and background.
Tap the notification banner in background then it can bring app to foreground then go to the view I wrote, everything works fine.
Except force quit the APP
here is my code in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController
containerWithCenterViewController:[self navigationController]
leftMenuViewController:leftMenuViewController
rightMenuViewController:rightMenuViewController];
self.window.rootViewController = container;
[self.window makeKeyAndVisible];
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
// Define an ID string to be passed back to your app when you handle the action
acceptAction.identifier = #"MARK_AS_READ_IDENTIFIER";
// Localized string displayed in the action button
acceptAction.title = NSLocalizedString(#"Mark as Read", nil);
// If you need to show UI, choose foreground
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
// Destructive actions display in red
acceptAction.destructive = NO;
// Set whether the action requires the user to authenticate
acceptAction.authenticationRequired = NO;
// First create the category
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
// Identifier to include in your push payload and local notification
inviteCategory.identifier = #"actionCategory";
// Add the actions to the category and set the action context
[inviteCategory setActions:#[acceptAction]
forContext:UIUserNotificationActionContextDefault];
// Set the actions to present in a minimal context
[inviteCategory setActions:#[acceptAction]
forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObject:inviteCategory];
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert) categories:categories]];
// for calling didReceiveRemoteNotification when app first launch
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"Device token: %#",deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Fail to get device token: %#", error);
}
// tap the backgraund banner button
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)newUserInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:#"MARK_AS_READ_IDENTIFIER"]) {
// when tapping the background banner's button will mark the notification status to read
[Functions updateComingNotificationToRead];
}
if (completionHandler) {
completionHandler();
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
//NSLog(#"Notification received: %# %#", newUserInfo,[newUserInfo objectForKey:#"aps"] );
userInfo = newUserInfo;
NSString *alertMessage = [[newUserInfo objectForKey:#"aps"] objectForKey:#"alert"];
UIApplicationState state = [application applicationState];
UIAlertView *alertView = nil;
// for background banner use
switch (state) {
case UIApplicationStateActive: // when app is alive, show alert to notify user
alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(#"SmartHome",nil) message:NSLocalizedString(alertMessage,nil) delegate:self cancelButtonTitle:NSLocalizedString(#"Close",nil) otherButtonTitles:NSLocalizedString(#"Open",nil),NSLocalizedString(#"Mark as Read",nil), nil];
[alertView show];
break;
case UIApplicationStateBackground: // app is in background mode
// user tap the banner or tap the mark as read button, code will go here
[Functions addNotificationDataInDatabase:[newUserInfo objectForKey:#"uniqueID"] type:[newUserInfo objectForKey:#"deviceType"] event:[newUserInfo objectForKey:#"event"] time:[newUserInfo objectForKey:#"time"] read:#"0" description:alertMessage];
break;
case UIApplicationStateInactive: // tapping the banner
//NSLog(#"UIApplicationStateInactive");
// go to notification view
// because will go to the notification view detail, set status to read
[self gotoNotificationView:userInfo]; //uniqueID
break;
default:
break;
}
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
handler(UIBackgroundFetchResultNoData);
// send post notification for updating the badge, will get the notification in foreground
[[NSNotificationCenter defaultCenter] postNotificationName:#"APNsNotification" object:self userInfo:nil];
}
Does anyone have this problem before? Did I miss something?
Please help me!!
u can put alert and check launchOptions
if (launchOptions) {
if ([launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
[self application:self didReceiveRemoteNotification:[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
}];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
NSString *str = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
}
}

Examine iOS Push Notification Payload

I'm trying to figure out how I can examine the payload of a push notification in order to determine which view opens when a user opens the app from the notification. For example, if a notification says "x: test" view x would open when the notification is tapped and if the notification says "y: test" view y would open.
EDIT: I guess I should clarify the part I'm not sure about.
I have this in didFinishLaunchingWithOptions:
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification)
{
// check payload then load appropriate view controller
}
How would I check the payload for certain text in order to determine the appropriate view controller to load?
Here is my code from a past project. The notification shows up in device like this "Kostas: wants to add you as friend".
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
NSDictionary *remoteNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif) {
NSString *name = [[NSString alloc] init];
NSString *message = [[NSString alloc] init];
// 'wants to add you as friend.'
NSString* alertValue = [[remoteNotif valueForKey:#"aps"] valueForKey:#"alert"];
NSMutableArray* parts = [NSMutableArray arrayWithArray:[alertValue componentsSeparatedByString:#": "]];
name = [parts objectAtIndex:0];
[parts removeObjectAtIndex:0];
message = [parts componentsJoinedByString:#": "];
if ([message isEqualToString:#": wants to add you as friend."]) {
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
// tabController.delegate = self;
tabController.selectedIndex = 1;
}
else{
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
// tabController.delegate = self;
tabController.selectedIndex = 2;
[self addMessageFromRemoteNotification:remoteNotif updateUI:NO];
}
Receiving a push notification is handled in two places in the app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions when your app is launched from a push notification. In this case, your push notification data is contained within [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo when your app is running when receiving the notification. In this case, userInfo is your push notification data.

get messages when user is offline in ios at quickblox

I am using chat api for IOS of quickblox in my project, chat application, now everything is ok... When the user is online, or the application not removed from background he is getting push notifications and messages in chat page.. but when the application is removed from background, he is getting push notifications, but the message doesnt appear in the chat page it's appear only in the push notification... I sent my problem to quickblox support, they gave me a code to replace in my project, now my problem code is here:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
// Override point for customization after application launch.
cManager = [ConnectionManager sharedMannager];
[cManager sendNetworkIdUpdate:[[DataManager sharedCenter]currentnetworkIdentifier]];
[QBSettings setApplicationID:-----];
[QBSettings setAuthorizationKey:#"--------"];
[QBSettings setAuthorizationSecret:#"--------"];
[QBSettings setAccountKey:#"--------"];
[cManager getBlockedList];
if (launchOptions != nil) {
NSLog(#"Launched from push notification");
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSLog(#"%#",launchOptions);
[[DataManager sharedCenter]setPushData:[notification valueForKeyPath:#"aps.user_info"]];
// Do something with the notification dictionary
}
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application{
if ([[[DataManager sharedCenter]currentUser]userChatId]){
[QBUsers logOutWithDelegate:[ChatService instance]];
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if ([[DataManager sharedCenter]chat_user] != nil) {
[[QBChat instance] loginWithUser:[[DataManager sharedCenter]chat_user]];
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
BOOL isLoggedIntoChat = [[QBChat instance] isLoggedIn];
if (isLoggedIntoChat) {
[[QBChat instance] logout];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
if ([[UIApplication sharedApplication]applicationIconBadgeNumber]>0){
[UIApplication sharedApplication].applicationIconBadgeNumber=0;
[cManager clearBadge];
}
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
/*if ([[[DataManager sharedCenter]currentUser]userChatId]){
[QBUsers logOutWithDelegate:[ChatService instance]];
}*/
if ([[LocalStorageService shared]messagesHistory] && [[[DataManager sharedCenter]currentUser]userId]){
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[[LocalStorageService shared]messagesHistory]];
[[[DataManager sharedCenter]defaults]setObject:data forKey:[NSString stringWithFormat:#"%#%#",[[[DataManager sharedCenter]currentUser]userId],kMessageHistoryBlock]];
[[[DataManager sharedCenter]defaults]synchronize];
}
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString* devToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"Update Token: %#",devToken);
[cManager sendPushTokenUpdate:devToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(#"Opend from push notification");
NSLog(#"%#",userInfo);
UIApplicationState state = [[UIApplication sharedApplication]applicationState];
if (state != UIApplicationStateActive){
if ([userInfo valueForKeyPath:#"aps.user_info"]){
[[DataManager sharedCenter]setPushData:[userInfo valueForKeyPath:#"aps.user_info"]];
[[NSNotificationCenter defaultCenter]postNotificationName:kShowPush object:nil];
}
}
[[NSNotificationCenter defaultCenter]postNotificationName:kUpdateTables object:nil];
[cManager clearBadge];
}
and the problem is still appearing ! , any help please ?
You have to do proper Chat logout. Server should know for sure that your user is offline
First of all, refer to the Chat in background mode documentation http://quickblox.com/developers/SimpleSample-chat_users-ios#Chat_in_background_mode
Try to do chat logout in applicationWillTerminate and applicationDidEnterBackground:
- (void)applicationWillTerminate:(UIApplication *)application
{
[[QBChat instance] logout];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[QBChat instance] logout];
}

Updating the badge number in a UITabBarItem

I'm developing a iOS app that manage Push Notifications. When a push comes up, the app badge is looking good, but where I'm having trouble is on the badges that appear inside the app. With inside the app i mean in the UITabBarItems that the app manages.
The app has a TabBarController where in two UITabBarItems a badge has to increment depending on wich Push Notification appeared. That is correctly handled in the server side, as I debuged and the push badge numbers comes ok. The thing is that the tab bar items are not updating ok.
Here's some part of my code:
This all happens inside de AppDelegate.m
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *user = [defaults stringForKey:#"id"];
if (user){
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"tabbar"];
self.window.rootViewController= viewController;
}
return YES;
}
And here's where I handle the push and update the badges in the uitabbaritem:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Notify UAInbox to fetch any new messages if the notification
// contains a rich application page id.
if (application.applicationState != UIApplicationStateBackground) {
UA_LINFO(#"Received remote notification: %#", userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshRequests" object:nil];
NSString* type = [userInfo objectForKey:#"type"];
if ([type isEqualToString:#"s"]){
[[[[(UITabBarController*)self.window.rootViewController viewControllers]
objectAtIndex: 2] tabBarItem] setBadgeValue:[[userInfo objectForKey:#"particularBadge"] stringValue]];
}else{
[[[[(UITabBarController*)self.window.rootViewController viewControllers]
objectAtIndex: 0] tabBarItem] setBadgeValue:[[userInfo objectForKey:#"particularBadge"] stringValue]];
}
}else{
// Notify UAPush that a push came in with the completion handler
[[UAPush shared] handleNotification:userInfo
applicationState:application.applicationState
fetchCompletionHandler:completionHandler];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshRequests" object:nil];
[self clearNotifications];
}
When I debug it, the badge in [[userInfo objectForKey:#"particularBadge"] stringValue] is 1 for example, but when the code finished passing over there the uitabbaritem doesn't update. Sometimes it works ok, but others it doesn't and I can't figure out why.
When the app launches it asks if the user is logged..If not the self.window.rootviewController is a LoginViewController. I don't know if this information should be important.
Any help would be appreciated!

Swiping push notification away should open related news

I'm new to iPhone development, but managed to receive push notifications in my iOS App. However, when I swipe away the incoming push notification, it just opens the app, but not the related post to the notification.
This is my code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(#"Eine Nachricht ist angekommen, während die App aktiv ist");
NSString* alert = [[userInfo objectForKey:#"aps"] objectForKey:#"id"];
NSLog(#"Nachricht: %#", alert);
//This is to inform about new messages when the app is active
//UIApplicationState state = [[UIApplication sharedApplication] applicationState];
//if (state == UIApplicationStateActive) {
// UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Neuer Artikel" message:#"Nachricht" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
// [alertView show];
// }
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"Device Token=%#", deviceToken);
NSUInteger theCount = [deviceToken length];
NSMutableString *theString = [NSMutableString stringWithCapacity:2 * theCount];
unsigned char const *theBytes = [deviceToken bytes];
for(NSUInteger i = 0; i < theCount; ++i) {
[theString appendFormat:#"%2.2x", theBytes[i]];
}
NSString* url = [NSString stringWithFormat:#"HERE_IS_MY_REGISTERING_URL",theString,theString];
NSLog(#"APNS URL : %#",url);
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *urlResponse, NSData *data, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
}
}];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(#"Error bei der Registrierung");
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window.frame = [[UIScreen mainScreen] bounds];
[self setApplicationDefaults];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
//This is the start of the push notification settings
[self.window makeKeyAndVisible];
Now, I have no Idea what to put where, to open a related post to a push notification...
What do you expect? From your code, I can not see that you are providing any information about which post you want to be opened. Neither Apple, nor Xcode, or your code will know that by magic.
In your payload for the push notification, you must provide information what post you are referring to, and then read this information in your didReceiveRemoteNotification.
See: "Examples of JSON Payloads" here: Apple Push Notification Service

Resources