Xcode - Run code each day on 00:00 - ios

I need a piece of code for Xcode (obj-c) that runs every day at 00:00.
The reason for this is because my server updates data each new day and I would like my app to synchronize with the update.
I was thinking about doing a timer that runs every minute and checks the time (from internet, not the phones time), but it seems like there could be an more efficient way.
Help or pointers really appreciated!
Thanks

Use the calendar app on your mac. Set up a recurring event every day at 0:00. At the point where you pick the type of alert, you can select an option to open a file (as opposed to a pop-up, etc.). Pick your app as the file to be opened.

When the app becomes active, register a local notification (UILocalNotification) to trigger at midnight.
Then, you can perform the updates at the app delegate's -application:didReceiveLocalNotification:
You can then cancel the notification when the application goes to background by calling the UIApplication's method -cancelLocalNotification:

I don't think it's even required to use notification here. Notification is usually on best effort basis and doesn't guarantee the delivery. This can be done in few simple steps.
Save the lastUpdated time in your iOS app. Probably in NSUserDefaults or if you're using local database you can store it there as well.
Everytime user launches the application check how much time has elapsed since last update.
If it's more than 24 hours then make an API call to your server and check if there's any new updates available (which you can determine probably from server timestamp). Get the latest data (possibly only the delta difference in stead of everything).
Update the lastUpdated time in your iOS app.

Related

Background Fetch at Specific Time

I am looking for solution to get data in background mode even app is terminated.
There are lots of tutorials and answers available for this questions, but my questions is different than other. I haven't find any proper solution on stackoverflow, so posted this question.
I have scenario which I can explain. I'm using realm database which store event date, name, time, address etc. Now the thing is that, I want to write a code which are execute in background, In this code I want to get all event data and compare their date with today's date. And based on days remaining between these days fire local notification to remind user about how many days are remaining for specific event.
I want to call this background fetch method exactly 8 AM in local time everyday.
I haven't write any code due to confused with Background fetch and implementation. Can anyone know how to implement this ?
Help will be appreciated.
I have got solution to fix issue. As per I have talked,
I want to write a code which are execute in background, In this code I
want to get all event data and compare their date with today's date.
And based on days remaining between these days fire local notification
to remind user about how many days are remaining for specific event.
So, when I getting response from API, I'm creating local notification for all events with unique id, which are fire and repeat daily at specific time, where I have display event time and remaining days of event.
Apple documentation states that there is no guarantee when background fetch is performed. It's up to the system to decide.
The system waits until network and power conditions are good, so you should be able to retrieve adequate amounts of data quickly.
The guaranteed way to wake your app is to send at 8 am VoIP push notification from the server. It is guaranteed that the app will be wakened upon receiving a push, and you'll be able to execute the jobs you need. For more details, https://medium.com/ios-expert-series-or-interview-series/voip-push-notifications-using-ios-pushkit-5bc4a8f4d587
It is not possible to wake up the app from suspended mode in iOS except with push notification (for this server has to send push notification).
This is something which is not documented anywhere. IMHO and experience with iOS, Apple must be recording user activities since the start of the iOS era. ScreenTime is a product of those recordings only that apple was able to create and visualize the data to present a user facing app that very beautifully restricts, manages and displays your activities. In WWDC 2018, it was even quoted that apple will even detect, if the user opens your app at let's say 9 PM daily before going to bed, iOS will allow every possible resource (battery, internet, processing time etc) to that app at 9 PM. But you need to understand your user activities before you do this. Let's take an example of:
News App:
A majority of users would check the news in the morning (If they are not instagram addicts). At this time even apple should be biased to open your app with background fetch. Unless of-course there is too much of a resource crunch
A Game: Many games allow provide a restriction time by calling it "recharge" or "re-fill" the energy of a character before user can play another round. This is done so that the addicted person would buy gems to remove that restriction and hence monetize the idea. But if you know that the refill process is completed before 8:00 AM in the morning or user plays your game daily at 8:00 AM configure background fetch accordingly.
Background fetch works with interval rather than specific time.
// Fetch data once an hour.
UIApplication.shared.setMinimumBackgroundFetchInterval(3600)
Lastly why don't you try silent push notifications? Based on your question, I think silent notification is enough to wake your app after a push notification from the server, download some data and do your calculation and provide a local notification.

Use of "applicationSignificantTimeChange"

