Architectural issue: Design of recurring events - ios

I need to have a logic in our app, which allows to define recurring events (e.g. every tuesday, oder every 1st day of a month) which lead then to a specific action in the app.
I thought UILocalNotification would be a good idea, but with this class I send a notification also to the user and I want to process the event only in the app (If the app is not online, then may be the next time the app is up)
Another idea was to set up a list with the event and check every time the app is up, whether an event is due - but this seems quite old fashioned - hope there is something better.
Thanks a lot for any suggestion

You definitely want to use UILocalNotification in your situation, it will completely fulfill the needs that you described.
Since you said, the event should only fire whenever the app is active (in foreground) you will have to add some custom logic to make this happen, but this is not a very difficult task and you have multiple options here.
What I would suggest is that you use the app lifecycle methods of your AppDelegate, to schedule and remove your notifications when it's appropriate.
The UIApplicationDelegate protocol contains two relevant methods for your case (actually a bit more, but these two will do the job for you...). First we have applicationWillEnterBackground:, that's where you should remove all currently scheduled notifications. In the method applicationDidBecomeActive: you can then reschedule the notifications, as this one is called every time your app is coming to the foreground again.
Let me know if you have further questions :)

Related

iOS do scheduled operation in background or when app active

I have CoreData model which I want to update at 12 AM. So it's kind of an even when the app can recognize that a new day is coming and at 12 AM change some things in data models.
Initially, the idea was:
Prepare a single function that returns updated data. So before the function returns smth I every time check for the time (NSDate interval between two dates) and then update data model (if it's a new day). But the architecture not so simple for this purpose and it will take some time to prepare for a single point where I can get updated data, also it takes some time in background to update CoreData model which also adds some expenses to this task.
Is this ok solution to use some timer which will update data at 12 AM, I don't care about consistency in this case, but I don't like a timer which is checking every single second is 12 AM already or not. Is there some push notification update or some scheduler manager in iOS which can update data for me. One more time I just want to update the data layer and I don't care about consistency in UI. If consistency matter for sure then I would like to follow initial ide with a single point of retrieving data.
So I probably need some scheduler manager for this purpose or rewrite code of how I get the data.
There is no way to execute a function at regular intervals, even when the app is backgrounded/killed by the user.
The most reliable solution for executing a function at regular intervals even when the app is backgrounded is to use push notifications scheduled for the specific time intervals (midnight each day in your case), which would wake up the app and let it update its data. However, this solution has its downsides, since you need a server to send the push notification from and the users device needs to be connected to the internet. Also, push notifications don't wake up the app in case the user manually killed it.
For your particular problem, the best solution would be to refactor your code in a way that you have a single function that can be used to retrieve data and hence this function could ensure the data is updated in case a certain time interval has passed since the last update.
You might want to look into BGProcessingTask. You won't have granular control over when you're granted CPU time but you can set the interval you'd prefer that the task execute. Ultimately, when you run and how often is up to the system.
I would recommend checking out the new BackgroundTasks Framework Apple releases for iOS 13.
https://developer.apple.com/documentation/backgroundtasks
While you are not guaranteed at specific time if you have a window (12 am - 3 am) scheduling background tasks may be sufficient for you.

Where to put code that gets checked frequently?

I have some code that needs to get called frequently, such as check what day it is, if it's the next day then move the day strings in the tableView.
Now I thought that the viewDidLoad would get called all the time and so it would be 'fine' to put it in there. However, I've left the simulator overnight, and I've pressed the home button and clicked again, changed VCs etc. and viewDidLoad hasn't been hit.
What are my options for doing sporadic checks such as, is it a new day? As x happened etc.
In this specific case, you can subscribe to NSCalendarDayChangedNotification to be notified when the date changes and respond accordingly in your view controller. In general, didBecomeActive or viewDidAppear would likely work.
What are my options for doing sporadic checks such as, is it a new day
It depends what the meaning of "is" is! In particular, "is" when? You say "sporadic", but that's just fluff. When do you need to know this? To what stimulus do you want to respond? When the user opens your app? Then put it in applicationDidBecomeActive. Every day at noon? Then run an NSTimer. Really, the problem here is that you don't seem to know, yourself, just when you need to perform these checks.
Whilst in your app, its quite easy to continually check for something. You simply create a background thread. However, what you describe is a thread that persists from outside the app's lifecycle.
Have a read on this documentation provided by Apple itself. You have to have good excuse to put a background thread. The scope of such thread is limited to only certain scenarios such as downloading background stuff, playing sounds etc.
For your scenario, I'd look at applicationDidBecomeActive(_:) found in your Application Delegate. There you can mimic such continual check. Beware however, don't put heavy word load on start up or your app might be killed automatically if it fails to become active in reasonable amount of time.

How to schedule a piece of code to run at a specific time, and repeat daily?

I'm new to WatchKit development. I've been wanting to create a simple app that requires the ability to display a message at a certain time of day, and repeat this process daily.
I've tried to use NSTimer but once I open another app, the message is no longer shown. I don't know if this is the correct way to do it.
I would like some general insight on what ways I can approach this.
Edit: If possible, I prefer that it can work without relying on the iPhone's notification architecture. I wonder how the built-in Timer app works.
Edit 2: NSTimer seems like the way to go, the reason the message wasn't shown has more to do with the user interface system.

Possible to make a task scheduler for iOS?

I want to make an app where I can have a task (GET URL) run at predefined times (selectable in UI). For instance, Monday to Friday at 8am.
Is this possible in iOS?
I tried searching but haven't found anything very useful, probably using the wrong search terms. Does anyone happen to find some sample code for what I'm trying to do?
Edit: Pointing out that I want the app to perform these tasks even if the app is not running. I want to user to just select wanted days of the week and time, and then the phone will take care of everything - even if the phone is restarted.
If you want to regularly wake up to download content, you can register to get push notifications, and download based on the contents of the notification. You are likely to get some cycles to do this close to the scheduled time. If you want to 'opportunistically' download content you can register for background 'fetch' but there is no guarantee of scheduling.
See
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
So, first of all, the app has to be open for any kind of task to run. After that, there are 2 ways you can do it:
You can set a timer with a selector, or you can use grand central dispatch. Both have their strengths and weaknesses depending on what the task is...
https://developer.apple.com/Library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/index.html
https://developer.apple.com/library/ios/documentation/performance/reference/gcd_libdispatch_ref/index.html
check out those links and see if they can help.
Remember that you should do stuff like this on a background thread, and that the UI cannot be updated from any thread by the main thread. Additionally, remember the limitations iOS puts on background applications.
Yes, it is possible.
You can use -
[self performSelector:#selector(myFunc:) withObject:nil afterDelay:5.0];

How to find out when user-created calendar events are about to start [Rails]

I'm building an online calendar in Ruby on Rails that needs to send out email notifications whenever a user-created event is about to start/finish (i.e you get a reminder when a meeting is 5 minutes away). What's the best way of figuring out when an event is about to start? Would there be a cron task that checks through all events to find out which ones are starting within a certain threshold (i.e 5 minutes) ? A cron task seems inefficient to me, so I'm wondering what might be a better solution. My events are stored in a mySQL database. There must be a design pattern for this... I'm just at a loss for what to search for.
Any help would be greatly appreciated. Thanks.
In all likelihood you will probably implement some background queuing mechanism to actually deliver the notifications - at least you certain should be considering this approach.
Assuming this, why not create your delayed notification jobs at event creation time to be delivered when the associated event is starting or finishing. The background queue, which is already waking up periodically to look for work, will pick these up and run them.
However adopting this approach requires you to consider the following (at least):
Removing queued notification job if the associated event is removed
Amending the notification job if the associated event is amended (say a new time)
Ensuring that the polling resolution of the queuing system does not allow notifications to be delivered so late as to be useless.
If you haven't picked a queuing solution for your application you should consider these options

Resources