UNNotificationRequest to send local notification daily at a specific time - ios

Since UILocalNotification was deprecated in iOS10, I'm having trouble understanding how to update the following code to the UNNotificationRequest framework. Im basically letting a user schedule a daily notification at a time of their choosing. For example, if they want to get a notification everyday at 11:00AM. The below code works for iOS versions below iOS10 but since UILocalNotification is deprecated, it no longer works. Any help is greatly appreciated.
let notification = UILocalNotification()
notification.fireDate = fixedNotificationDate(datePicker.date)
notification.alertBody = "Your daily alert is ready for you!"
notification.timeZone = TimeZone.current
notification.repeatInterval = NSCalendar.Unit.day
notification.applicationIconBadgeNumber = 1
UIApplication.shared.scheduleLocalNotification(notification)

You can use UNCalendarNotificationTrigger for creating a notification that fires repeatedly using UNUserNotificationCenter. You can do something like this. The trick is to only have the time component in the Trigger date.
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Attention!"
content.body = "Your daily alert is ready for you!"
content.sound = UNNotificationSound.default
let identifier = "com.yourdomain.notificationIdentifier"
var triggerDate = DateComponents()
triggerDate.hour = 18
triggerDate.minute = 30
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: true)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
// Something went wrong
print("Error : \(error.localizedDescription)")
} else {
// Something went right
print("Success")
}
})

You can't schedule a notification that repeats daily. That notification would happen only once, and then you would have to schedule it again, which means that you would have to open the app again.
There is BGTask API introduces in iOS 13, that can be used to perform some background tasks, but not this one, you can not schedule the task for specific time.This API last only works when app is in the background, not when it is killed. You can only set some time interval that the system will use as a guiding point to determine when to perform you app's code. But in my experience it is pretty unreliable.
The only way to achieve this is to implement remote push notifications. Push notifications also work even when the app is killed.

Related

How To Create Alarm Notification Swift iOS?

I want to when user get notification from fcm (Firebase Cloud Messaging) or scheduler local notification like alarm notification like image below :
Here my code :
func onTest() {
let content = UNMutableNotificationContent()
content.title = "Weekly Staff Meeting"
content.body = "Every Tuesday at 2pm"
// Configure the recurring date.
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = 16 // 14:00 hours
dateComponents.minute = 11
// Create the trigger as a repeating event.
let trigger = UNCalendarNotificationTrigger(
dateMatching: dateComponents, repeats: true)
// Create the request
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString,
content: content, trigger: trigger)
// Schedule the request with the system.
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.add(request) { (error) in
if error != nil {
// Handle any errors.
}
}
}
My code right now just like the usual notification which disappears in 5 seconds I want to make it like an Alarm notification or Whatsapp Calling Notification. Please Help Thanks.
Due to Apple's limitation, app dev can only play notification tone up to 30 seconds. It will play default notification tone if your tone is longer than 30 seconds.
If your notification tone is gone after 5 seconds, try to set your notification presentation options to list, badge and sound.
Once there's no banner for notification, your 30seconds tone will play till the end.
Unfortunately there's no legal way or any workaround to have notification ring continuously such as alarm clock. Hope I was wrong though.
https://developer.apple.com/documentation/usernotifications/unnotificationpresentationoptions
What I think, max you can do is to present a local notification. But yes that would not be exactly like an Apple Alarm notification. In Reality, you don't have permission for this. You can only present the local notifications.

Local notification not fired on iOS 13 if it was scheduled when notifications access is disabled from iOS Settings

