Issue with implementing badges in ios - ios

I am working in ios app in phonegap with pushnotification.i have added the below code in Appdelegate+notification.m
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
PushPlugin *pushHandler = [self getCommandInstance:#"PushPlugin"];
[pushHandler didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"didReceiveNotification");
// Get application state for iOS4.x+ devices, otherwise assume active
UIApplicationState appState = UIApplicationStateActive;
if ([application respondsToSelector:#selector(applicationState)]) {
appState = application.applicationState;
}
if (appState == UIApplicationStateActive) {
PushPlugin *pushHandler = [self getCommandInstance:#"PushPlugin"];
pushHandler.notificationMessage = userInfo;
pushHandler.isInline = YES;
[pushHandler notificationReceived];
} else {
//save it for later
self.launchNotification = userInfo;
}
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + [[[userInfo objectForKey:#"aps"] objectForKey: #"badge"] intValue];
}
I am using pushNotification.java file for sending push message to our application in that i have mentioned payload.addBadge(1);
So in my app badge gets update onclick of notification Please suggest me how to do it while receiving notification

Related

how to handle Notification when app State is UIApplicationStateInactive

I am using following code to handle push notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if(application.applicationState == UIApplicationStateInactive)
{
//************************************************************
// I only want this called when user click on notification.
//************************************************************
NSLog(#"Inactive");
if ([[userInfo valueForKey:#"noty_type"] isEqualToString:#"web"])
{
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[userInfo valueForKey:#"url"]]])
{
dispatch_async(dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[userInfo valueForKey:#"url"]]];
});
}
}
}
if((application.applicationState == UIApplicationStateActive)
{
// I am useing local notification when app in Forground
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.soundName = #"Default";
localNotification.alertBody = [userInfo valueForKey:#"msg"];
localNotification.userInfo = userInfo;
[[UIApplication sharedApplication] scheduleLocalNotification: localNotification];
}
}
This code open the url in safari browser. this code work fine When my app in background and notification come and I click on notification check the applicationState and open the url with [[UIApplication sharedApplication] openURL.
now the scenario that generate the problem.
I open my app .
and Down the notification UI
now Send the notification from server
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler method get called.
Now I get the ApplicationState == UIApplicationStateInactive .
"It open into the safari browser without any user interaction".
I only want this called when user click on notification.
So, How can I handle this condition ?
Try this.
if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground)
{
// do something when app open with notification
}
You have to know why the app is inactive. The two possibilities are that the app was in the background and the user is bringing it to the foreground (by tapping on the notification banner), or something like the notification center was pulled down or the user got a system alert.
To tell the difference, keep track of when the user enters the background. Just set a boolean in the applicationDidEnterBackground: delegate method, and clear it when the app is resigning active.
static BOOL didEnterBackground;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Launching the app is kind of like coming from background.
didEnterEnterBackground = YES;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
didEnterBackground = NO;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
didEnterBackground = YES;
}
Now you can check the variable didEnterBackground to determine how the app got to the inactive state when you're handling a notification.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
if (application.applicationState == UIApplicationStateInactive) {
if (didEnterBackground) {
// The user tapped the notification
}
else {
// The app was inactive, but not in the background.
// Ignore notification, or do whatever the app does
// when receiving a notification while active.
}
}
}
Hope this help you
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
}//iOS below 9
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(nullable NSString *)identifier
forLocalNotification:(nonnull UILocalNotification *)notification
completionHandler:(nonnull void (^)())completionHandler {
// handling local and interactive notifcation
} // iOS 9 and above
Which is used to trigger the notification in background state.

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"];
}
}

Update badge icon when app is in background/suspended mode

I want to update application badge icon when a notification is received. It works fine when app is running (active mode),but having trouble when trying to set it when app is in suspended/background mode. Want to achieve the same without using the 'badge' field in apns dictionary.
Here is what i am doing,
-(void) incrementOneBadge{
NSInteger numberOfBadges = [UIApplication sharedApplication].applicationIconBadgeNumber;
numberOfBadges +=1;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:numberOfBadges];
}
-(void) decrementOneBadge{ NSInteger numberOfBadges = [UIApplication sharedApplication].applicationIconBadgeNumber;
numberOfBadges -=1;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:numberOfBadges];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
}
else {
// Push Notification received in the background
[self incrementOneBadge];
}
[self handlePushNotificationsForState:application withDictionary:userInfo];
}

Parse pushnotificaton not displaying in iOS?

I have configured parse and send pushnotification form there (both plain text and json)
then inside my project this methode get called
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
if (application.applicationState == UIApplicationStateInactive)
{
[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}
[PFPush handlePush:userInfo];
NSLog(#"----notify-->%#",userInfo);
sharedManager=[Mymanager sharedManager];
THNotificationData *newNotification=[[THNotificationData alloc] init];
newNotification.notificationDetails = [userInfo objectForKey:#"description"];
NSLog(#"%#",[userInfo objectForKey:#"description"]);
newNotification.notificationTitle = [userInfo objectForKey:#"title"];
newNotification.notificationURL = [userInfo objectForKey:#"url"];
sharedManager.notificationTitle=[userInfo objectForKey:#"title"];
sharedManager.notificationDetails=[userInfo objectForKey:#"description"];
sharedManager.notificationURL=[userInfo objectForKey:#"url"];
newNotification.isRead = NO;
newNotification.timeStamp = timestamp;
[notificationStore addNotificationData:newNotification];
[[NSNotificationCenter defaultCenter] postNotificationName:kParseNotificationKey object:nil userInfo:userInfo];
}
i can see then message in log also but after that i got warning in log
"2015-01-07 11:26:08.991 PROJECT[325:35376] Warning: Application delegate received call to -application:didReceiveRemoteNotification:fetchCompletionHandler: but the completion handler was never called."
and it didnt showing notification in phone(as a popup or alert).
please help me
You have to implement this (Its just an example method):
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if(application.applicationState == UIApplicationStateInactive) {
NSLog(#"Inactive");
completionHandler(UIBackgroundFetchResultNewData);
} else if (application.applicationState == UIApplicationStateBackground) {
NSLog(#"Background");
completionHandler(UIBackgroundFetchResultNewData);
} else {
NSLog(#"Active");
completionHandler(UIBackgroundFetchResultNewData);
}
}
Hope this helps.. :)

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];
}

Resources