The code to register for notifications is:
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
And the code to schedule the notification:
UILocalNotification *notification = [[UILocalNotification alloc] init];
[self setNotificationTypesAllowed];
if (notification)
{
if (allowNotif)
{
notification.timeZone = [NSTimeZone defaultTimeZone];
if ( [statusString isEqualToString:#"daily"]) {
notification.fireDate = _timePick.date;
notification.repeatInterval = NSCalendarUnitDay;
}else if ( [statusString isEqualToString:#"weekly"]) {
notification.fireDate = _timePick.date;
notification.repeatInterval = NSCalendarUnitWeekOfYear;
}else if ( [statusString isEqualToString:#"fortnightly"]) {
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60*60*24*14];;
notification.repeatInterval = NSCalendarUnitMinute;
//notification.repeatInterval = NSCalendarUnitYear;
}else{
notification.repeatInterval = 0;
}
}
if (allowsAlert)
{
notification.alertBody = [NSString stringWithFormat:#"Do you really want to send message to %#",name];
}
if (allowsBadge)
{
notification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
}
if (allowsSound)
{
notification.soundName = UILocalNotificationDefaultSoundName;
}
notification.alertAction = #"Yes";
notification.timeZone = [NSTimeZone defaultTimeZone];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showSMS) name:#"showSMS" object:nil];
// this will schedule the notification to fire at the fire date
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
I am able to repeat local notification daily & weekly but it is not repeating fortnightly ,please help
Yes as #Nikos suggested, try below code:
Cancel UILocalNotification.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Schedule local notification
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.userInfo = #{#"notification_identifier":#"After14Days"};
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:(60*60*24*14)];
notification.alertBody = #"Text to display";
notification.repeatInterval = NSCalendarUnitDay;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
If you have any doubt then let me know.
To set a notification to fire every 14 days you have to create 26 separate UILocalNotifications with the repeatInterval set to NSYearCalendarUnit (the repeat interval must be set to a calendar unit, and there is no 14 days CalendarUnit in iOS).
Another way to handle it is to cancel the UILocalNotification in the didReceiveLocalNotification method and schedule a new one there for after 14 days. This method though assumes that the user interacts with the notification, otherwise the next one will never get scheduled.
Related
I created a Local Notification that triggers 60 seconds when a certain button(SetButton) is clicked. My problem right now is if SetButton is pressed again, it does not override the first press, it displays 2 notifications and so on. How do I make sure that the second press of the button overrides the first press and there isn't a build up of notifications ?
- (IBAction)SetButtonPressed:(id)sender {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
localNotification.alertBody = #"HEY GET UP";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
}
My AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if ([UIApplication instanceMethodForSelector: #selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
if (localNotification) {
application.applicationIconBadgeNumber = 0;
}
}
If you only use notifications for that specific action you could cancel all notifications at once using
[[UIApplication sharedApplication] cancelAllLocalNotifications];
It looks like you only have one type of local notifications in your app.
In that case you could keep it simple. Whenever you want to schedule a new one - cancel the previous one.
- (IBAction)SetButtonPressed:(id)sender {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
localNotification.alertBody = #"HEY GET UP";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber =
[[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
}
-(void)setNoti {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
localNotification.alertBody = #"NOTI 1";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
localNotification.repeatInterval = kCFCalendarUnitMinute;
NSDictionary *dict = #{#"nid":#"1"};
localNotification.userInfo = dict;
[[UIApplication sharedApplication]scheduleLocalNotification:localNotification];
}
Why my simple UILocalNotification is not firing?
Have you added this code in didFinishLaunchingWithOptions of AppDelegate
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
I am not sure you added or not, but if you missed this, you will never get local as well as remote notification.
You have To Register Notification setting For Local and Remote Notification both Please Register notification setting First.
I followed this tutorial to display buttons on a push notification.
Buttons are registered by calling registerNotification in didFinishLaunchingWithOptions.
However, in few cases I need to display a simple notification without any buttons. How to show/hide the buttons for different notifications ?
For adding another kind of interactive notification with no button you will have to update the UIUserNotificationSettings.
Create a new notification category UIMutableUserNotificationCategory without any button:
UIMutableUserNotificationCategory *newNotificationCategory = [[UIMutableUserNotificationCategory alloc] init];
newNotificationCategory.identifier = #"no_button_id";
Then, add this new category to the existing UIUserNotificationSettings:
NSMutableArray *arrNewCategories = [NSMutableArray new];
UIUserNotificationSettings *oldSettings = [[UIApplication sharedApplication]currentUserNotificationSettings];
for (UIMutableUserNotificationCategory *oldCategory in oldSettings.categories)
{
if (![oldCategory.identifier isEqualToString:newNotificationCategory.identifier])
[arrNewCategories addObject:oldCategory];
}
[arrNewCategories addObject:newNotificationCategory];
UIUserNotificationType notificationType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *newSettings = [UIUserNotificationSettings settingsForTypes:notificationType categories:[NSSet setWithArray:arrNewCategories]];
[[UIApplication sharedApplication] registerUserNotificationSettings:newSettings];
Just make sure that the identifier of newNotificationCategory matches with your UILocalNotification's category, in which you dont need any buttons.
Then schedule the notification:
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:afireDate];
localNotification.alertBody = #"alert body text";
localNotification.category = #"no_button_id"; // Same as category identifier
localNotification.timeZone = [NSTimeZone systemTimeZone];
localNotification.soundName = SOUND_FILE;
localNotification.repeatInterval = 0;
[[UIApplication sharedApplication]scheduleLocalNotification:localNotification];
I hope this is help you.
Parameter Description.
userInfo --> dictionary value for user needs.
title --> notitification Title.
fireDate --> trigger notification date and time.
Interactive -> pass flag to set Interactive or normal notification.
-(void)setLocalnotfication:(NSDictionary *)userInfo title:(NSString *)title date:(NSDate *)fireDate Interactive : (BOOL)flag {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = fireDate;
notification.alertBody = title;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
if(flag) notification.category = #"Category name";
if([userInfo isKindOfClass:[NSDictionary class]]) notification.userInfo = userInfo;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
i am using this code to create it.
and more swift
func setLocalnotfication(userInfo: [NSObject : AnyObject], title: String, date fireDate: NSDate, Interactive flag: Bool) {
var notification: UILocalNotification = UILocalNotification()
notification.fireDate = fireDate
notification.alertBody = title
notification.timeZone = NSTimeZone.defaultTimeZone()
notification.soundName = UILocalNotificationDefaultSoundName
if flag {
notification.category = NCI
}
if (userInfo is NSDictionary.self) {
notification.userInfo = userInfo
}
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
Refer the Website
When my app goes in background then applicationDidEnterBackground is automatically called and in this method we fire local notification. but didReceiveLocalNotification: method is not called
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
bgTask = UIBackgroundTaskInvalid;
}];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.fireDate = [NSDate date];
localNotification.alertBody = textString;
localNotification.alertAction = #"View";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
Your expectations with local notifications are incorrect:
When your app will go in background then you will see an immediate notification on your phone but you have to tap that notification to trigger didReceiveLocalNotification delegate.
If you receive local notification in foreground then didReceiveLocalNotification will be triggered automatically.
Above scenario is tested and verified.
Update: You must read this documentation:
http://www.thekspace.com/home/component/content/article/62-uilocalnotification-demystified.html
Try this code:
NSDate *pickerDate = [date_picker date];
// Schedule the notification
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = pickerDate;
localNotification.alertBody = #"Alert Body Message";
localNotification.alertAction = #"Alert Action Message";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
and use this code in didFinishLaunchingWithOptions in App delegate class.
UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (locationNotification) {
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
Before scheluding notification you must register it for specified type:
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
bgTask = UIBackgroundTaskInvalid;
}];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.fireDate = [NSDate date];
localNotification.alertBody = textString;
localNotification.alertAction = #"View";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
// register notification settings
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
#ifdef __IPHONE_8_0
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
#endif
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
I have built a test-application for local notifications. it looks like this
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.alertBody = #"My Next Custom Notification";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:15];
localNotification.alertBody = #"Second One Now";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
NSLog(#"Notifications: %#", [[UIApplication sharedApplication] scheduledLocalNotifications]);
My AppDelegate:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSLog(#"%s", __PRETTY_FUNCTION__);
}
It works fine when I'm in Background or in the LockScreen I'm getting these notifications.
But when the first notifications comes in, it does not show the badge which should be "1" now. When the Second notification comes in the the badge shows "1" and not "2"(which would be the right number now). So what is wrong with my code?
You are making a simple mistake that you are scheduling the notification first than setting its badge number. So you should first set the notification badge number then schedule it.
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.alertBody = #"My Next Custom Notification";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:15];
localNotification.alertBody = #"Second One Now";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = localNotification.applicationIconBadgeNumber + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
NSLog(#"Notifications: %#", [[UIApplication sharedApplication] scheduledLocalNotifications]);
Also for the right badge number during the second notification either you should save your notification badge number or set it from the last notification badge as I had did in above code. Because in your code it just set the badge number from the current [UIApplication sharedApplication] badge which is 0 + 1 equals 1 each time.
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.alertBody = #"My Next Custom Notification";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
localNotification.applicationIconBadgeNumber = 1; //first notification
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:15];
localNotification.alertBody = #"Second One Now";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
localNotification.applicationIconBadgeNumber = 2; // second notification
NSLog(#"Notifications: %#", [[UIApplication sharedApplication] scheduledLocalNotifications]);
after you add condition check first is fire then cancelallnotification and register remaining with decreasing badge order.