How to make local notification fire only once? - swift

I'm trying to set local notification in swift firing once at a definite date, but it seems there is no such option for repeat interval . By the default it triggers every 24 hours. Is there any way to submit a notification, which fires only once, so that user didn't have to even open the app or etc?

You have to set the repeatInterval of your UILocalNotification to 0:
If you assign a calendar unit such as weekly (NSCalendarUnitWeekOfYear) or yearly (NSCalendarUnitYear), the system reschedules the notification for delivery at the specified interval. Note that intervals of less than one minute are not supported.
The default value is 0, which means that the system fires the notification once and then discards it.
Regarding your second question: no! The user has to open the app at least once! Otherwise the app does not execute any of its code. Register the notification on first launch.

Related

Sending multiple Local Notifications in a period of time

I am building an app where the user puts in there working hours and working days. I need to be able to send the user a local notification every 20 minutes to update them on something. I am having trouble being able to add the exact date and times to scheduleLocalNotification. Would this be done by adding multiple fire dates? Or an array of dates?
Any input helpful.
It is good programming to only have one notification for one function at the time. So you raise a notification to fire at 14:00h.
In the fired selector you can create a new notification for 14:30h.
However when you want to have the notifications at scheduled periods you can use the repeat = YES for the Timer notification.

Is it possible to call past date UILocal Notification?

I have to added a local notification for next 30 days(June-01-2013 t0 June-30-2013).
For Example:
I have to change the date on the "settings" to June-15-2013, and then I have to change the date to June-05-2013. The local notification not called for the (June-01 to June-15). After June-16 is working fine.
My question is
1) Any restrictions for the UILocalNotification to fire the past dates?
2) Is it possible to fire the local notification for past dates?
Please help me. Thanks in advance.
Apple docs states that
If the specified value is nil or is a date in the past, the
notification is delivered immediately.
So if you are setting the fireDate of a local notification in the past the notification will be fired immediately.
Also your case I think is a special one because you are manually change the device date settings. The date settings may be changed when the time zone is changed but your case is different, you are not changing the time zone, you just change the date and I think the local notifications before (in the past) your new date are ignored.
Well, this is one of the situation i had faced when cam testing of robustness of the app. My app was also issuing notification for future dates. All goes well, if user does not change the date. But as part of testing, changing date to future and then past makes disables some notification which were suppose to appear.
The way i workaround this situation was responding to following call back in application Delegate
-(void)applicationSignificantTimeChange:(UIApplication *)application
Here i re-issued all the notifications as per required from the current date. That did the trick in my case. It's a heavy solution as all notifications has to be deleted and re-issued, but did the required for me.
There is one more case where you may required to re-Sync the notification. User may had also changed the date, when app is closed. For this, i made the application to reSync the notification everytime it launches. You can optimize this approach, by checking if there is significant change in date or not.

Avoiding Local Push notification to fire after changing time

In my app, I want to send a Local Push notification every 30 minutes. One way is to just configure local push notification and fire it. However there is a possibility that user can change his time and move forward 30 minutes. In this way a cheat can be done.
I want to configure my app so that notification only occur after 30 minutes. How can I do that. My app does communicate with server and can get its timestamp but I want to do things which don't use much server resources.
The only way I can think of to detect a user altering the system clock is as follows:
When app launches, ask your server the time and note the difference between that and [NSDate date]. Persist that as [NSNumber numberWithFloat:serverOffset];
Implement a method like - (BOOL)deviceClockChanged that asks the server again and compares to the persisted value. If the difference is greater than some small tolerance for clock drift + latency on the synch request, then you can conclude that the clock was changed. Do all this in UTC so it works independent of user travels between time zones.
Consider this: if the user wants badly enough to fool your app about the time in order to delay a notification, messing up the rest of his phone, maybe you ought to just let him edit the notification schedule.
I can supply code examples for points 1 and 2 if you want, and if you want I can supply some #"alert text" for point 3 that will make the user feel really guilty about editing his notifications.
My original answer here. If you choose to let user edit notifications, these methods will be key... UIApplication has a property:
NSArray *scheduledLocalNotifications;
and implements:
- (void)cancelLocalNotification:(UILocalNotification *)notification
So to change one, cancel it, then reschedule it.

UILocalNotification repeatInterval + applicationIconBadgeNumber

I'm trying to schedule repeating local notifications and set the application badge number to the actual number of notifications that have been scheduled so far at any given moment.
Since there's apparently no way to set a different badge number for each occurrence of the notification, I can see only 3 solutions:
Ignore the repeatInterval property of the notification and schedule separate notifications myself (see here). The thing is, since the system holds only 64 notifications per application, I may miss notifications if the user taps "dismiss" too many times, especially if several notifications are active.
Show an incorrect badge number (1 for each unique notification, regardless of the number of times this notification has been repeated so far).
Not use a badge at all.
Am I missing something, or are these the only 3 options?
Looks like those are your options, since the badge number property of an UILocalNotification does not increment the current applicationIconBadgeNumber but just set it's these are your options.
Also keep in mind that when going with option 1 your have a maximum of 64 notifications that can be set, but you know that already ;)

Determine if day change has occurred

I would like to create a notifciation that occurs every time a new day has occurred locally (either while using the app, or if it occurs in between launches). I was wondering what might be the best way to go about observing this change.
While your app is running, you can listen for the UIApplicationSignificantTimeChangeNotification notification and test the current day when you receive that. When your app quits, you can save the current day to your preferences, and when the app launches again, you can test the saved day against the current day.
You can get information about the current day using NSDateComponents.
As mentioned in the other thread, as of iOS8, you can also directly listen to NSCalendarDayChangedNotification.
Check out :
Erica Sadun Time Utililties
There are some useful methods there for checking dates.
Alternatively you can look at UILocalNotifcations
You could schedule a local notification with a repeatInterval of one day.
It all depends on what you want to do but those are some options.
I'd probably do two things:
While the app is running, have an NSTimer set to poll the current date [NSDate date] at a given interval. Store the value of the last date someplace (even in the user defaults) and then compare the new time to the stored time to check for a new day.
When closing/quitting the app, store the current date and time in the same manner above. Then, when launching the app or bringing it to the foreground, check the current date against the stored date.
NSDateComponents, NSCalendar and NSDate will come in handy for this.