I know that this topic is a duplicate, but I need your help. It is very important for me and the other posts have no really an solution for me.
I have an app (Swift 2) where the user can save entries in core data. These entires will show in a table view.
The user has to set an reminder date (with a date picker) for each entry. This date will use for the fire date of the local notification.
Each entry get 2 local notifications
First fire date: 1 week before the chosen date, second fire date: chosen date
The problem is the Apple limitation of 64 local notifications.
The user can only save 32 entries (32 entries * 2 notifications = 64 notifications)
How can I solve this problem with the limitation?
I know that I can set "reminder" into the Apple calendar instead of local notifications. But this doesn't looks good - this shouldn't be the solution.
I know that I can check on each app start or in the method did receive notification, which notifications should set next. but for this I have to trust, that the user start the app or tap on the received notification. If he or she doesn't do this for a few days => no new notification will set and he or she doesn't get the next notification. This solution isn't very safe.
You could routinely send a push notification to devices that have not contacted the backend in some time and have the remote notification handler setup local notifications up to the limit, see application(_:didReceiveRemoteNotification:fetchCompletionHandler:).
Or, you could setup a background fetch that reschedules local notifications up to the limit using, see application(_:performFetchWithCompletionHandler:). Note that you cannot fully control how often this refresh is performed, but in my experience it is called up to a number of times a day.
When using either one of the above method, you can update local notifications even if the user never opens the apps.
I also had some kind of problem like this.
So what I did is that I planned the notifications as much as possible, and when there is room to plan more notifications then I planned more notification.
UIApplication.sharedApplication().scheduledLocalNotifications?.count
You can get the number of planned notifications. Subtract it from 64 and plan remaining notifications.
In applicationWillEnterForeground you can do this -
if UIApplication.sharedApplication().scheduledLocalNotifications?.count < 64
{
//refersh list
let nc = NSNotificationCenter.defaultCenter()
nc.postNotificationName(Constants.SCHEDULE_MORE_NOTIFICATION, object: nil)
}
So your notification list will be refreshed automatically.
Related
I have an app that allows users to create recurrent events. Each one of the events may or may not have reminder/alerts at a specific time of day. If they have so, the app sends a local notification at that time of day.
Events are stored in CoreData.
Event(name: "Go to London",
date: 2020-04-03 21:40:55.419925+0200,
reminders: [2020-04-03 20:00:00.419925+0200,
2020-04-03 10:00:00.419925+0200,
2020-04-03 12:00:00.419925+0200]
)
An event may occur on each day of the year or everyday for the next X years.
A user may create unlimited number of events per day. And hence, the total number of notifications to be sent can easily surpasses 64 (total number of local notification that you can schedule in iOS). So I can not schedule all the notifications while the app is in foreground.
I need a mechanism to periodically schedule notifications if there are less than 64 notifications pending. This should be done even if the app is in the background.
I would be happy if you provide a solution or guide me towards finding a solution for this scenario.
info
I tried to set up a Timer that periodically checks total number of pending notifications and their due dates. . But it did not work, because timers won’t fire once the app goes in background.
I am not sure if I understand your problem right. But my impression is the following:
Your users set up and update a database of events where each event has a certain date and time.
They do this simply be entering new events into the database.
It is easy then to fetch the first n (say, 10) events from the database.
It is required to fetch more than one, since the delivery of a local notification is not guaranteed, see the docs:
Every attempt is made to deliver local and remote notifications in a
timely manner, but delivery isn't guaranteed.
Register these n local notifications with the notification center, and cancel any notification for events that are no longer among the n next ones. The docs say:
Typically, you cancel a request when conditions change and you no
longer need to notify the user. For example, if the user completes a
reminder, you would cancel any active requests associated with that
reminder. To cancel an active notification request, call the
removePendingNotificationRequests(withIdentifiers:) or
removePendingNotificationRequests(withIdentifiers:) method of
UNUserNotificationCenter.
So, even if your app is in the background or suspended, the local notification will wake it up, handle the event, remove it from the database, and update the n next events. Even if a notification could not be delivered (which is not probably, but possible), you could handle the missed event, and schedule the next ones.
I hope this meets your requirements!
Have you tried the background fetch feature? Official document link here.
And in my opinion, it would be better to use remote notification, just setup a simple server to store the users' data.
If a user taps on notification that got fired few days before how to identify the date of firing? I wanted to save the date and status into the app.
Fire date property is giving only the start date for the notification. Is there any way to achieve this?
No, for a repeating local notification you can't know exactly which notification was used to open the app because they're all exact duplicates of each other.
Each time the app is opened you could remove the local notification and create a new one. This would only bound the issue, and you could do the same with a date in user defaults.
You could create explicit notifications instead of repeating if there are enough slots, this is the only way to get close to your requirement with local notifications,
The alternative is push notifications where you can get the server to add additional date info to the push.
Use the property userInfo to store the repeating interval (e.g infinite or normal). In the userInfo dictionary , store the key "IsInfinite" and value as "Yes/No". By this way you can differentiate the notification type.
FYI: check the local notification object information also. Is repeat property is available or not?
Since my app works locally so I cannot go for push notifications. Now I am firing notification in a for loop for next 90 days as a possible solution. Its seems like defect with iOS local notifications.
I would like to know what is the best approach to do if I want to fire notifications for more than one time each day everyday.
I did some research and read that notifications for the next day cannot be fired unless the user opens the app the next day and updated the notification. Is that true? is there anyway I can do it without the need of the user opening the app everyday?
Thank you
You can schedule up to 64 local notifications. There is no limit on the time period; you can schedule them years in advance if you like.
That said, if you need some mechanism to schedule new notifications, even if the app is not running at all (e.g. because the user terminated it), you need a background mode for that. Fetch is probably the way to go here, as it doesn't need a special trigger. You could also send silent push notifications in order to wake the app, make the calculations and schedule the new notifications.
I am working on an app for a trash company. The idea is as follow:
There is a calendar for 2012/2013 with dates when and what trash can (brown, gree and black) will be picked up.
I need to make a kind of notification system which will send a notification on a specific day (from that array) with some text about what container will be picked up this week.
That would not be smart to post all notifications at once coz there are over 100 (and I've heard the limit is 64 in iOS).
I thought to schedule next notification after the current one fires. This could be done in the kind of handleNotification method when user touches the action-button at the notification and goes to the app. But what if the user gets enough information from the notification window and never touches that notification, never goes to the app and mostly have it in the "non running" state at all?
How to schedule next notification then?
Maybe some smart heads can come with other ways to make it works without using UILocalNotification?
There is no way.
If the user never opens up your app you will at most have 64 scheduled notifications. When all those have been triggered there will be no more notifications.
Although you can have your notifications repeating. So if the brown trash can will be picked up every week you can set a repat interval of weekly instead of scheduling it 52 times (thus saving 51 notifications).
Overview
I have an iOS app which sends local notifications at specific dates.
I just learned that I can only schedule 64 notifications at a given time.
There are cases when I can't schedule notifications as the 64 slots are filled.
So I store them in the database and when the user responds to a notification I check if there are any available slots and schedule the remaining notifications.
Problem
When the user doesn't respond to a notification my code is not executed so I am not able to schedule the remaining notifications.
Question
Is there a solution for this problem ?
can I execute a piece of code (house keeping) at certain times ?
is there any work around for this ?
You may not want to signal to the user there is a problem, but rather just do it in the background. If a user has 64 notifications for one app and hasn't opened the app, then they probably aren't using the app. Once a notification has fired it isn't in the array anymore. So you will have room every time a notification is fired off. They do however remain in notification centre, which you have to clear out yourself.
Its usually better to not present possible problems to the user, but rather handle them in a way that makes sense internally if that is an option. Look up the delegate methods for the appDelegate and you will most likely find ways you can handle what you are trying to do.
Thought I would make a post in case you wanted to accept the answer.
Best of luck.