Why UILocalNotifications does not repeat? - ios

I want to run UILocalNotifications and repeat it every 2 minutes. For this I do:
let reminderNote: UILocalNotification = UILocalNotification()
reminderNote.fireDate = NSDate(timeIntervalSinceNow: 60 * 2)
reminderNote.repeatInterval = NSCalendarUnit.Hour
reminderNote.alertBody = "some text"
reminderNote.alertAction = "View"
UIApplication.sharedApplication().scheduleLocalNotification(reminderNote)
It runs it just one time, later it does not.
I think it's because of this line:
reminderNote.repeatInterval = NSCalendarUnit.Hour
How can I repeat my notifications every 1.5 or 2 hours?

Directly you can not.
Unfortunately repeatInterval can Only be set as TimeUnit Such as Hour, Minute, Second etc.
Eg: Lets say if you want to repeat notification in each 2 minutes, You will need to create 30 notifications that repeats hourly.

firedate sets the time that the notification fires the first time, and repeatInterval is the interval between between repetitions of the notification.
Unfortunately, you can only schedule notifications to repeat at exact intervals defined by NSCalendar constants: e.g., every minute, every hour, every day, every month, but not at multiples of those intervals.
Luckily, to get a notification every 2 minutes, you can just schedule 29 notifications: one right now, one 2 minutes from now, and later one 2 minutes from previous one - up to your 29 notification schedules, and have all repeat every hour. Like so:
So the code in the question schedules a notification to fire every 2 minutes (60 * 2 seconds) from now, and then repeat every hour.
UILocalNotification *reminderNote = [[UILocalNotification alloc]init];
reminderNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:60 * 2];
reminderNote.repeatInterval = NSHourCalendarUnit;
reminderNote.alertBody = #"some text";
reminderNote.alertAction = #"View";
reminderNote.soundName = #"sound.aif";
[[UIApplication sharedApplication] scheduleLocalNotification:reminderNote];
reminderNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60];
[[UIApplication sharedApplication] scheduleLocalNotification:reminderNote];
For 2 hours, you set your notification for now, after 2 hours from now and 2 hours from the previous one up to 11 notification (12*2 hours) = 24 - 2 hour (because 1st one will be on the day change) = 22/2 = 11 notifications will be required to set on the repeat interval of day by NSDayCalendarUnit.

Related

iOS Notification Trigger: Every Two Months & Every Three Months

I'm trying to create notifications that repeat every two months or every three months, depending on the user's selection.
I can successfully create one that sends a notification two/three months after the user makes their initial choice, but the 'repeats:' part is stuck on that day, so it will just repeat once a year at whatever two/three months after their initial selection was.
How can I create a notification that repeats every two/three months? Is there a way to repeat the dateRequest() function call each time the notification is triggered? That way, I could continually get a notification every two/three months because the call would be refreshed.
Here's my code to create the 'every two months' notification. The three months code is essentially the same.
var components = DateComponents()
//if it's January - October, send notification two months after the current month
if Date().currentMonth()! < 11 {
components.month = Date().currentMonthPlusTwo()
//if it's November, send notification in January
} else if Date().currentMonth()! == 11 {
components.month = 1
//if it's December, send notification in February
} else if Date().currentMonth()! == 12 {
components.month = 2
}
components.day = Date().dayOfMonth()
components.hour = 14
components.minute = 30 //every two months at 2:30pm
NotificationService.shared.dateRequest(with: components, contactName: storedContacts[key].key, identifier: storedContacts[key].value[10])
Any feedback is appreciated. Thank you.

Update UIProgressView each 5 Minutes from current Time

