Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top