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 am trying to create a timer which triggers a local notification to go off at a time that the user has set. The issue I am having is that I cannot figure out a way to be able to set the local notification to go off at say 7:00PM. Almost all the methods found when researching this issue involved the local notification going off at a certain amount of time from the current date. I am trying to allow the user to select 7:00PM and then have the notification go off at that time. Logically it makes sense that this can be achieved through having the final time (selected value by the user) - current time which would give you the time difference. I am however not entirely sure how to do this.
Any help with regard to the topic will be very much appreciated, thank you. Below is the code which I am currently using to trigger a local notification.
let center = UNUserNotificationCenter.current()
content.title = storedMessage
content.body = "Drag down to reset or disable alarm"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.init(named: "1.mp3")
content.badge = 1
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeAmount, repeats: false)
let request = UNNotificationRequest(identifier: "requestAlarm", content: content, trigger: trigger)
center.add(request)
center.delegate = self
Well in iOS 10 Apple has deprecated UILocalNotification which means it is time to get familiar with a new notifications framework.
Setup
This is a long post so let’s start easy by importing the new notifications framework:
// Swift
import UserNotifications
// Objective-C (with modules enabled)
#import UserNotifications;
You manage notifications through a shared UNUserNotificationCenter object:
// Swift
let center = UNUserNotificationCenter.current()
// Objective-C
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
Authorization
As with the older notifications framework you need to have the user’s permission for the types of notification your App will use. Make the request early in your App life cycle such as in application:didFinishLaunchingWithOptions:. The first time your App requests authorization the system shows the user an alert, after that they can manage the permissions from settings:
// Swift
let options: UNAuthorizationOptions = [.alert, .sound];
// Objective-C
UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound;
You make the actual authorization request using the shared notification center:
// Swift
center.requestAuthorization(options: options) { (granted, error) in
if !granted {
print("Something went wrong")
}
}
// Objective-C
[center requestAuthorizationWithOptions:options
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
NSLog(#"Something went wrong");
}
}];
The framework calls the completion handler with a boolean indicating if the access was granted and an error object which will be nil if no error occurred.
Note: The user can change the notifications settings for your App at any time. You can check the allowed settings with getNotificationSettings. This calls a completion block asynchronously with a UNNotificationSettings object you can use to check the authorization status or the individual notification settings:
// Swift
center.getNotificationSettings { (settings) in
if settings.authorizationStatus != .authorized {
// Notifications not allowed
}
}
// Objective-C
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) {
// Notifications not allowed
}
}];
Creating A Notification Request
A UNNotificationRequest notification request contains content and a trigger condition:
Notification Content
The content of a notification is an instance of the UNMutableNotificationContent with the following properties set as required:
title: String containing the primary reason for the alert.
subtitle: String containing an alert subtitle (if required)
body: String containing the alert message text
badge: Number to show on the app’s icon.
sound: A sound to play when the alert is delivered. Use UNNotificationSound.default() or create a custom sound from a file.
launchImageName: name of a launch image to use if your app is launched in response to a notification.
userInfo: A dictionary of custom info to pass in the notification
attachments: An array of UNNotificationAttachment objects. Use to include audio, image or video content.
Note that when localizing the alert strings like the title it is better to use localizedUserNotificationString(forKey:arguments:) which delays loading the localization until the notification is delivered.
A quick example:
// Swift
let content = UNMutableNotificationContent()
content.title = "Don't forget"
content.body = "Buy some milk"
content.sound = UNNotificationSound.default()
// Objective-C
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.title = #"Don't forget";
content.body = #"Buy some milk";
content.sound = [UNNotificationSound defaultSound];
Notification Trigger
Trigger a notification based on time, calendar or location. The trigger can be repeating:
Time interval: Schedule a notification for a number of seconds later. For example to trigger in five minutes:
// Swift
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 300, repeats: false)
// Objective-C
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:300
repeats:NO];
Calendar: Trigger at a specific date and time. The trigger is created using a date components object which makes it easier for certain repeating intervals. To convert a Date to its date components use the current calendar. For example:
// Swift
let date = Date(timeIntervalSinceNow: 3600)
let triggerDate = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
// Objective-C
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:3600];
NSDateComponents *triggerDate = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear +
NSCalendarUnitMonth + NSCalendarUnitDay +
NSCalendarUnitHour + NSCalendarUnitMinute +
NSCalendarUnitSecond fromDate:date];
To create the trigger from the date components:
// Swift
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
// Objective-C
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDate
repeats:NO];
To create a trigger that repeats at a certain interval use the correct set of date components. For example, to have the notification repeat daily at the same time we need just the hour, minutes and seconds:
let triggerDaily = Calendar.current.dateComponents([hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
To have it repeat weekly at the same time we also need the weekday:
let triggerWeekly = Calendar.current.dateComponents([.weekday, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
Scheduling
With both the content and trigger ready we create a new notification request and add it to the notification center. Each notification request requires a string identifier for future reference:
// Swift
let identifier = "UYLLocalNotification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
// Something went wrong
}
})
// Objective-C
NSString *identifier = #"UYLLocalNotification";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier
content:content trigger:trigger]
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(#"Something went wrong: %#",error);
}
}];
To launch notification on specific time use below code.
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Body"
content.sound = UNNotificationSound.default()
let gregorian = Calendar(identifier: .gregorian)
let now = Date()
var components = gregorian.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)
// Change the time to 7:00:00 in your locale
components.hour = 7
components.minute = 0
components.second = 0
let date = gregorian.date(from: components)!
let triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second,], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let request = UNNotificationRequest(identifier: CommonViewController.Identifier, content: content, trigger: trigger)
print("INSIDE NOTIFICATION")
UNUserNotificationCenter.current().add(request, withCompletionHandler: {(error) in
if let error = error {
print("SOMETHING WENT WRONG")
}
})
And to launch constantly in specific time interval for example after every 2 minutes use below line for trigger.
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 120, repeats: true)
For Swift You can possibly Use this Code:
let calendar = Calendar.current
let components = DateComponents(year: 2018, month: 05, day: 06, hour: 20, minute: 22) // Set the date here when you want Notification
let date = calendar.date(from: components)
let comp2 = calendar.dateComponents([.year,.month,.day,.hour,.minute], from: date!)
let trigger = UNCalendarNotificationTrigger(dateMatching: comp2, repeats: true)
let content = UNMutableNotificationContent()
content.title = "Notification Demo"
content.subtitle = "Demo"
content.body = "Notification on specific date!!"
let request = UNNotificationRequest(
identifier: "identifier",
content: content,
trigger: trigger
)
UNUserNotificationCenter.current().add(request, withCompletionHandler: { error in
if error != nil {
//handle error
} else {
//notification set up successfully
}
})
Hope this Help.
This is the simplest way to add a notification at a specific time, and it is based off of Apple's Developer Documentation: https://developer.apple.com/documentation/usernotifications
Here is my implementation in a modular function:
public func simpleAddNotification(hour: Int, minute: Int, identifier: String, title: String, body: String) {
// Initialize User Notification Center Object
let center = UNUserNotificationCenter.current()
// The content of the Notification
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = .default
// The selected time to notify the user
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = hour
dateComponents.minute = minute
// The time/repeat trigger
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// Initializing the Notification Request object to add to the Notification Center
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
// Adding the notification to the center
center.add(request) { (error) in
if (error) != nil {
print(error!.localizedDescription)
}
}
}
try this
let dateformateer = NSDateFormatter()
dateformateer.timeStyle = .ShortStyle
let notification = UILocalNotification()
var datecomponent = NSDateComponents()
datecomponent = NSCalendar.currentCalendar().components([NSCalendarUnit.Day,NSCalendarUnit.Month,NSCalendarUnit.Hour,NSCalendarUnit.Year, NSCalendarUnit.Minute],fromDate: Datepicker.date)
var fixdate = NSDate()
fixdate = NSCalendar.currentCalendar().dateFromComponents(datecomponent)!
notification.fireDate = fixdate
notification.alertTitle = "Title"
notification.alertBody = "Body"
UIApplication.sharedApplication().scheduleLocalNotification(notification)`
I have the below notification that is being set up to fire at 9pm either on that day (if its currently before 9PM) or 9PM the next day (if its past 9PM already).
Everything seems to look right however it always just displays the notification right away no matter the current time.
let hour = 21
let minute = 0
let calendar = NSCalendar(identifier: .gregorian)!;
var dateFire = Date()
// if today's date is passed, use tomorrow
var fireComponents = calendar.components( [NSCalendar.Unit.day, NSCalendar.Unit.month, NSCalendar.Unit.year, NSCalendar.Unit.hour, NSCalendar.Unit.minute], from:dateFire)
if (fireComponents.hour! > hour
|| (fireComponents.hour == hour && fireComponents.minute! >= minute) ) {
dateFire = dateFire.addingTimeInterval(86400) // Use tomorrow's date
fireComponents = calendar.components( [NSCalendar.Unit.day, NSCalendar.Unit.month, NSCalendar.Unit.year, NSCalendar.Unit.hour, NSCalendar.Unit.minute], from:dateFire);
}
// set up the time
fireComponents.hour = hour
fireComponents.minute = minute
// schedule local notification
dateFire = calendar.date(from: fireComponents)!
print(dateFire)
let notification = UILocalNotification()
notification.alertBody = "TEST"
notification.soundName = "Default"
notification.fireDate = dateFire
UIApplication.shared.presentLocalNotificationNow(notification)
You're calling UIApplication.shared.presentLocalNotificationNow, which does exactly what it says, it presents the notification right as the method is called.
If you want to schedule a local notification, you need to first import UserNotifications (with iOS 10+)
import UserNotifications
Then you can schedule a notification like so:
func registerLocalNotification(date: Date) {
let content = UNMutableNotificationContent()
content.categoryIdentifier = "YOUR_IDENTIFIER"
content.title = "YOUR_TITLE"
content.body = "NOTIFICATION_BODY"
content.sound = UNNotificationSound.default()
// Use date components to create a trigger time
let triggerDate = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second,], from: date)
print("Register: \(triggerDate)")
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
// Instantiate the notification request
let request = UNNotificationRequest(identifier: "SOME_IDENTIFIER", content: content, trigger: trigger)
// Schedule the notification.
let center = UNUserNotificationCenter.current()
center.add(request) { (error) in
// Handle error if necessary
print("Notification Added")
}
}
You also need to make sure you've properly registered for notifications using the new UserNotifications in your AppDelegate
import UserNotifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
if granted {
UIApplication.shared.registerForRemoteNotifications()
}
}
return true
}
I want to schedule a local notification with a text like "Day 1" on first day and "Day 2" on second day like that:
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
let notification = UILocalNotification()
notification.fireDate = // ex: 5 am
notification.alertBody = "Day 1" // on second day it want to be "Day 2" , on third day it want to be "Day 3" like that..
notification.alertAction = "be awesome!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["CustomField1": "w00t"]
UIApplication.sharedApplication().scheduleLocalNotification(notification)
Is there any possibility to do this?
User will receive a notification of first Day as "Day 1"
Second Day as "Day 2"
Third Day as "Day 3"
Is it possible to set a notification like that?
You can schedule notifications for whole week with something like this:
func scheduleAwesomeNotifications() {
for day in 0...7 {
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
let intervalForDay = Double(60 * 60 * 24 * day)
let notification = UILocalNotification()
notification.fireDate = NSDate().dateByAddingTimeInterval(intervalForDay)
notification.alertBody = "Day " + day.description
notification.alertAction = "be awesome!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["CustomField1": "w00t"]
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
}
I'm a newbie in iOS programming and in my app I've a UILocaleNotification which have to appear at a certain time.
So first I setup parameters :
let notificationSettings: UIUserNotificationSettings! = UIApplication.sharedApplication().currentUserNotificationSettings()
if (notificationSettings.types == UIUserNotificationType.None) {
var notificationTypes: UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Sound
// Bouton d'envoi
var sendAction = UIMutableUserNotificationAction()
sendAction.identifier = "send"
sendAction.title = "Send"
sendAction.activationMode = UIUserNotificationActivationMode.Foreground
sendAction.destructive = false
sendAction.authenticationRequired = true
// Bouton de non-envoi
var dontSendAction = UIMutableUserNotificationAction()
dontSendAction.identifier = "dontsend"
dontSendAction.title = "Don't send"
dontSendAction.activationMode = UIUserNotificationActivationMode.Background
dontSendAction.destructive = true
dontSendAction.authenticationRequired = false
let actionsArray = NSArray(objects: sendAction, dontSendAction)
var reminderNotification = UIMutableUserNotificationCategory()
reminderNotification.identifier = "reminderNotification"
reminderNotification.setActions(actionsArray as [AnyObject], forContext: UIUserNotificationActionContext.Minimal)
let categoriesForSettings = NSSet(objects: reminderNotification)
let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categoriesForSettings as Set<NSObject>)
UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
}
... and I schedule my notification like that :
var localNotification = UILocalNotification()
localNotification.fireDate = NSDate(timeIntervalSinceNow: 3)
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = "Hey, inform your contacts !"
localNotification.alertAction = "Send Message"
localNotification.category = "reminderNotification"
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
When I try this code, notifs are displaying right in the notification center, but there is no pop-up displayed...
I searched sources on the net and I don't understand why those examples and tutos are displaying pop-up because I wrote the same code...
Thanks for your help and have a good day !
EDIT : I forgot something : it's the notification center which have to detect an event, and not the locale notification. So I want the addObserver of the notification center to check an event, is it possible in background state ?
According to this line: localNotification.fireDate = NSDate(timeIntervalSinceNow: 3) you want your notification to be triggered 3 seconds later. I assume that the app is still in the foreground when it happens. If it's the case, you will not have a notification popup.
If the app linked to a notification is opened when the notification is received, it has to handle it in your AppDelegate to display a custom popup.
func application(application: UIApplication!, didReceiveLocalNotification notification: UILocalNotification!) {
// do your jobs here
}