In local notifications there is repeatInterval property where we can put the unit repeat intervals for minute, hour, day, week, year, etc.
I want that repeat interval on Prayer time hours and every day same process.
So every Prayer time hours the local notification comes.
Prayer time is everyday different times
You can't do it with repeat. Make a bunch of different make notifications - one for each day - for the next 30 days. When the user opens the app, then recreate them for the next 30.
You can set repeat interval as day and pass array of local notifications of different time.
myapp.scheduledLocalNotifications = arrayOfNOtifications;
this may help you : how to create multiple local notifications
i have done a app like this try this .
func scheduleNotification() {
let dateString = "2017-04-04 09:00:00"
let dateFormatter = DateFormatter()
var localTimeZoneName: String { return TimeZone.current.identifier }
var secondsFromGMT: Int { return TimeZone.current.secondsFromGMT() }
dateFormatter.timeZone = TimeZone(secondsFromGMT: secondsFromGMT)
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateObj:Date = dateFormatter.date(from: dateString)!
let triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second,], from: dateObj)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let content = UNMutableNotificationContent()
content.title = "mIdeas"
content.body = getRandomMessage()
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "myCategory"
let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)
UNUserNotificationCenter.current().delegate = self
//this commented code is to remove the pre-seted notifications so if you need multiple times don't use this line of code
//UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Uh oh! i had an error: \(error)")
}
}
}
call this function to set notification you can modify this func and add parameters to pass time
Yes you can push a notification at a particular time and day with a repeat option.
Follow the code below:
//1. catch the notif center
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//2. I prefer removing any and all previously pending notif
[center removeAllPendingNotificationRequests];
//then check whether user has granted notif permission
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) {
// Notifications not allowed, ask permission again
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
//request authorization succeeded!
}
}];
}
}];
//3. prepare notif content
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:NSLocalizedString(#"Hello! Today's Sunday!!",nil) arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:NSLocalizedString(#"Sleep tight!",nil) arguments:nil];
content.sound = [UNNotificationSound defaultSound];
content.badge = #([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
//4. next, create a weekly trigger for notif on every Sunday
NSDate* sundayDate = startDate;
NSDateComponents *components = [[NSDateComponents alloc] init];
while(true){
NSInteger weekday = [[NSCalendar currentCalendar] component:NSCalendarUnitWeekday fromDate:sundayDate];
if(weekday == 1){//sunday, stay asleep reminder . LOL
components.weekday = 1;
components.hour = 9;
components.minute = 0;
break;
}else{//keep adding a day
[components setDay:1];
sundayDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:sundayDate options:0];
}
}
//5. Create time for notif on Sunday
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:unitFlags fromDate:sundayDate];
comps.hour = 9;
comps.minute = 0;
sundayDate = [calendar dateFromComponents:comps];
NSDateComponents *triggerWeekly = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday + NSCalendarUnitHour + NSCalendarUnitMinute fromDate:sundayDate];
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerWeekly repeats:YES];
//6. finally, add it to the request
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"LocalIdentifier" content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(#"Local Notification succeeded");
} else {
NSLog(#"Local Notification failed");
}
}];
If you are looking for actionable items on the notification. You should add it somewhere in the center.
UNNotificationAction *snoozeAct = [UNNotificationAction actionWithIdentifier:#"Snooze"
title:NSLocalizedString(#"Snooze",nil) options:UNNotificationActionOptionNone];
UNNotificationAction *deleteAct = [UNNotificationAction actionWithIdentifier:#"Delete"
title:NSLocalizedString(#"Delete",nil) options:UNNotificationActionOptionDestructive];
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:identifier
actions:#[snoozeAct,deleteAct] intentIdentifiers:#[]
options:UNNotificationCategoryOptionNone];
NSSet *categories = [NSSet setWithObject:category];
[center setNotificationCategories:categories];
content.categoryIdentifier = #"ActionIdentifier";
Make sure you set a different identifier for your notification request!
Related
I scheduled multiple Local Notification for the user. All of them are also delivered on their specified time. However, when I try to open any one of them from Notification Center, all of them are getting cleared.
In a rightful scenario, I don't want all them to be cleared from notification centre, only those which are tapped to be opened.
Also, i tried commenting below code from AppDelegate.m, but the issue still persists. [[UIApplicationsharedApplication]setApplicationIconBadgeNumber:0];
Can anyone tell me what could be the issue here due to which my scheduled notifications are cleared from Notification Center even when I'm tapping to open only one of them?
Below is the code I'm using to schedule Local Notifications -
NSDateComponents *components = [SSUtility hoursMinuteAndSectionsForDate:date];
NSInteger hour = [components hour];
NSInteger minute = [components minute];
NSLog(#"Hour %ld Min %ld ", hour,minute);
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
/* Set notification */
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.body = body;
// content.categoryIdentifier=NSNotificationC;
content.sound = [UNNotificationSound defaultSound];
content.userInfo = userInfo;
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier
content:content
trigger:trigger];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
SSLOG(#"Something went wrong: %#",error);
}
}];
So i did't believe that this is a default behaviour so what i found:
if you use UNCalendarNotificationTrigger then all delivered reminders are deleted on tap
if you use UNTimeIntervalNotificationTrigger then delivered reminders remain on the notification center
so try to use the UNTimeIntervalNotificationTrigger instead of UNCalendarNotificationTrigger
NSTimeInterval timeInterval = [fireDate timeIntervalSinceDate:[NSDate date]];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timeInterval repeats:NO];
In my case, Add some text to content.body solve the problem:
content.body = 'Any text'
I have searched a lot to try to find a specific solution to this problem. I have an app that uses the former UILocalNotification system to send local notifications, and this still works fine under iOS 10.3.3. However, I have tried to convert this to the new UNNotification system because the former system is deprecated. No matter whether I try a UNCalendarNotificationTrigger or a UNTimeIntervalNotificationTrigger, the delegate does not receive a call. Here is the code for the triggering viewcontroller.
if (isItTime){
NSCalendar *currentCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
[currentCalendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *components = [currentCalendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitTimeZone fromDate:[now dateByAddingTimeInterval:30]];
// components.second = 0;
NSLog(#"trigger components: %#", components);
UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger
triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"invite" content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(#"Something went wrong: %#",error);
}
}];
[self.currentLocalNotificationRequests addObject:request];
return request;
}else{
return nil;
}
And here is the code for the delegate (appdelegate) didFinishLaunching:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// Enable or disable features based on authorization.
NSLog(#"_prefix:set($class $method $line)");
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
if(granted == YES){
[storage setBool:YES forKey:#"permission granted"];
[storage setBool:YES forKey:#"alert permission granted"];
[storage setBool:YES forKey:#"sound permission granted"];
}else{
NSLog(#"No permission granted");
[storage setBool:NO forKey:#"permission granted"];
};
}];
Code for the appdelegate to get the notifications:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
NSLog(#"appdelegate - center didReceiveNotificationResponse");
NSString *actionIdentifier = response.actionIdentifier;
UNNotification *notification = response.notification;
if([actionIdentifier isEqual:#"com.apple.UNNotificationDefaultActionIdentifier"] || [actionIdentifier isEqual:#"com.apple.UNNotificationDismissActionIdentifier"]){
}else{
BOOL accept = [actionIdentifier isEqual:#"ACCEPT_IDENTIFIER"];
BOOL stop = [actionIdentifier isEqual:#"DECLINE_IDENTIFIER"];
BOOL doNotDisturb = [actionIdentifier isEqual:#"DO_NOT_DISTURB_IDENTIFIER"];
if (accept){NSLog(#"accept");
[self handleAcceptActionWithNotification:notification];
}
else if (stop){NSLog(#"stop");
[self handleDeclineActionWithNotification:notification];
}
else if(doNotDisturb) {NSLog(#"do not disturb");
[self handleDoNotDisturbActionWithNotification:notification];
};
}
completionHandler();
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(#"appdelegate willPresentNotification");
UNNotificationRequest * request = notification.request;
NSString * actionIdentifier = request.identifier;
if([actionIdentifier isEqualToString:UNNotificationDismissActionIdentifier] || [actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]){
}else{
if([actionIdentifier isEqualToString:#"invite"]){
NSLog(#"app delegate notification received while in foreground");
}
}
completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
}
Here is the NSLog of the triggering code:
<NSDateComponents: 0x146d51c0>
TimeZone: America/Chicago (CDT) offset -18000 (Daylight)
Calendar Year: 2017
Month: 10
Leap month: no
Day: 29
Hour: 14
Minute: 3
Second: 4
It is very clear that appdelegate methods are not being called by the system (I did put the app in background before the notification time, so the didReceiveNotification method should have been called.
If anyone can help, I would appreciate it!
Also, this code in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotificationFromAppDelegate:)
name:kAppDelegateNotification
object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(applicationBecameActive) name:UIApplicationDidBecomeActiveNotification object:nil];
self.currentLocalNotificationRequests = [[NSMutableArray alloc]init];
/*
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkDndIndicator) name:UIApplicationDidBecomeActiveNotification object:nil];
*/
UNNotificationAction *acceptAction = [UNNotificationAction actionWithIdentifier:#"ACCEPT_IDENTIFIER" title:NSLocalizedString(#"Continue notifications", nil) options:UNNotificationActionOptionAuthenticationRequired];
UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier:#"DECLINE_IDENTIFIER" title:NSLocalizedString(#"Stop notifications", nil) options:UNNotificationActionOptionAuthenticationRequired];
UNNotificationAction *doNotDisturbAction = [UNNotificationAction actionWithIdentifier:#"DO_NOT_DISTURB_IDENTIFIER" title:NSLocalizedString(#"Start Do Not Disturb", nil) options:UNNotificationActionOptionAuthenticationRequired];
NSArray *actions = [NSArray arrayWithObjects:acceptAction, declineAction, doNotDisturbAction, nil];
// NSArray *intentIdentifiers = [NSArray arrayWithObjects:#"none", nil];
UNNotificationCategory *invite = [UNNotificationCategory categoryWithIdentifier:#"com.nelsoncapes.localNotification" actions:actions intentIdentifiers: #[] options:UNNotificationCategoryOptionNone];
NSSet *categories = [NSSet setWithObjects:invite, nil];
[center setNotificationCategories:categories];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// Enable or disable features based on authorization.
NSLog(#"request granted");
}];
And code to start the trigger process:
-(UNNotificationRequest *)startLocalNotification:(NSDate *)fireDate :
(NSMutableDictionary *)userInfo{
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllPendingNotificationRequests];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(#"TimeChime Alert", nil);
content.body = NSLocalizedString(#"Click to Stop or Change Timer",nil);
content.categoryIdentifier = #"com.nelsoncapes.localNotification";
It turns out that this problem is obscure but the fix is easy. Unfortunately, I didn't carefully follow the first rule of coding: RTFD.
Apple's documentation for UNNotificationRequest> identifier states:
"If you use the same identifier when scheduling a new notification, the system removes the previously scheduled notification with that identifier and replaces it with the new one."
My code was using the same identifier for each UNNotificationRequest. Although the calendar notification date for each request was different, the system only kept the latest-dated request. In my case, the trigger would have fired after 1 hour, and I expected it to fire after 15 minutes. This is why I never saw a notification on the device and why I never saw a breakpoint in the delegate's didReceiveNotificationResponse method.
The fix is very easy. Just supply a unique identifier in the following code. After that, the code works.
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"invite" content:content trigger:trigger];
Replace #"invite" with a unique identifier for each request.
I was not getting my notification because I did not specify the required date components to pass to my UNCalendarNotificationTrigger.
This does not work:
NSDateComponents *dateComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour) fromDate:[[NSDate date] dateByAddingTimeInterval:5]];
This works:
NSDateComponents *dateComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond) fromDate:[[NSDate date] dateByAddingTimeInterval:5]];
I am using UNUsernotification for iOS 10 and Xcode 8 Beta 2
I wrote below code for Local Notification in iOS device:
-(void) localNotificationForiOS10:(NSDate *) _reminderDate{
NSLog(#"_reminderDate %#",_reminderDate);
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitTimeZone fromDate:_reminderDate];
NSLog(#"NSDateComponents %#",components);
UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
objNotificationContent.title = [NSString localizedUserNotificationStringForKey:#"Event Name!" arguments:nil];
objNotificationContent.body = [NSString localizedUserNotificationStringForKey:#"You have event reminder"
arguments:nil];
objNotificationContent.sound = [UNNotificationSound defaultSound];
/// 4. update application icon badge number
objNotificationContent.badge = #([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"firedate"
content:objNotificationContent trigger:trigger];
/// 3. schedule localNotification
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(#"Local Notification succeeded");
}
else {
NSLog(#"Local Notification failed");
}
}];
}
I want to set three different or multiple future dates and want reminder of event on defined dates.
When I used the above code for 3 different time on same date
e.g. (2016-12-29 18:05 ,2016-12-29 18:10, 2016-12-29 18:15) than only last one gave notification.
I register Location notification in AppDelegate file.
application.applicationIconBadgeNumber = 0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] > 10.0f) {
#if XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8
/// schedule localNotification, the delegate must be set before the application returns from applicationDidFinishLaunching:.
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
#endif
} else {
UILocalNotification *localNotifacation = [self getLocalNotificationFromLaunchOptions:launchOptions];
if (localNotifacation) {
NSString *title = localNotifacation.alertBody;
NSLog(#"Add Title %#",title);
}
}
I tried my self and I tried it.
I am able to cancel the Local Notification in iOS 10.
here is posted code.
how to cancel a local notification in iphone
Below is the code I am using to send local push.
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = pickerDate;
NSString *alertText = [NSString stringWithFormat:#"Test Push Title"];
localNotification.alertBody = alertText;
localNotification.soundName = #"Glass.caf";
localNotification.alertAction = #"Show me the item";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// Request to reload table view data
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
But now I want to send push from to date with interval of hours.
E.g. I want to send push from 1-Jan-2014 to 2-Feb-2014.
Now daily I will have 3 push. Each push will start at 8 pm and in a day after 6 after I will get rest push. Means first push at 8am, second at 2pm and 3rd push at 8 pm.
Any idea how to do this?
Any guidance would be greatly appreciated.
Actually I want to do the reminder where I will have below inputs.
Daily how many times you will have medicine
From what time you will have medicine
After how many interval you will have another medicine
For how long days you will have medicine
Edit 1
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = pickerDate;
NSTimeInterval interval = 1*60;
for (int i =0;i<=2;i++ ) {
// setup the notification using the fire date
// pickerDate = [pickerDate dateByAddingTimeInterval:interval];
pickerDate = [pickerDate dateByAddingTimeInterval:interval];
}
I tried with this code, but still I am getting one push. I was expecting 4 pushes...
You can have up to 64 scheduled notification so be aware that there is a limit.
You can put your above code into a loop and add the interval date components (using a calendar) or the interval seconds (dateByAddingTimeInterval) onto the fire date of the previous notification.
Aside, this is pointless:
[NSString stringWithFormat:#"Test Push Title"]
And wasteful. There is no format, it's just a string so just directly use #"Test Push Title".
NSDate *fireDate = pickerDate;
NSTimeInterval interval = ...;
for ( however you decide how many notifications there are ) {
// setup the notification using the fire date
fireDate = [fireDate dateByAddingTimeInterval:interval];
}
I know how to make a local notification in the applicationDidEnterBackground function in AppDelegate.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UILocalNotification * uln = [[UILocalNotification alloc] init];
uln.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
uln.timeZone = [NSTimeZone defaultTimeZone];
uln.alertBody = #"Did you forget something?";
uln.alertAction = #"Show me";
uln.soundName = UILocalNotificationDefaultSoundName;
//uln.applicationIconBadgeNumber = 0;
uln.repeatInterval = NSMinuteCalendarUnit;
application.scheduledLocalNotifications = [NSArray arrayWithObject:uln];
}
But is that possible a user can set a time for the fireDate and a do not disturb time like late in midnight?
Yes you can set the firedate property to any date in the future. Do not disturb is possible for the user to trigger himself in Settings in iOS6.