Local Notifications limit for Calendar app - ios

Im building a Calendar app, where you can schedule events, and you get Notified by UserNotification.
The Problem is that i recently read that you can only have 64 scheduled events. But what if the user has more than 64 events? I know repeated notifications are counted as one.
Does this limit count for all notification types (Timer,Calendar,Loacation)?
How would u solve this issue? Since i don't use a server, i cant make push/remote notifications.
Looking forward to ur answers!
Thanks in advance!

After the 64th event, you can try to save the ones after that and schedule them once the number of current scheduled event is less than 64. You should take into account the event's schedule time to avoid missing event with sooner start date.
EDIT
Since your app allows user to schedule future events, it makes sense to use CoreData to persist data. For each event they created, you can create an entity with following attributes:
event name
event start date
isScheduled boolean
This should be fairly simple. After that, whenever the app starts, you can fetch the events and schedule the ones with closest start date. This way, you don't have to schedule an event too far ahead.
If you want to check the number of scheduled events, you can do
UIApplicaiton.shared.scheduledLocalNotifications?.count
This method works but it is deprecated so you might want to use
UNUserNotificationCenter.getPendingNotificationRequests

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.

Dataflow Sliding Window vs Global window with trigger usecase?

I am designing a basket abandoning system for an Ecommerce company. The system will send a message to a user based on the below rules:
There is no interaction by the user on the site for 30 minutes.
Has added more than $50 worth of products to the basket.
Has not yet completed a transaction.
I use Google Cloud Dataflow to process the data and decide if a message should be sent. I have couple of options in below:
Use a Sliding window with a duration of 30 minutes.
A global window with a time based trigger with a delay of 30 minutes.
I think Sliding Window might work here. But my question is, can there be a solution based on using a global window with a processing time based trigger and a delay for this usecase?
As far as i understand the triggers based on Apache Beam documentation =>
Triggers allow Beam to emit early results, before a given window is closed. For example, emitting after a certain amount of time elapses, or after a certain number of elements arrives.
Triggers allow processing late data by triggering after the event time watermark passes the end of the window.
So, for my use case and as per the above trigger concepts, i don't think the trigger can be triggered after a set delay for each and every user (It is mentioned in above - can emit only after a certain number of elements it is mentioned above, but not sure if that could be 1). Can you confirm?
Both answers 1 - Sliding Windows and 2 - Global Window are incorrect
Sliding windows is not correct because - assuming there is one key per user, a message will be sent 30 minutes after they first started browsing even if they are still browsing
Global Windows is not correct because - it will cause messages to be sent out every 30 minutes to all users regardless of where they are in their current session
Even Fixed Windows would be incorrect in this case, because assuming there is one key per user, a message will be sent every 30 minutes
Correct answer would be - Use a session window with a gap duration of 30 minutes
This is correct because it will send a message per user after that user is inactive for 30 minutes
I think that sliding window is the correct approach from what you described, and I don't think you can solve this with trigger+delay. If event time sliding windowing makes sense from your business logic perspective, try to use it first, that's what it's for.
My understanding is that while you can use a trigger to produce early results, it is not guaranteed to fire at specific (server/processing) time or with exact number of elements (received so far for the window). The trigger condition enables/unblocks the runner to emit the window contents but it doesn't force it to do so.
In case of event time this makes sense, as it doesn't matter when the event arrives or when the trigger fires, because if the element has a timestamp within a window, then it will be assigned to the correct window no matter when it arrives. And when the trigger will fire for the window, the element will be guaranteed to be in that window if it has arrived.
With processing time you can't do this. If event arrives late, it will be accounted for at that time, and will be emitted next time the trigger fires, basically. And because the trigger doesn't guarantee the exact moment it fires you can potentially end up with unexpected data belonging to unexpected emitted panes. It is useful to get the early results in general but I am not sure if you can reason about windowing based on that.
Also, trigger delay only adds a fire delay (e.g. if it was supposed to fire at 12pm, not it will fire at 12.05pm) but it doesn't allow you to reliably stagger multiple trigger firings so that it goes off at specific intervals.
You can look at the design doc for triggers here: https://s.apache.org/beam-triggers , and possibly lateness doc may be relevant as well: https://s.apache.org/beam-lateness
Other docs can be found here, if you are interested: https://beam.apache.org/contribute/design-documents/ .
Update:
Rui pointed that this use case can be more complicated and probably not easily solvable by sliding windows. Maybe it's worth looking into session windows or manual logic on top of keys+state+timers
I find state[1] and timer[2] doc of Apache Beam, which should be able to handle this specific use case without using processing time trigger in global window.
Assuming the incoming data are events of users' actions, and each event(action) can be keyed by user_id.
The nice property that state and timer have is on per key and window basis. So you can accumulate state for each user_id and the state is amount of money in cart in this case. Timer can be set at the first time when amount in cart exceeds $50, and timer can be reset when user still have shopping actions within 30 mins in processing time.
Assume transaction completion is also a user_id keyed event. When an transaction completion event is seen, timer can be deleted[3].
update:
This idea is completely on processing time domain so it will have false alarm messages depending on lateness problem in system. So the question is how to improve this idea to event time domain so we have less false alarm. One possibility is event time based timer[4]. I am not clear what does event time based timer mean at this moment.
[1] https://beam.apache.org/blog/2017/02/13/stateful-processing.html
[2] https://docs.google.com/document/d/1zf9TxIOsZf_fz86TGaiAQqdNI5OO7Sc6qFsxZlBAMiA/edit#
[3] https://github.com/apache/beam/blob/master/sdks/java/core/src/main/java/org/apache/beam/sdk/state/Timers.java#L45
[4] https://github.com/apache/beam/blob/master/sdks/java/core/src/main/java/org/apache/beam/sdk/state/TimeDomain.java#L33

Architectural issue: Design of recurring events

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 :)

Can I change the message in a repeating UILocalNotification?

I have a UILocalNotification that repeats every hour and I would like to change the message when it repeats so it is different, or rotates between 3 messages.
Does anyone know of a way to do this?
Also, it appears I cannot customize my repeating local notifications beyond once every minute, hour, day, etc. What I'd like is a notification every 15 minutes. I suspect that can't be done though... unless you know a way?
Many thanks for assistance you can offer.
If you wanna change the message you can acces to the scheduledLocalNotifications array in your app delegate and modify the message, but to do that you need the app to be running. I think it's better to simply schedule different notifications with the different messages you want to show.
About the repeating interval the simple answers is no, you can't create your own repeating intervals. This is one of the many limitations that UILocalNotificationhas. Many apps (included mine) had solve the problem creating a queue of notifications. I explain that topic here

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