UILocalNotification delayed by 1 hour - ios

I've not experienced this problem personally, but it seems that for a number of my users, a notification being set for one time is actually being triggered an hour later.
Here's the code I use to generate the notification:
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.fireDate = date;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Alert time!";
notif.alertAction = #"Wake me";
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
Fairly standard. The users who've had the problem are on British time, which has daylight savings. I'm wondering if this is an iOS bug of some kind?

I believe the problem was to do with iOS storing a cache of the timeZone. This feature is kind of confusing, as there are 3 different timeZones you can have (and don't worry if half of this confuses you):
[NSTimeZone defaultTimeZone];
Returns the default time zone for the current application. If no default time zone has been set, this method invokes systemTimeZone and returns the system time zone. The default time zone is the one that the application is running with, which you can change (so you can make the application run as if it were in a different time zone).
[NSTimeZone localTimeZone];
Returns an object that forwards all messages to the default time zone for the current application. The local time zone represents the current state of the default time zone at all times. The local time zone adds a level of indirection, it acts as if it were the current default time zone whenever you invoke a method on it.
[NSTimeZone systemTimeZone];
Returns the time zone currently used by the system. If you get the system time zone, it is cached by the application and does not change if the user subsequently changes the system time zone. The next time you invoke systemTimeZone, you get back the same time zone you originally got. You have to invoke resetSystemTimeZone to clear the cached object.
This whole thing baffled me, personally. But that resetSystemTimeZone method seemed interesting:
If the application has cached the system time zone, this method clears that cached object. If you subsequently invoke systemTimeZone, NSTimeZone will attempt to redetermine the system time zone and a new object will be created and cached.
With the possibility of the user moving between time zones, and when some time zones support daylight savings and some don't, and being in mind that Apple themselves have on-going problems with all of this, it seemed like the logical solution would be to make this as non-breakable as possible.
Non-breakable meant that I used systemTimeZone throughout my entire app, and used resetSystemTimeZone on the line before every mention of it.
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.fireDate = date;
[NSTimeZone resetSystemTimeZone];
notif.timeZone = [NSTimeZone systemTimeZone];
I haven't had a problem with this so far. Hopefully this will help someone.

Related

How to schedule the execution of code at 9 : 00 AM

My app based on LocalNotifications in iOS 10.
I have a "Note" entity with "Reminder Date" (Daily, Weekly etc.). Every day I want a check: for today I have notes to remind or not. In case - if the user has only weekly-remind notes, how to check on what day of the week need to show notification.
Thanks
I dont think there is any possibility to execute your code on a specified time. Instead if your app is working on that time you can execute anything as you want. Otherwise application will not be in memory.
Use the code below to get the current time:
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSLog(#"%#",[dateFormatter stringFromDate:[NSDate date]]);
And check if time matches 9:00 AM
Not: only when your application is running.
Making a notification from APNS server is possible even if application is not working

How to store time and date in plist and compare it with now time iOS 7

I'm trying to develop am iPhone application doing the following tasks:
user stores his movies time and date in plist .
before the movie starts, e.g. 30 minutes before start, the application will give him notification
Now I'm asking for two points:
there is only date field on plist how we can store full time and date at once
how we can keep application compare the current time with movies time on plist even in background
if possible tell me with small example . ( to keep application comparing in background )
example :
Movies.plist
- id
- movie_name
- showing_time
if i have record
id : 1
movie_name: Games B 2
showing_time : 2014-05-22 2:00AM
today is 21-5
i want the application send notification at : tomorrow at 1:00 AM
there is no problem with notification code i know it's like this
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
localNotification.alertBody = msg;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
the problem is how the application will send the notification in the specific time and date
for your information this things is not only for one record in plist , maybe the user will store 10 movies in different days and time .
another example :
**if i open the application and i go to Save New movies i enter 3 different movies name and showing time
and i click save
all the details will saved in Movies.Plist
and i closed the application . now the application should give me local notification before any of Plist Movies start .
this is whole idea .**
NSDates store the date and the time. For example, the current date and time could be represented as: 2014-05-21 17:19:13 +0000.
As for the background process, it'll be unnecessary. When the user sets the movie time, schedule a notification for 30 minutes before the set time. There won't be any ongoing comparison, the notification will fire when the correct time is hit..
You don't need to store something nor to do some background checks, if you want notify user in specific time - just use UILocalNotification, here's the link to Apple documentation on local notifications UILocalNotification

scheduledLocalNotifications showing wrong timezone

i can get list of my scheduledLocalNotifications in my table view with this code perfectly ;
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
but the only problem is , my local notifications are firing on correct time but showing with wrong time zone on the list.
I'm also using systemTimeZone for scheduling my local notification like this ;
notification.timeZone = [NSTimeZone systemTimeZone];
What is the correct way to get a list of scheduledLocalNotifications with the correct time zone?
Thanks in advance
I've had the same problem when after i had already scheduled a notification at 3:30 pm and it was correctly scheduled when i NSLog it's fireDate it'll show up in a different time zone and that's how i fixed it.
[localNotification.fireDate descriptionWithLocale:NSGregorianCalendar]
this will return fire date with the Gregorian local (or you should use whatever local you have used when scheduling your local notification)

Detect [NSTimeZone localTimezone] secondsFromGMT property change

In our app we're using an NSCalendar to process NSDate objects, for example to obtain the day component.
This NSCalendar instance is a singleton object because we do tons of date calculations in a short amount of time and we noticed that creating new instances with [[NSCalendar alloc] initWith...] each time we needed it was consuming too much time.
The problem is, that if you keep an NSCalendar instance throughout the application execution time, this instance keeps the timezone property unchanged, even if the timezone changed.
So, the problem is that we want to detect changes to the timezone and react properly by either:
self.singletonCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
or
self.singletonCalendar.timezone = [NSTimezone localTimezone];
Possible solutions we're discussing:
Update the timezone property each time the application becomes active.
Use KVO to detect timezone changes (tried this without success).
Thanks,
Nicolás.
Implemented proposed solution by Putz1103:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(significantTimeChangeNotification) name:UIApplicationSignificantTimeChangeNotification object:nil];
- (void)significantTimeChangeNotification
{
NSTimeZone *localTimezone = [NSTimeZone localTimeZone];
[KIDateUtils setCalendarTimezone:localTimezone];
}
I would do a mashup of two options. I would update it on app start (or entering foreground). But for while the app is currently in the foreground you can set a listener for time changes like the answer here:
"UIApplicationDelegate" has a method called "applicationSignificantTimeChange:" that gets called when there is a significant change in the time.
Have your singleton register for the UIApplicationSignificantTimeChangeNotification notification. When this is received, update the NSCalendar instance in your singleton.

Will changing an events Time-Zone affect other people on shared events?

If I were to normalize an EKEvent 's startDate property using a NSDateFormatter and setting the time zone with
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm a"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
event.startDate = [formatter dateFromString:[NSString stringWithFormat:#"%#", [event.startDate]]];
and I later make a change to that event requiring me to call
[self.event.eventStore saveEvent:currentEvent span:EKSpanThisEvent commit:YES error:nil];
Would it override the time-zone on the server, causing issues for the person (whom uses GCal) in another state that originally created that shared calendar event, or is it just a local change?
If it does affect the event, what is the best way for me to make sure the events on the app side always represent the users current time zone, without having to change format the event each time I refer to it on the UI?
Yes the timezone of an event will sync. If an event happens at 9 Mountain time, the event will be displayed as occurring at 9 to anyone whos devices general setiings is set to mountain time. If their device is eastern time, the event will appear to occur at 7. If you change the time zone of the event to Eastern, devices in mountain time will now see the event occurring at 11, and eastern time devices will see the event occurring at 9. So, changing the time zone does not change the time it occurs in its own time zone, but it will change it relative to where you moved it from.
You can do 2 things after asking the user when the event occurs: 1) you can assume the event occurs in the users devices current time zone. 2) you can ask them where the event occurs and set the events time zone to that.
If you have an event with the wrong time, you should first set its time zone to where the event is actually happening, then change when it occurs to when it actually happens, where it actually happens.
If you just focus on getting the data on the event set correctly, it will appear correctly on everyones device who is sharing the calendar with you.

Resources