in my app I have a UIProgressView that needs increase by +0.1 every 5 minutes. The method for doing this, but I know I have a problem, because I would like the calculations progressview five minutes even if my application is then closed should rely on real-time (iphone clock) and not that when my application is open ... I'll explain
I open my app and begin counting the minutes
Then I close my app
I open my app after 10 minutes
my view progress should have a value of +0.2 (0.1 every 5 minutes)
I know that to do that I should use NSDate but can not implement it in the right way, could someone help me with an example to better understand how to implement this?
Thank you all
in a few words what I look for is that the increase uiprogressview must be obtained from the clock iphone minutes ... this has to happen is if the app is open or closed .... just one more minute comes uiprogressview must change. .. in short, this should be a recover energy from a user
I think you should:
Store start date in some variable: NSDate *startDate = [NSDate new];
save actual start date to NSUserDefaults:
[[NSUserDefaults standardDefaults] setObject: startDate forKey: #"MyKey"];
Next, when your application will became active get the date from NSUserDefaults, calculate time interval between saved date and actual date:
NSTimeInterval secondsBetween = [[NSDate new] timeIntervalSinceDate: savedDate];
Now you can divide result by your progress interval (I guess in ViewWillAppear):
progress = secondsBetween/(5*60) * 0.1
If you want to refresh your progress after each time unit when your ViewController is active you should use NSTimer:
[NSTimer scheduledTimerWithTimeInterval: (5 * 60)
target:self
selector:#selector(refreshProgressMethod)
userInfo:nil
repeats:YES];
Upon app launch or whenever you want the progress to start, store current time:
let startTime = NSDate()
Then on refresh (can through timer setup to fire every few minutes, or in viewDidAppear()):
let timeDelta = Date().timeIntervalSince(startTime)
progressBar.progress = timeDelta/(60 * 5) * 0.1
Update:
Sounds like OP needs to know how to persist the progress start time between app termination and fresh launch. Like the other answer you could use the UserDefaults and check if a start time already exists. If it exists then use it otherwise create a new entry like so:
let userDefaultKey = "startTime"
var startTime = UserDefaults.standard.object(forKey: userDefaultKey)
if (startTime == nil)
{
startTime = Date()
UserDefaults.standard.set(startTime, forKey: userDefaultKey)
}

How to set an alarm for 2 week days with UserNotifications API

I am trying to simulate the stock alarm app usage with the UserNotifications API but I am having hard time doing it.
For a single specific weekday (monday in this case) its all good.
NSDateComponents *components = [NSDateComponents new];
components.hour = 13;
components.minute = 0;
components.second = 0;
components.weekday = 2;
According to Apple: "The weekday units are the numbers 1 through N (where for the Gregorian calendar N=7 and 1 is Sunday)."
But if I want both monday and tuesday (should be 1 + 2?, which points to wednesday) I can't get it working.
This walkthrough also have detailed information. "To create a trigger that repeats at a certain interval use the correct set of date components. For example, to have the notification repeat daily at the same time we need just the hour, minutes and seconds:"

Repeating Local Notifications every Week with Swift

I have an app using local notifications there is a total of 64 notifications, which is the limit of local notifications. I need to repeat each notification every week. I know that to set the repeat interval you use:
alarm.repeatInterval = NSCalendarUnit
I have tried using the .WeekOfYear and .WeekOfMonth. Do they repeat the notification every year or month? And I do not know the calendar unit for weekly. Which one can I use to repeat weekly?
Edit:
This is the code I am using to set the notifications.
let notifyAlarm = UILocalNotification()
let component = NSDateComponents()
component.hour = NSUserDefaults.standardUserDefaults().integerForKey("Hour1")
component.minute = NSUserDefaults.standardUserDefaults().integerForKey("Minute1")
component.weekday = 1
notifyAlarm.fireDate = calendar.dateFromComponents(component)
notifyAlarm.timeZone = NSTimeZone.defaultTimeZone()
notifyAlarm.alertBody = NSUserDefaults.standardUserDefaults().stringForKey("Message1")
notifyAlarm.repeatInterval = NSCalendarUnit.WeekdayOrdinal
notifyAlarm.soundName = NSUserDefaults.standardUserDefaults().stringForKey("Sound1")
app.scheduleLocalNotification(notifyAlarm)
I am setting 64 notifications like that at once. But with different dates.
If you want the notification to fire for first time after a week you need to change the fire date.
I use TimeIntervalSinceNow for this, which is in seconds, so 1 week would be around 604000 seconds.
You can use _ to separate numbers for legibility.
alarm.fireDate = NSDate(timeIntervalSinceNow: 604_000)
Maybe a bit clunky but I think its the easiest for those type of notifications. I do something like this to make it easier.
struct NotificationFireDate {
static let nextDay: NSTimeInterval = 85_000
static let nextWeek: NSTimeInterval = 604_000
}
and than use it like so
alarm.fireDate = NSDate(timeIntervalSinceNow: NotificationFireDate.nextWeek)
Repeat interval should be weekOfYear
alarm.repeatInterval = NSCalendarUnit.WeekOfYear
The first repeating notification should fire 1 week after the first (fireDate) notification fired.
For a full list have a look at this (thanks madmik3)
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/#//apple_ref/c/tdef/NSCalendarUnit

Swift handle date change event

How can I handle date change event in swift?
I want to create a set of notification when the date changes.
var localNotification: UILocalNotification = UILocalNotification()
localNotification.alertAction = "Testing notifications on iOS8"
localNotification.alertBody = " Woww it works!!"
localNotification.fireDate = date
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
You can subscribe to UIApplicationSignificantTimeChangeNotification. This one should fire when the day changes.
Unfortunately this one also fires on other occasions. So you should store a static variable with the date the last time this notification fired and then check if it actually changed the day.
I don't know what you're gonna use it for, but in most cases the general significant time change is what one is looking for.
You could do localNotification.fireDate = NSDate(timeIntervalSinceNow: 1) which will give you a notification 1 day from the current date. This could be further customized to your liking depending on how specific you want the timing to be.
EDIT: As was pointed out in the comments, the timeIntervalSinceNow is calculated in seconds, so 1 would be one second, not one day.
EDIT 2: Trying to answer the question that was asked. If you want to create a notification at midnight every day...
First, create an NSCalendar object
var calendar = NSCalendar()
var calendarComponents = NSDateComponents()
calendarComponents.setDay(29)
calendarComponents.setMonth(6)
calendarComponents.setYear(2015)
calendarComponents.setHour(12)
calendarComponents.setSeconds(0)
calendarcomponents.setMinutes(0)
calendar.setTimeZone(NSTimeZone.defaultTimeZone)
var dateToFire = calendar.dateFromComponents(calendarComponents)
Now we can schedule the notification daily.
localNotification.fireDate = dateToFire
localNotification.setTimeZone(NSTimeZone.defaultTimeZone)
localNotification.setRepeatInterval(kcfCalendarUnitDay)
Syntax might not be perfect, I was translating from Obj-C, but you should get the general idea.
Try adding observer for NSNotification.Name.NSCalendarDayChanged
The down side of this that it triggers only when app is in foreground

Resources