I'm making an applikation which is using push notifications, I am currently using pushbots for the push notifications. I was wondering if there is any way to intercept the notifications that is received by the application and check the notification before the notification is shown on the device. And if the data in the notification is not correct, dont show a notification at all? Is this possible with pushbot or do I need to do it all by my self?
Yes, you can achieve this behaviour playing around with Local Notifications.
You can configure your payload without an alert and "content-available": "1" so your application can receive notifications without showing them to the user.
// Payload
{
aps: {
"content-available": 1
},
text: 'my alert message' // your custom info
}
And in your app code, register notifications as
// Register notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
UIRemoteNotificationTypeNewsstandContentAvailability];
Then, the key is to trigger Local Notifications in the application:didReceiveRemoteNotification:fetchCompletionHandler: method based on some condition
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(#"push data package: %#", userInfo);
// Retrieve your data
NSString *text = [userInfo objectForKey:#"text"];
BOOL mustShow = YES;
// Only show notification if app is background and your custom condition
if ((state == UIApplicationStateInactive || state == UIApplicationStateBackground)
&& mustShow) {
// Raise the local notification a second after received
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
localNotification.alertBody = text;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
This way you can "intercept" the notifications before "displaying" them to the user.
You can't prevent the notification from being shown once it reaches the device (assuming it contains an alert field in the aps dictionary - if it doesn't, no notification will be shown anyway).
You should determine in your server which notifications should be sent to which device tokens. You can associate device tokens with users in your DB, if your functionality requires it.
Even if what you request was possible, it would be very inefficient to send notifications to all the devices that installed your app, and then only display the notification in a small subset of them.
Related
I am making an app in which user select time and video. When notification fire than I want that the select video should be played . How can i achieve that?
Here is my notification code.
-(void) scheduleLocalNotificationWithDate:(NSDate *)fireDate
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = fireDate;
localNotif.timeZone = [NSTimeZone localTimeZone];
localNotif.alertBody = #"Time to wake Up";
localNotif.alertAction = #"Show me";
localNotif.soundName = #"Tick-tock-sound.mp3";
localNotif.applicationIconBadgeNumber = 1;
localNotif.repeatInterval = NSCalendarUnitDay;
NSLog(#" date %lu",kCFCalendarUnitDay);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
Any Syggestion?
Your code for scheduling a local notification looks good. Probably you should also add some data in the userInfo property of the local notification, so that when it fires, you can check that property and do something different (play a specific video) according to the data inside the userInfo.
Example:
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"video1" forKey:#"videoName"];
localNotif.userInfo = infoDict;
Make sure that you also request user permission for using local notifications, otherwise the local notification will not fire.
Example:
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
Now you need to handle the firing of the local notification when your app is in the 3 states: foreground, background/suspended and not running.
The app is running in the foreground. The local notification fires at the date you set it to. The following delegate method will get called by the system in AppDelegate:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
NSString *videoName = [notification.userInfo objectForKey:#"videoName"];
//do something, probably play your specific video
}
The app is running in the background or is suspended. The local notification is shown to the user (it fired at the date you set it to) and the user taps on it. The same delegate method as above (didReceiveLocalNotification) will get called by the system in AppDelegate:
The app is not running, the local notification is shown to the user (it fired at the date you set it to) and the user taps on it. The following delegate method will get called by the system in AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif)
{
//the app was launched by tapping on a local notification
NSString *videoName = [localNotif.userInfo objectForKey:#"videoName"];
// play your specific video
} else {
// the app wasn't launched by tapping on a local notification
// do your regular stuff here
}
}
I would recommend reading Apple's documentation regarding working with local notifications.
You can use the Media Player framework as recommended in Glorfindel's answer and you can find an example for playing a video in this StackOverflow answer.
Once the user opens your local notification, your app will be launched, and the - application:didFinishLaunchingWithOptions: of your UIApplicationDelegate will be called. The options dictionary will contain a UIApplicationLaunchOptionsLocalNotificationKey key, which contains the UILocalNotification. That should give you enough information to determine which video needs to be played, which you can do with the Media Player framework.
My title might not accurately depict my question, so I apologize. I have looked for a solution to creating this level of functionality but I am unable to find it.
I am creating a VoIP application for iOS 8. When a user receives a call I am displaying a notification with a 12 second ringtone. While this notification is in progress if the call disconnects I want the Incoming Call notification to disappear and display a Missed Call notification immediately. This level of functionality is possible because Viber does it.
Currently, I am sending a silent push notification when a Incoming Call is available. This is my payload...
aps = {
"content-available" = 1;
};
category = INCOMING;
from = "+15555554220";
Upon receiving the silent push I am creating a Local Notification like this ...
if ([userInfo[#"category"] isEqualToString:#"INCOMING"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Incoming Call Notification Received");
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Sending Local Notification For Incoming Call");
// Get Caller Contact Info
NSDictionary *contact = [self findContactInfoForNumber:userInfo[#"from"]];
NSString *message = [NSString stringWithFormat:#"Incoming Call: %#",userInfo[#"from"]];
if (contact != nil) {
message = [NSString stringWithFormat:#"Incoming Call: %# %#",contact[#"firstName"],contact[#"lastName"]];
}
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithObject:#"Incoming Call" forKey:#"type"];
notification.userInfo = infoDict;
notification.category = #"INCOMING_CALL_CATEGORY";
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
notification.alertBody = message;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = #"ring.m4a";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
Then, once the call is disconnected I am sending another silent push notification for a missed call...
aps = {
"content-available" = 1;
};
category = MISSED;
Once received I am canceling all local notifications like this...
if ([userInfo[#"category"] isEqualToString:#"MISSED"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Missed Call Notification Received");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The issue I am encountering is that on the lock screen it behaves exactly the way I want it to. I receive the incoming call notification and when the caller hangs up that notification immediately disappears from notification center and a missed call notification is there in the place of it. However when the phone is on the home screen. A banner is shown and then it plays the whole ringtone then displays the missed call. Does anyone know the reason why this is happening? Does anyone have any solutions to achieve this level of functionality? Like I said before the app Vider is a prime example of what I want my app to do.
Thanks you in advance.
Hello everyone,
I am trying how to implement pushnotification.For this i have read apple official document for push notification and also read raywenderlich blog and i understand the flow of pushnotication very well. I have created development and production certificate,profile and its working fine and push was successfully sent and receiving in -
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
*** display message in uialertview******
}
but my problem is how can i display push in my device like other push notification on top up side for both when my application is foreground and background too.
currently i am trying for IOS 7.0 and XCode Version 5.1.1 (5B1008)
Thanks In advance.
First of all check via these methods in App Delegate that if your registered successfully to APNS.
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
}
then in
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *Notification = userInfo;
NSString *title = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"title"];
NSString *body = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"body"];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive || [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = body;
localNotification.fireDate = [NSDate date];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
If your application is in active state show UIAlertView. if its not you need to show a UILocalNotification.
When you are in Background mode then push notification will display as per your application notification settings from notification centre. you dont have to display ios will do that.
when you are in Foreground mode then notification will receive and -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo method will be called. so using this method you get userinfo. just NSLog userinfo dictionary and then you can create customview with label at top and animate it like ios default banner.
Hope this will help you.
As per Apple's note push/local notification will be display only when app is background mode. If notification is arrive at the time of app is on foreground/active then you need to manually manage it because iOS won't show a notification banner/alert That's default design.
I just put my logic here for manage notification when app in foreground mode:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// check the application state for app is active or not.
if (application.applicationState == UIApplicationStateActive)
{
// Nothing to do if applicationState is Inactive, the iOS already displayed an alert view.
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Receive a Remote Notification" message:[NSString stringWithFormat:#"Your App name received this notification while it was running:\n%#",[[userInfo objectForKey:#"aps"] objectForKey:#"alert"]]delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}
If you want to receive notification in top of the device like banner style then follow these steps.
First, you need to launch the 'Settings' app on your iOS device.
Once you're in, choose 'Notifications' from the list of options.
Here's a list of every app that supports push notifications. The ones at the top have been granted permission by you
You can also set the alert style. You can choose the banners that conveniently appear at the top of the screen, or full-on pop-ups that force you to take action before they go away. Or you can just choose 'None'.
For more detail check this link.
Hope you will get something from my answer.
I got my push notification successfully in both background and foreground but my problem is when my application is in active state/foreground and push notification is arrived then i show this pushnotification message on alertview using didReceiveRemoteNotification method,
My alert view have two buttons
1) later
2) Ok.
If I press 1) "later" button then I want add this pushnotification message in notification area so after some time user can see and tap on that particular push notification and go with that and that record of push notification will remove from notification area.
This is not possible. There is no API to access notification are of iOS.
Alternative
What near alternative you can try is Local Notification. When user select later set Local Notification for that thing. You can add this Local Notification when user leave your app so that you don't get notification while user is continue with your application.
Better Approach
The most general approach for this problem is Notification screen in app. Your application has one screen which has list of received notification so that user can check that in you app. I suggest you to go with this. Because this is most common and clear idea.
You need to implement core data for Notifications but it can only happen when your Application is is Active state.
1-create a new identity everytime a new notification arrive.
2-save it.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *Notification = userInfo;
NSString *title = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"title"];
NSString *body = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"body"];
XXNotification *objNotification = [XXNotification create];
objNotification.title = title;
objNotification.detail = body;
[XXNotification save:nil];
NSArray *arrNotification =[XXNotification allUnRead:nil];
[UtilityFunctions setApplicationBadgeNumber:[arrNotification count]];//Utility functions is my class for common functions.
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
[UtilityFunctions showAlertView:title message:body delegate:self cancelButtonTitle:#"Ok" otherButtonTitle:#"Cancel" withTag:99 withAccessibilityHint:[NSString stringWithFormat:#"%#:|:%#", title,body]];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive || [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = body;
localNotification.fireDate = [NSDate date];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
if (![IsLocationSaved isEqualToString:#"NO"])
{
[[NSNotificationCenter defaultCenter]postNotificationName:kNotificationForShowingNotification object: nil userInfo:nil];
}
}
}
On showing the UIAlertView, on its click event either delete that notification in DB or make a bool in it as isRead and make it YES. then save it,
On Notifications list Query the notification from DB or only those whose isRead = NO.
That is the way I did it in My Application.
I am developing iOS app with both Push notification and Local Notification, I know how to remove 1 and all notification from center,
using
[[UIApplication sharedApplication]cancelAllLocalNotifications];
But my problem is if i have scheduled some local notifications ,
and a push notification is arrived so in didReceiveRemoteNotification
I am write
[[UIApplication sharedApplication]cancelAllLocalNotifications]; for clear notification center,
but it is cleared all my LocalNotification also...
EDIT
if there are total 3 notifiction in NC i.e. 1 is come from local notification and two from push( from server) in this case how can i handle it,? i am tap on 1st notification( comes from server) in NC. in this case what should do, my app badge should be 2.
then what should i do?
The cancelAllLocalNotifications will only cancel the local notifications, its even in the name! Not the push notifications as you can read in the documentation:
Cancels the delivery of all scheduled local notifications.
Since push notifications are server side there is noting to cancel in your app. To remove the push notification from the notification center just set the applicationBadegNumber to 0.
There is an option ,each notification contains a dictionary inside it, so when you creates any local notification add any key in dictionary which specifies that this notification is for local notification.so you can check that if it is not my local notification then i will remove it.
-(void)scheduleLocalNotification{
[self cancelAlarm]; //clear any previous alarms
UILocalNotification *alarm = [[UILocalNotification alloc] init];
alarm.alertBody = #"alert msg";
alarm.fireDate = [NSDate dateWithTimeInterval:alarmDuration sinceDate:startTime];
alarm.soundName = UILocalNotificationDefaultSoundName;
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:#"localNotification" forKey:#"localNotification"];
alarm.userInfo = userInfo;
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
}
-(void)cancelNotification{
for (UILocalNotification *notification in [[[UIApplication sharedApplication] scheduledLocalNotifications] copy]){
NSDictionary *userInfo = notification.userInfo;
if (![self.key isEqualToString:[userInfo objectForKey:localNotification]]){
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
}
The applicationbadgenumber is managed by you. Deleting scheduled notifications will not change that number. You must manage that yourself. I gave a presentation a while back that might help. http://www.youtube.com/watch?v=ixQqZWtn0pg Start watching at 11:50.