May be I am asking a stupid question here.
I recently noticed an UIApplication delegate method
- (void)applicationSignificantTimeChange:(UIApplication *)application {
}
I was wondering what will be its actual use? Do we need to handle this. Can anyone explain a scenario that can happen in an iOS application and we need to do some coding here.
My App is really sensitive to system time, that is the reason I am asking this question. After seeing this API , I have a feeling that I am missing something here to handle.
I am just curious to know... :)
Thanks,
Ramesh Chandran A
Per the documentation on iOS, this method is called:
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 app that displays time or is sensitive to time changes. Prior to
calling this method, the app also posts a
UIApplicationSignificantTimeChange notification to give interested
objects a chance to respond to the change. If your app is currently
suspended, this message is queued until your app returns to the
foreground, at which point it is delivered. If multiple time changes
occur, only the most recent one is delivered.
Examples of when this should be used include:
If your app has repeating scheduled events, such as a local notification that now is past, and your app should reschedule the next notification (like daily reminders).
If your app displays data in time ago that needs to be correct, even if the user sets a bad time (for example a medical app that shows your current glucose reading or similar). If a glucose monitor showed an old glucose value as the users current glucose value for instance, the user could make the wrong decision and get hurt.
How you respond to this event depends on your application. You could for instance, read UTC from a server to see if the phone's UTC is correct within some margin, and take appropriate action, such as warning the user, or updating an internal offset between actual UTC and phone UTC.
Hope that helps.
-applicationSignificantTimeChange: is roughly equivalent to the UIApplicationSignificantTimeChangeNotification notification.
I have a custom date picker control that highlights the today date. Subscribing to this notification allows it to change its highlight at midnight, or if the user messes with the time setting manually.

NSSystemClockDidChangeNotification acts weird when app wakes up

In my app I'm registering a NSSystemClockDidChangeNotification notification in AppDelegate method application:application didFinishLaunchingWithOptions:options.
Posted whenever the system clock is changed. This can be initiated by
a call to settimeofday() or the user changing values in the Date and
Time Preference panel. The notification object is null. This
notification does not contain a userInfo dictionary.
Month ago it was working fine, but these days every time I suspend my app, lock my iPhone and leave it 2 minutes to pass, when opening the app, the selector method is called, which is weird to me. I didn't change the system or time, I just let the device idle.
Can anyone help me understand this? I just want to execute some code when the user manually change the system time, just in that case (tried with UIApplicationSignificantTimeChangeNotification but that doesn't help).
Like that: Getting iOS system uptime, that doesn't pause when asleep
But remember, this solution will fail sometimes because of out-of-sync when system tries to update time from NTP server when the Internet connection is not reachable.
This answer is a bit late but this is what the apple support team replied when I ask a similar question:
Part of the question I asked:
Could it be possible for the OS posted [this notification] if the
time/timezone has not changed in the device?
The answer I got from them:
Absolutely [1]. It's common for a notification like this to be posted
redundantly. In some cases it's triggered by a state change you can't
see. For example — and I haven't tested this theory, so it's just an
example of how this sort of thing can come about — this notification
might be posted if the system's giant list of time zone info has
changed. So, the time zone state has changed, but it's not something
that affects your app.
But in other cases, a notification might be truly redundant (-: iOS
is a complex system and in some cases this complex machinery generates
redundant notifications, and there's no need to filter them out
because…
Your app should respond to such notifications be refetching the info
it cares about and updating its state based on that. If this update
is expensive, keep your own copy of the previous state, compare the
current system state to that, and only do the update if the stuff you
care about has actually changed.

how to trigger a download on specific date

In my iPhone application I want to trigger a download every monday of a week, every 10th working day of a month, every 3rd day of a month etc. I did some R & D and found that NSDate, NSDateComponents & NSCalendar classes needs to be used for this scenario. Can somebody help in the same as I am new to date & time usage.
Also by the time when trigger comes if app is not in running state or mobile is switched off.. How to handle these scenarios.
If you device is switched off / out of order / app is not running, you can not do any thing.
Apple would not allow you to launch your automatically, so the question of downloading and saving is bit far.
What you can do is, whenever your app is launched you can read from plist or userdefaults about the time ( 3rd day of month ) and compare to the last saved date, if it is one month away then it is the time to download and show a popup to do so.
Only legal way to do this is to schedule NSLocalNotification to desired date. When notification is fired up and user taps it, app would be started, and there you should start with download.
The documentation for Local Notifications: Local Notifications
You can read this: iOS timed background processing
Can go through this tutorial as well.
I have reading up as well. Something new for me as well. Best is NSLocalNotifications. Have a look at this: Reminder App

ios How to run method on every day?

I want to check for update of the stored db every day or every X interval of day, how is it possible to call a method on every X interval of day? I found some code that is for the x interval of seconds, is it feasible to do by the same way? And main thing is it should run in background too. I also though of the way by storing the last updated date in database so that I retrive every time app lunch and compare with present date? Please help me by suggesting the better way.
Since you can't really run any app in background unless you are playing audio, doing something thing with the location or a re an voip client, you will need to do this when the user opens your app.
Just store the last update date in the NSUserDefault
You can not execute your application when it is closed. You can not create background applications or daemons.
Maybe running it on application start would be appropriate for you, but if you need information from the device every day, the user will have to make sure the app is open every day.

Resources