I am trying to add badge and sound to local notification in my app but I get none.
I see the notification when it supposed to appear but without any sound or badge...
Can anyone please tell me what I am doing wrong?
func requestUserPermissionForNotifications(){
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in
if (error != nil) {
print("Error authorzing notifications")
} else {
if (didAllow) {
self.setDailyNotifications()
print("User allowed to Push notifications")
} else {
print("User did not allow to Push notifications")
}
}
})
}
func setDailyNotifications() {
var sunday = DateComponents()
sunday.hour = 11
sunday.minute = 00
sunday.weekday = 1
timeNotification(id: "Sunday", notificationTitle: "Daily reward is waiting", notificationText: "Log in and get your daily reward", timeOfNotification: sunday)
}
func timeNotification(id: String, notificationTitle: String, notificationText: String, timeOfNotification: DateComponents) {
let trigger = UNCalendarNotificationTrigger(dateMatching: timeOfNotification, repeats: true)
let content = UNMutableNotificationContent()
content.title = notificationTitle
content.body = notificationText
content.sound = UNNotificationSound.default()
content.badge = 1
let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if (error != nil) {
print("Error adding notification \(id) --- \(String(describing: error))")
}
}
}
The issue was that I called my setDailyNotifications() function from the requestAuthorization() method. All I did was to call setDailyNotifications() from viewDidLoad if the user approved push notifications.
Related
I have been attempting to implement an instance of local notifications without much luck. It seems that it tries to schedule the notification before the closure for the request is completed and therefore never gets scheduled correctly.
I have the two following methods constructed for the request and send:
func requestNotificationAuthorization(myDate: Date) {
let authOptions = UNAuthorizationOptions.init(arrayLiteral: .alert, .badge, .sound)
self.userNotificationCenter.requestAuthorization(options: authOptions) { (success, error) in
if let error = error {
print(error.localizedDescription)
}
}
}
func sendNotification(myDate: Date) {
let content = UNMutableNotificationContent()
content.title = "My Title"
content.body = "Placeholder for data from Firebase"
content.sound = .default
let triggerDaily = Calendar.current.dateComponents([.hour, .minute], from: myDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let identifier = "LocalNotification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
userNotificationCenter.add(request, withCompletionHandler: { (error) in
if let error = error {
print("Error")
}
})
}
The following are the calls for these methods:
let newDate = formatter.date(from: myDate)
self.requestNotificationAuthorization(myDate: newDate!)
self.sendNotification(myDate: newDate!)
I'm not sure how to hold off with the sendNotification call until I'm sure that the requestNotification has been completed successfully. If anyone is willing to provide some useful help with this, I would be most appreciative.
Larme got it right, if someone knows how to give him credit other my saying so here I would appreciate it.
I have this app with a daily notification at 12pm. If the user does something, I want to cancel the notification that day.
Is there a way to cancel the notification that day, but the rest of the days keep working the same?
private func setUpNotification() {
// Ask Permission
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
}
// Create content for notification
let content = UNMutableNotificationContent()
content.title = "I'm a notification!"
content.body = "Don't forget to track your cigarretes!"
// Configure the recurring date.
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = 12
dateComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// Create the request
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
//Register the request
center.add(request) { (error) in
if error != nil {
// Handle any errors.
print(error?.localizedDescription)
}
}
}
I'm working on an app that gives you a notification at mid-day. This notification is supposed to be different every day.
I got the notifications themselves working:
let notificationOptions: UNAuthorizationOptions = [.alert, .sound];
UNUserNotificationCenter.current().requestAuthorization(options: notificationOptions) { (granted, error) in
if !granted {
print("Something went wrong")
} else {
let content = UNMutableNotificationContent()
content.body = getRandomDailyString()
content.sound = UNNotificationSound.default()
let date = DateComponents(hour: 12, minute: 15)
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let request = UNNotificationRequest(identifier: "Daily String", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error {
print(error.localizedDescription)
}
}
}
}
What's happening now is that the getRandomDailyString()-function is called, it returns a string, and a repeating notification is set which does appear the specified time, but always has the same content.
How would I go about making a notification that gives a unique content every day?
Cannot test it right now, but try it and tell me
If it is not inside a function I would place it in one. Then you call it from your delegate method. Don't forget to change it to not be repeatable.
You must have a class to handle its delegates methods, can be your AppDelegate or any other class you create.
Delegate UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
x()
}
func x() {
let notificationOptions: UNAuthorizationOptions = [.alert, .sound];
UNUserNotificationCenter.current().requestAuthorization(options: notificationOptions) { (granted, error) in
if !granted {
print("Something went wrong")
} else {
let content = UNMutableNotificationContent()
content.body = getRandomDailyString()
content.sound = UNNotificationSound.default()
let date = DateComponents(hour: 12, minute: 15)
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: false)
let request = UNNotificationRequest(identifier: "Daily String", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error {
print(error.localizedDescription)
}
}
}
}
}
This answer can help you too
Getting local notifications to show while app is in foreground Swift 3
Ok, here is the solution for this.
It is NOT possible to schedule a repeating notification with a random content each day. The content is defined when the notification is scheduled, and cannot be changed later.
What you CAN do it schedule up to 64 notifications in advance though. So you can schedule 64 unique notifications for the next 64 days, and then whenever you open the app check how many remain, and fill up the notification-schedule up to 64 again.
If you don't open the app after 64 days the notifications stop coming though :P
I am trying to learn how to use local notifications and currently I am just trying to let a notification pop up when a certain time has passed (for the sake of learning just 5 seconds).
I register the notification in this function, which is used at the end of an onBoarding screen:
func registerNotification() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Granted.")
} else {
print("Not granted.")
}
}
}
Now to test the notification I just add the function set() to a button:
set() {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "It works!"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
But when the button is pressed and 5 seconds passed, no notification is shown, but also no error in Xcode, so I suppose this should all work?
What am I missing here? As far as I understand from various sources on the net this is the easiest way to display a local notification?
So to register a UserNotification and call the function at an appropriate
place:
func registerNotification() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Granted.")
} else {
print("Not granted.")
}
}
}
This functions sets a notification with a time interval of 5 seconds. When the app is closed the notification will be displayed:
set() {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "It works!"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
I have a Firebase listener that launches a notification when it fires like so:
chat.ref.child("lastMessage").observe(.value, with: { snapshot in
let lastMessage = snapshot.value as! String
chat.lastMessage = lastMessage
self.tableView.reloadData()
chat.lastMessageText = "New Message!"
let content = UNMutableNotificationContent()
content.title = "You have a new Message!"
content.subtitle = chat.title
content.body = chat.lastMessage
content.badge = 1
let trigger = UNTimeIntervalNotificationTrigger (timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "timerDone", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
Also have:
override func viewDidLoad() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in })
}
The problem I am having is, although the HomeScreen notifications are working in the simulator, they are not showing on the device. All permissions are granted on the device. Reading some questions here I found some answers that suggested I add the following in the app delegate:
application.beginBackgroundTask(withName: "showNotification", expirationHandler: nil)
but this actually disabled notifications on the simulator too. The notifications did work on the device before but stopped very suddenly. Any thoughts?