I've set the user notification. They got deliver well but the badge on the app icon is always one.
Here's my code:
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound];
center.requestAuthorization(options: options) {
(granted, error) in
if !granted {
// ask for permission
}
}
When the use click the button i schedule the notif:
#IBAction func saveBtnPressed(sender: UIButton) {
scheduleNotif()
}
Here's the scheduleNotif function
func scheduleNotif() {
let dateformatter = DateFormatter()
dateformatter.dateStyle = DateFormatter.Style.medium
dateformatter.timeStyle = DateFormatter.Style.short
let dateFromString = dateformatter.date(from: selectDateTextField.text!)
let fireDateOfNotification: Date = dateFromString!
//Notif are enabled
let content = UNMutableNotificationContent()
content.title = notifTitleTextField.text!
content.body = notifNoteTextView.text
content.sound = UNNotificationSound.default()
content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber
var trigger: UNCalendarNotificationTrigger
var triggerDate = DateComponents()
trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
let titleNospace = notifTitleTextField.text?.replacingOccurrences(of: " ", with: "")
var identifier = titleNospace
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
self.center.add(request, withCompletionHandler: { (error) in
if let error = error {
print(error.localizedDescription)
}
})
}
Any idea why the badge will always display one and never increment as the notifications are delivered?
Thank you
I think you need to increment applicationIconBadgeNumber. So replace
content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber
By:
UIApplication.shared.applicationIconBadgeNumber += 1
content.badge = UIApplication.shared.applicationIconBadgeNumber as NSNumber
Related
Hello I am making an alarm app and I am trying to play audio when the user receives the local notification. I keep all my local notification functions and management in a swift file titled NotificationPublisher. It works when the user has the app in the foreground because the willPresent() function gets called, however I am trying to make it work in the background/phone is closed.
Is there a function that gets called when a local notification is presented in background and not just the foreground?
If not am I tackling this feature wrong.
Here is my sendNotification function where I take in my alarms and schedule the local notifications. (In my NotificationPublisher.swift)
func sendNotification(alarm : Alarm, badge: Int?) {
let notificationContent = UNMutableNotificationContent()
notificationContent.title = alarm.alarmName
notificationContent.subtitle = alarm.alarmTime + " " + alarm.alarmPeriod
notificationContent.body = "Click here to open the app and click the solve button!"
if let badge = badge {
var currentBadgeCount = UIApplication.shared.applicationIconBadgeNumber
currentBadgeCount += badge
notificationContent.badge = NSNumber(integerLiteral: currentBadgeCount)
}
notificationContent.sound = UNNotificationSound.default
UNUserNotificationCenter.current().delegate = self
var hour = ""
if(alarm.alarmTime.count == 4){
hour = String(alarm.alarmTime.prefix(1))
} else {
hour = String(alarm.alarmTime.prefix(2))
}
let minute = String(alarm.alarmTime.suffix(2))
var intHour = Int(hour)!
if(alarm.alarmPeriod == "PM" && intHour != 12){
intHour += 12
} else if(alarm.alarmPeriod == "AM" && intHour == 12) {
intHour = 0
}
var dateComponents = DateComponents()
if(alarm.alarmDays.filter{$0}.count == 0) {
dateComponents.hour = intHour
dateComponents.minute = Int(minute)!
dateComponents.timeZone = .current
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true) // Repeating Alarm
let request = UNNotificationRequest(identifier: alarm.alarmKey, content: notificationContent, trigger: trigger) // replace trigger with delaytimetrigger and vice versa for exact time
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print(error.localizedDescription)
}
}
} else {
dateComponents.hour = intHour
dateComponents.minute = Int(minute)!
dateComponents.timeZone = .current
let days = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]
for i in alarm.alarmDays.enumerated() {
if(i.element){
dateComponents.weekday = i.offset + 1
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: alarm.alarmKey + days[i.offset], content: notificationContent, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print(error.localizedDescription)
}
}
}
}
}
}
Here is the audio function that is in my ViewController.swift that I am calling from my willPresent() function.
func alarmSound() {
print("alarm sound was called")
if let player = player, player.isPlaying {
player.stop()
} else {
let urlString = Bundle.main.path(forResource: "buzzer", ofType: "mp3")
do {
try AVAudioSession.sharedInstance().setMode(.default)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
guard let urlString = urlString else { return }
player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: urlString))
guard let player = player else { return }
player.numberOfLoops = -1
player.play()
} catch {
print(error)
}
}
}
I am not sure if this will work, but I know the setting sound property will change the sound for your notification. Please check the below link and share your feedback.
https://smashswift.com/create-custom-notification-sound/#:~:text=Scheduling%20local%20notification%20you%20need,of%20UNNotificationSound%20to%20sound%20field.&text=The%20filename%20has%20to%20match,the%20same%20with%20Push%20Notification.
I am trying to set up local notifications that are triggered under two circumstances:
- An x number of days after the first use of the app
- In case the user has gone an x number of days without using the app
Is this possible? All the information I have found online is about setting notifications to go off at a specific time, but how can I send depending on the app's first and last use?
First of all, you need a request to register the notifications, and after the notification is granted, you can call the functions that firing the notifications on the specific time.
In AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .sound]
center.requestAuthorization(options: options, completionHandler: { granted, error in
if granted {
self.setNotificationForFirstTimeUseApp()
self.setNotificationForLastTimeUseApp()
print("Notification is granted")
} else {
print("Notification is not granted")
}
})
return true
}
Create the functions for firing the notification on a specific time:
func setNotificationForFirstTimeUseApp() {
// Check the app, if it is opened before
if let _ = UserDefaults.standard.value(forKey: "appOpened") as? Bool {
return
}
// Save a flag on preferences that it tells the app is opened for the first time
UserDefaults.standard.set(true, forKey: "appOpened")
let content = UNMutableNotificationContent()
content.title = "Using for the first time - Notification" // Add your own title
content.body = "Awesome thank you for using this application!" // Add your own description
content.sound = UNNotificationSound.default
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = NSTimeZone.local
// Specific the time you want to fire the notification (after some days, hours, minutes...)
if let date = Date.getDateByAdding(days: 0, hours: 0, minutes: 0, seconds: 5) {
let componentsForFireDate = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .timeZone], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: componentsForFireDate, repeats: false)
let identifier = "firstTimeUseApp"
let request = UNNotificationRequest(
identifier: identifier,
content: content,
trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: { error in
if error != nil {
if let error = error {
print("Something went wrong: \(error)")
}
}
})
center.getPendingNotificationRequests(completionHandler: { requests in
print(String(format: "PendingNotificationRequests %i", requests.count))
for req in requests {
let trigger = req.trigger
if let trigger = trigger {
print("trigger \(trigger)")
}
}
})
}
}
func setNotificationForLastTimeUseApp () {
let content = UNMutableNotificationContent()
content.title = "Using for the last time - Notification" // Add your own title
content.body = "You have not used the application for a long time!" // Add your own description
content.sound = UNNotificationSound.default
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = NSTimeZone.local
// Specific the time you want to fire the notification (after some days, hours, minutes...)
if let date = Date.getDateByAdding(days: 0, hours: 0, minutes: 0, seconds: 10) {
let componentsForFireDate = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .timeZone], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: componentsForFireDate, repeats: false)
let identifier = "lastTimeUseApp"
let request = UNNotificationRequest(
identifier: identifier,
content: content,
trigger: trigger)
let center = UNUserNotificationCenter.current()
// Remove pending notifications
center.removePendingNotificationRequests(withIdentifiers: [identifier])
center.add(request, withCompletionHandler: { error in
if error != nil {
if let error = error {
print("Something went wrong: \(error)")
}
}
})
center.getPendingNotificationRequests(completionHandler: { requests in
print(String(format: "PendingNotificationRequests %i", requests.count))
for req in requests {
let trigger = req.trigger
if let trigger = trigger {
print("trigger \(trigger)")
}
}
})
}
}
And finally, add this function. It will calculate a future date by adding days, hours, minutes and seconds, from now.
extension Date {
static func getDateByAdding(days: Int, hours: Int, minutes: Int, seconds: Int) -> Date? {
let currentDate = Date()
var dateComponent = DateComponents()
dateComponent.day = days
dateComponent.hour = hours
dateComponent.minute = minutes
dateComponent.second = seconds
let futureDate = Calendar.current.date(byAdding: dateComponent, to: currentDate)
return futureDate
}
}
I hope this answer will help you with your issue!
I'm trying to trigger local notifications for every 1 minute even in terminated state and background state. But, my app should not trigger notification when time is after 06:00PM. Below is my code.
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60,repeats: true)
//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.
}
}
}
To handle local notification, try this:
public func addLocalNotification(hour: Int, minute: Int, identifier: String, title: String, body: String) {
// Initialize
let center = UNUserNotificationCenter.current()
// Set its content
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = .default
// whenever you want to notify user select time
var dateComp = DateComponents()
dateComp.calendar = Calendar.current
dateComp.hour = hour
dateComp.minute = minute
// repeat and date
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComp, repeats: true)
// Initializing the Notification Request object
let req = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
// Add the notification to the center
center.add(req) { (error) in
if (error) != nil {
print(error!.localizedDescription)
}
}
}
I am working on a medicine reminder app. The user will input two dates and I need to schedule local notifications between those two dates. I can't find how to specify the starting and the ending date in the UNNotificationRequest.
I have tried this:
static func setAlarmWithDate (hour:Int, minutes:Int , day:Int, medicineName:String, medicineId:String) {
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationString(forKey: "MY_MEDICINE".localizedString(), arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: "This is a notification for your medicine \(medicineName)",
arguments: nil)
content.sound = UNNotificationSound.default()
var userInfo = [String:String]()
let medicine = medicineId
userInfo["medicine"] = medicine
content.userInfo = userInfo
var dateInfo = DateComponents()
dateInfo.hour = hour
dateInfo.minute = minutes
dateInfo.weekday = day
let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: true)
let identifier = medicineId
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if let theError = error {
print(theError.localizedDescription)
}
}
}
I am new to Swift and I am really stuck.
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .sound];
center.requestAuthorization(options: options) { (granted, error) in
if !granted {
print("Something went wrong")
}
}
center.getNotificationSettings { (settings) in
if settings.authorizationStatus != .authorized {
// Notifications not allowed
}
}
let content = UNMutableNotificationContent()
content.title = "Good Morning"
content.body = "wake up"
content.sound = UNNotificationSound.default()
var dateInfo = DateComponents()
dateInfo.hour = 7
dateInfo.minute = 0
let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: true)
let identifier = "localNotification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let _ = error {
LOGG("Something went wrong")
}
})
Above code, triggers push notification perfectly at 7 am. How I set notification at 9 pm or 12 pm using the same code. Thanks.
Try to fire at 9 PM
var dateInfo = DateComponents()
dateInfo.hour = 21
dateInfo.minute = 0