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

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

Related

How can I Specify Relative Time in UILocalNotification Alert Body (i.e. "starting in X minutes")?

I'm creating a local notification like this:
NSDate *fireDate = // start date from model
NSString *startingInMinutes = #"5 minutes"; // also actually from model
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = [NSString stringWithFormat:#"Your event is starting in %#", startingInMinutes];
notification.fireDate = fireData;
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
After the notification is shown to the user, however, the "5 minutes" string is quickly outdated.
For example, if the user doesn't interact with the notification for 30 minutes, it still shows "Your event is starting in 5 minutes." This is obviously due to the fact that the "5 minutes" is a hard-coded string.
Is there any syntax to specify a relative time (i.e. "in X minutes") in the alert body of a UILocalNotification?
You can't do anything about that.
It's a static text.
See documentation
This isn't possible because the notification's payload is set at the time it is scheduled (UILocationNotification) or delivered to APNS (remove notification).
You have two choices:
Leave your message as is and hope that the user realizes that the content of the message reflects a frozen point in time and can mentally do the math using the notification's timestamp.
Adjust the text to be slightly ambiguous ("Your event is starting soon") or reference an absolute time ("Your event starts at 4:00pm").
WatchKit does include WKInterfaceTimer, which is an OS-controlled counter label. It was created to decrease the amount of communication needed between an Apple Watch and an iPhone just to update UI as the time changes. If this functionality is important to you in a notification context, I would encourage you to submit a bug report asking for the enhancement at https://bugreport.apple.com.

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.

UILocalNotification delayed by 1 hour

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.

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.

iOS calendar check in background

I would like my app to check on a date while running in the background. At that point, I would like to do a local notification, but I know how to do that... What I am interested in is, if somebody even clicks the home button, and my app is in the background, I would like my app to check what date it is (once a day, while in the background), and if it is a particular date, I would like to do a local notification - a sort of an app-specific calendar...
Any ideas??
Your app (probably) doesn't run in the background so you cannot check the date, but you can schedule a local notification for a specific date (fireDate) with the following
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [NSDate dateWithTimeIntervalSinceNow:60*90]; // the date you want the notification to fire.
localNotif.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
For more info see Apple's docs
Maybe this post would be helpful for you http://mobileorchard.com/ios-advanced-programming-understanding-ios-4-multitasking/ . Good luck!

Resources