I am creating a reminder based app and my only problem right now is being able to implement reminders on my app.
Basically the user is presented with a UITableView where the user can add events and I'd like to fire these dates with a notification to the user reminding them of the event on a date saved to Core Data.
At this time, I still do not understand how NSLocalNotification works an I have heard some users here say how apple only allows 64 notifications to be processed at a time and I only managed to create 1 but when creating another event, It is down to 0 and randomly goes back to 1 event when I debug my app with the
UIApplication.sharedApplication().scheduledLocalNotifications?
and I can see the notification I set but not the other ones.
Any sample app in swift would greatly help me understand how I can set multiple notifications to add, edit, delete them.
Thanks in advance and happy coding
The easiest way to tackle this is to just create notifications and schedule them. If you want to remove specific notifications you will have to hold on to their references and persist them across app launches, however you can always remove all the currently scheduled notifications with UIApplication.sharedApplication().cancelAllLocalNotifications()
This is an example of scheduling a notification to fire once a day at the same time for 5 days:
let secondsInADay = 60 * 60 * 24
for i in 1...5 {
var dayString = "\(i) days"
if i == 1 {
dayString = "\(i) day"
}
let notification = UILocalNotification()
notification.fireDate = NSDate(timeInterval: Double(i * secondsInADay), sinceDate: NSDate())
notification.alertBody = "It has been \(dayString) since you last opened the app."
notification.soundName = UILocalNotificationDefaultSoundName
if notification.fireDate?.timeIntervalSinceNow > 0 {
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
}
Also, you are correct, each app is given a queue for local notifications that have yet to fire. That queue can hold 64 individual notifications (a repeating notification counts as only 1 of those 64).
Related
I want to execute something in the background the check data every one hour.
For this, I am following the Apple Documentation video.
Here is the App Delegate code
import SwiftUI
import UserNotifications
import BackgroundTasks
#main
struct notificationtestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear(perform: {
AppCheckData()
})
}.backgroundTask(.appRefresh("notifyuser")) {
print("In Background Task")
//Check data
}
}
}
func AppCheckData() {
var startDate = Date()
let calendar = Calendar.autoupdatingCurrent
var checkTime = calendar.date(byAdding: .minute, value: 2, to: startDate)!
print(checkTime)
let notifyrequest = BGAppRefreshTaskRequest(identifier: "notifyuser")
notifyrequest.earliestBeginDate = checkTime
try? BGTaskScheduler.shared.submit(notifyrequest)
print("Done Scheduling")
}
For testing purposes, I changed addition of time to 2 minutes.
According to this code, it should print out the date after adding 2 minutes to the current date, then print out a confirmation that the BGTaskScheduler had been submitted. From there, after 2 minutes, it should print out the "In background task" in the console.
However, my app is not receiving the scheduled background task. I am not sure what I am missing here, is it the limits that Apple creates, or something else.
Please help
A BGAppRefreshTaskRequest is a request, and it is scheduled with earliestBeginDate. You are not requesting a specific time to run. You are indicating the earliest time it makes sense to run so that the OS doesn't call this unnecessarily.
As the docs note (emphasis mine):
The system decides the best time to launch your background task, and provides your app up to 30 seconds of background runtime.
In order to test your background operations, see Starting and Terminating Tasks During Development. IMO it is quite awkward, but it does work.
I want to execute something in the background the check data every one hour.
You will need to send a push notification in that case. This is not possible with BGTaskScheduler. As a rule, however, you should avoid this kind of polling and rather send the push notification only when there is new information. The point of BGAppRefreshTask is to periodically update your app's information at some point soon before the user is anticipated to need it so the user doesn't have to wait. It is not to facilitate polling.
There is no mechanism in iOS to allow you to do something at specific time intervals, without the user's intervention, except silent push notifications (and there are limits on those). This is by design. If you do not have a system for sending push notifications, then this is impossible, and you will need to redesign to not require it.
I'm not sure if it is technical issues. I tried to implement a scheduled local notification by calling this:
// Schedule the notification ********************************************
if UIApplication.sharedApplication().scheduledLocalNotifications.count == 0 {
let notification = UILocalNotification()
notification.alertBody = "This is local push notification"
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = NSDate()
notification.category = categoryID
notification.repeatInterval = NSCalendarUnit.Minute
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
from
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
}
It works fine. However, when I revert the code to the origin version without any line of codes related to the scheduleLocalNotification() the local notification still running.
I can't stop it even I clean the project/remove the application from devices before a rebuild.
Please help if possible, thank you!
You have created a repeating local notification and handed it to the system. At that point it is out of your hands. You have told the system to repeat this notification, and it will do so, forever.
Your only choice at this point is to delete your app.
What you have done is a classic mistake — one, unfortunately, that many apps do in fact make. And I have had to delete those apps from my device as well, as there is no other way to stop the repeating notification.
The right thing to do would have been to build into your app a cancelation of that local notification, i.e. you stop the notification in code. For example, you tell the UIApplication shared instance to cancelAllLocalNotifications. But you failed to do that.
Is it possible to have the lock screen pin/touchid to also authenticate my application if this is protected the same way using a pin/touchid? So I dont have to do this twice when opening an actionable notification.
Yes you can use home screen Passcode or TouchID to authenticate the app with in timeInterval by setting a property touchIDAuthenticationAllowableReuseDuration which is newly introduce in LocalAuthentication Framework in iOS9.
Code snippet(Example):-
let laContext = LAContext()
let timeInterval = 10 // In Seconds
LAContext.touchIDAuthenticationAllowableReuseDuration = timeInterval
......
......
If the device was successfully unlocked by TouchID/Passcode within this time interval, then Touch ID authentication on this context will succeed automatically and the reply block will be called without prompting user for Touch ID Authentication.
Note:- The Maximum supported interval is 5 minutes and setting the value beyond 5 minutes does not increase the accepted interval.
I am working on the alert project which daily alerts the varying message and daily increments the badge. What I want to do is something like below.
Day1 : alert "January 1st", Badge = 1
Day2 : alert "January 2nd", Badge = 2
Day3 : alert "January 3rd", Badge = 3
Day4 : alert "January 4th", Badge = 4
::::
Day365 : alert "December 31st", Badge = 365
localnotification.repeatInterval = NSDayCalendarUnit
can repeat every day, but it will only repeats registered static notification. i.e always same alert message of "January 1st" and badge will stay "1" every time notification pops up.
I can register each separate local notifications but it is limited to register only 64 notifications, and it will not keep alerting after 64 times of alerts if the user does not launch the application at all.
Does any one know how to setup permanent snooze notification with arbitrary alert message and incremental badge without having launch the application? - If anyone knows workaround to do the same/similar thing will be great too!
Thank you so much for your help!
You can schedule a UILocalNotification to repeat it self, for example every day, week, month, year.... But it will be the same notification every time.
There is noway to make it snooze, you will need to set a second notification to make it look like the snooze time is past. Just cancel that notification when the user does open your app with the first notification.
The badge number is not incremented, it a stack number. You can not make it increment other then setting it when your app startup.
I have developed application, I have successfully integrated the code of the local notification. Now I want is to show notification for selected hours only.
For example I want to show notification from 8:00 am to 8:00 pm every day every hours.
so how I can set repeat interval for this task.
Thanks in advance.
Satish
You can set the repeatInterval property of UILocalNotification.
To change the repeat interval or disable the notifications, I think your app will have to become active. For example, lets say you want to display the notifications from 8 AM to 8 PM. The 8 PM notification comes up but the user taps the 'close' button on the alert. In this case, I don't think anything can prevent the 9 PM notification from displaying unless your app becomes active between 8 & 9 PM.
In case the user does not close the notification & does come back to your app, you can check the current time & set the repeatInterval to 0 (don't repeat).
HTH,
Akshay