Is it possible to call past date UILocal Notification? - iphone

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.

Related

How to make local notification fire only once?

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.

Detect device time change ONLY WHEN it is changed manually

Problem: I know about the method applicationSignificantTimeChange to detect manual time change. But the method documentation says:
Examples of significant time changes include the arrival of midnight, an update of the time by a carrier, and the change to daylight savings time. The delegate can implement this method to adjust any object of the application that displays time or is sensitive to time changes.
So it detects not only a manual time change, but arrival of midnight as well. In my application, that will create a problem as the user will see an alertbox:
You have change the time. Please revert back to actual time.
even when he resumes the app after midnight (or may be he minimized the app and went to sleep. Next day he wakes up, resumes the app and surprisingly gets the time change notification).
Question:
How to show the alert only on manual time change and not on arrival of midnight ?
Just use NSSystemClockDidChangeNotification
Apple doc link
I have used a variant of the remote server time check for one or a few years now. It works pretty well, on iOS.
Fetch remote time.
In your time checking class, store the offset between remote time and device time, store that in a simple NSTimeInterval variable.
Now you can get "real time" at any time from your time checking class, because it can take the current device time and just add the stored offset and you will have the real time, all the time.
Whenever the app backgrounds, you will need to delete the stored offset, because the user can be fiddling with the time settings.
For every app foreground event, you will have to perform 3. again. Go get remote time again. Deny any calls to get real time until you have that offset again. Any calls depending on the real time existing will have to fail gracefully in those events where real time has not yet been fetched.
Now the offset you get should/can be compared with the offset you got last time. Decide a threshold, like 15 seconds. If the offset change from last time exceeds that threshold, the user likely changed time manually. This is a useful event for me. Of course even though the user can change the device time I will always have real time handy (most of the time).
Afaik, I always work with UTC time stamps to avoid any locale troubles.
Always its better to check such things with server time.
Follow below steps.
Fetch the server time and convert to current locale.
Check mobile time using current locale.
If they are not same, that means user has changed the time.
Let me know if this is clear 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.

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.

Send notification each day with different information

i want to send a notification each day at the same time with different information. I got no problem with showing the alert when i want to. The problem is what to show. First i tried to schedule one alert every day with different information in them, but that seems really inefficient. Then i tried with
-(void)application(UIApplication*)app didReceiveLocalNotification:(UILocalNotification *)Notif{}
but found out that it runs when the application is running in foreground only.
Is there any way to provide an array or something like it with the alert and tell the alert to get its body from the array with different index for different days?
Or should i do it with some notification that can run when the app is in background mode and the alert show and make a new alert?
All information must be provided when you schedule a local notification, so no, a notification's body cannot be sourced from an array as you described. If users are likely to open your app often and you know notification content in advance, perhaps you could ensure that x notifications are always scheduled (could be achieved by inspecting UIApplication's scheduledLocalNotifications).
This solution isn't ideal though, as it relies on users opening your app on a (somewhat) regular basis. I think push notifications are probably your best bet, but that requires access to a server, etc.
Yeah push could prob be the solution. But i dont have a server for that. The users will most likeley not open it any more after they have opened it the first time to activite the local-messages. So then this isnt really possible to do without push. when i tried a for-loop to schedule 250 days with different text each day it took about 2 minutes on iphone 4 so its not duable.