In my app I am scheduling local notifications with the following method:
func addNotificationRequest(fireDate: Date, identifier: String, sound: UNNotificationSound)
{
let notificationCenter = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Important"
content.body = notificationMessage
content.sound = sound
content.categoryIdentifier = "UserActions"
let calendar = Calendar(identifier: .gregorian)
let triggerDate = calendar.dateComponents([.hour, .minute, .second], from: fireDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: true)
let notificationRequest = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
notificationCenter.add(notificationRequest) { error in
if let error = error
{
print(error.localizedDescription)
}
}
let myAction = UNNotificationAction(identifier: "MyActionID", title: "Open", options: [.foreground])
let category = UNNotificationCategory(identifier: "UserActions", actions: [myAction], intentIdentifiers: [], options: [])
notificationCenter.setNotificationCategories([category])
}
Notifications are supposed to fire at a given time and should repeat every day at the same time.
On iOS 13 I found a bug that can be reproduced by the following steps:
I go to iOS Settings > Notifications > App Name > Disable "Allow Notifications"
Then I open the app and schedule a local notification for example after 2 minutes
After that I go back to Settings and enable back "Allow Notifications" switch.
After 2 minutes no local notification is shown. Tested it on older iOS versions and notifications are shown as supposed.
Maybe some people found this bug too and have any advice how to fix. Any help is appreciated.
Starsky is correct!
According to Apple's Documentation:
Before trying to schedule local notifications from your app, make sure that your app is authorized to do so, because the user can change your app’s authorization settings at any time. Users can also change the types of interactions that are allowed for your app, which might cause you to change the way you configure your notifications.
You'll either have to "silently fail" at scheduling the notification if permissions are disabled, or notify the user that they need to go into the Settings app to re-enable them:
In my case, I did something like this using SwiftMessages:
static func showNotificationDisabledInfo() {
print("INFO: Notification permissions denied, need to reset in Settings!")
showAlertMessage(withTitle: "Notifications are disabled!",
body: "Go to the Settings app to re-enable notifications.",
type: .info)
}

Problem in scheduling repeating local notification every hour

Im trying to schedule local notification every hour. The problem is that im getting the notification in such irregular time. Sometime in 10 minutes, or in second, or 30 minutes. Sometime i get like 10 notifications in the same second suddenly. I have no idea what is the mistake im doing here. I apologize in advance, i just started learning swift.
This is my code.
#objc func LocalNotificationHour() {
let user = UNUserNotificationCenter.current()
user.requestAuthorization(options: [.alert,.sound]) { (granted, error) in}
let content = UNMutableNotificationContent()
content.title = "Local Notification"
content.body = "Test."
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (60*60), repeats: true)
let uuid = UUID().uuidString
let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)
user.add(request) { (error) in print("Error")}
}
Is it possible that your function is being run multiple times, and therefore scheduling more than one notification to repeat? That would account for receiving multiple notifications at once/at times when you're not expecting them.
If that is the case, try adding the line user.removeAllPendingNotificationRequests() under let user = UNUserNotificationCenter.current(). This will remove any pending notifications your app may have scheduled before scheduling a new one.
It's because you are running your code once with one hour logic.
And then you are changing logic for two hour logic.
So basically both notification is triggering.
Either delete the app or previously scheduled notifications or change the identifier.

Local location notifications are not being delivered in iOS 12

I have an app which uses UNLocationNotificationTrigger to deliver notification based on user's location. When I'm testing my app sometimes it registers that user entered specific region, but doesn't deliver notification on entering region. Other times it works perfectly but I was wondering why this doesn't work every time. Does anyone else have similar problem? I would appreciate if someone could give a short explanation on this problem :)
This is the piece of code for registering notification:
let notification = UNMutableNotificationContent()
notification.title = "Notification title"
notification.subtitle = "Notification subtitle"
notification.body = "Notification body"
let notificationTrigger = UNLocationNotificationTrigger(region: enteredRegion, repeats: true)
let notificationRequest = UNNotificationRequest(identifier: "id12494", content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(notificationRequest, withCompletionHandler: nil)

Schedule a local notification(silent) to perform a custom task in background + swift ios

In our app, the user will clock-in when he starts his work. If the user forgets to clock-out, we will have to automatically clock him out after 24 hours from the clock-in time. The app might not be in the active/background state for such a long time. It might be terminated. So our idea is to post a local notification through which will execute the code in the background to clock him out. This notification has to be a silent notification. But our understanding from the research is that local notifications cannot be silent. So is there any other way we could achieve this? Or can we actually schedule a silent local notification?
class func generateLocalNotificationWith(timeInterval : TimeInterval, title : String, message : String, mobileTimeClockId: Int)
{
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
let content = UNMutableNotificationContent()
//adding title, subtitle, body and badge
content.title = title
content.body = message
let userInfoDictionary = ["badge":"0","content-available": "1"]
let dict = ["aps": userInfoDictionary, "MobileTimeClockId": mobileTimeClockId] as [String : Any]
content.userInfo = dict
//getting the notification trigger
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval, repeats: false)
//getting the notification request
let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)
//adding the notification to notification center
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
If you want a notification to be silent and do background work it has to be a push notification. A local notification can't wake your app without some user interaction.
The best way to do what you want is to use Core Location region monitoring to wake your app when the user physically leaves their workplace. Region monitoring can wake your app silently in the background and let you do some work. The problem is that it's not 100% assured that it will be triggered and the user will need to accept background location permissions.

Resources