Ios Swift : Add Message Tone and Vibration when notification received - ios

Using IOS 9 and Swift 2
I have written a function to call Notification when needed.
How do i add Msg Tone and Vibration when notification received :
func getNotification(message:String)
{
let curentSeting = UIApplication.sharedApplication().currentUserNotificationSettings()
if(curentSeting!.types == .None)
{
let newSeting = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(newSeting)
}
let nfnVar = UILocalNotification()
nfnVar.fireDate = NSDate(timeIntervalSinceNow: 0)
nfnVar.alertBody = message
nfnVar.soundName = UILocalNotificationDefaultSoundName
nfnVar.userInfo = ["NamKey":"NamVey"]
UIApplication.sharedApplication().scheduleLocalNotification(nfnVar)
}

Related

UILocalNotifications not firing when scheduled

Well, none of the existing discussions presented a working solution for me. So here's my code to show local notifications. What am I missing?
let notification = UILocalNotification()
notification.alertBody = "Reminder" // text that will be displayed in the notification
notification.alertAction = "open"
notification.applicationIconBadgeNumber = 1
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = NSDate(timeIntervalSinceNow: 5)
print("Notification scheduled")
notification.userInfo = ["title": "Test", "UUID": "1"]
notification.repeatInterval = NSCalendarUnit.WeekOfMonth
UIApplication.sharedApplication().scheduleLocalNotification(notification)
I'm aware that when the app is in foreground there should be an event in didReceiveLocalNotification. I do not get an event in the appdelegate's didReceiveLocalNotification or the notification. However, when I use presentLocalNotificationNow with the notification - I the didReceiveLocalNotification in app delegate does get called. I also tried with other fireDates but it doesn't work. What am I missing?
Oh and I do have the below code in my appdelegate didfinishlaunchingapplication
let application = UIApplication.sharedApplication()
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
I had been testing, and this are my results, the problem seems to be related with time unit weekOfMonth with day works as intended, here is the picture of console log, using XCode 8.2, device iOS 10.2, still working
func scheduleTestNotification()
{
let notification = UILocalNotification()
notification.alertBody = "Reminder" // text that will be displayed in the notification
notification.alertAction = "open"
notification.applicationIconBadgeNumber = 1
notification.soundName = UILocalNotificationDefaultSoundName
notification.timeZone = NSTimeZone.default
notification.fireDate = Date(timeIntervalSinceNow: 5)
print("Notification scheduled")
notification.userInfo = ["title": "Test", "UUID": "1"]
notification.repeatInterval = NSCalendar.Unit.day
UIApplication.shared.scheduleLocalNotification(notification)
debugPrint(UIApplication.shared.scheduledLocalNotifications!)
}
but if I use weekOfMonth then
I think you can use this code as a workaround, it's not the best solution, but maybe can help you to achieve what you need
func scheduleTestNotification()
{
let notification = UILocalNotification()
notification.alertBody = "Reminder" // text that will be displayed in the notification
notification.alertAction = "open"
notification.applicationIconBadgeNumber = 1
notification.soundName = UILocalNotificationDefaultSoundName
notification.timeZone = NSTimeZone.default
notification.fireDate = Date(timeIntervalSinceNow: 5)
print("Notification scheduled")
notification.userInfo = ["title": "Test", "UUID": "1"]
UIApplication.shared.scheduleLocalNotification(notification)
notification.repeatInterval = NSCalendar.Unit.day
notification.fireDate = Calendar.current.date(byAdding: .day, value: 7, to: notification.fireDate!)
UIApplication.shared.scheduleLocalNotification(notification)
debugPrint(UIApplication.shared.scheduledLocalNotifications!)
}
I hope this helps you
To send notification in iOS 10 you need to ask permission as bellow before you fire the notification.
func requestPermition() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in
if settings.authorizationStatus != .authorized {
let options: UNAuthorizationOptions = [.alert, .sound];
center.requestAuthorization(options: options) {
(granted, error) in
if !granted {
print("Something went wrong")
}else {
print("permition granted")
}
}
}
}
}
UILocalNotification is deprecated in iOS 10 you may use UNUserNotificationCenter instead.to fire a notification try bellow code
//to fire notification after 5 seconds.
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5,
repeats: false)
//Set contents to be desplayed on the notification
let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = "Test reminder"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "myCategory"
let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)
//set UNNotificationActionOptions .foreground if you need to open when button tapped.
let action = UNNotificationAction(identifier: "remindOpen", title: "Open", options: [.foreground])
let category = UNNotificationCategory(identifier: "myCategory", actions: [action], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("notification error: \(error)")
}
}
I tested and this code works on my side, iOS 10 with XCode 8.2
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert ], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
let notification = UILocalNotification()
notification.alertBody = "Reminder" // text that will be displayed in the notification
notification.alertAction = "open"
notification.applicationIconBadgeNumber = 1
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = Date(timeIntervalSinceNow: 5)
print("Notification scheduled")
notification.userInfo = ["title": "Test", "UUID": "1"]
notification.repeatInterval = NSCalendar.Unit.minute
UIApplication.shared.cancelAllLocalNotifications()
UIApplication.shared.scheduleLocalNotification(notification)
The method didReceiveNotification is called whenever the app pushes a local notification. My repeatInterval is minute instead of weekOfMonth. I think weekOfMonth is the problem because when I change repeatInterval to weekOfMonth, I did not receive notifications, the method didReceiveNotification never called.
So I also encountered a same problem.
I was trying to fire UILocalNotification from background fetch. I had UILocalNotification scheduled, I stepped through in Xcode, make sure that scheduleLocalNotification was called, but it only fired about 1/5 times.
It seems that scheduling UINotification from background fetch simply does not work reliably in iOS 10. I switched to using UNUserNotification and it fires reliably, every time I step through the code.

Push Notifications for Swift iOS 10

I'm struggling to get push notifications to work with Swift with iOS 10. Registering seems to be going through successfully, but creating a notificaiton does nothing on the device and returns a nil error. Any ideas what I'm missing?
import Foundation
import UIKit
import UserNotifications
class SPKPushNotifications
{
class func register(application:UIApplication){
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
// Enable or disable features based on authorization.
application.registerForRemoteNotifications()
}
} else {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
}
}
class func unregister(application:UIApplication){
application.unregisterForRemoteNotifications()
}
class func create(title:String, body:String, delay:Double, repeats:Bool){
if #available(iOS 10.0, *) {
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = UNNotificationSound.default() //idk if we're gonna want something else
content.badge = NSNumber(value:UIApplication.shared.applicationIconBadgeNumber+1)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval:delay, repeats:repeats)
let request = UNNotificationRequest(identifier:title, content:content, trigger:trigger)
let center = UNUserNotificationCenter.current()
center.add(request){ (error) in
print(error)
}
} else {
// Fallback on earlier versions
}
}
class func delete(){
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.removeAllDeliveredNotifications()
} else {
// Fallback on earlier versions
}
}
}
You won't see the notification if the application is in the foreground. Try adding the request to the notification center when the application is in the background.
You can do (for this test only) that by adding a few second sleep and moving your application to the background. Or scheduling the notification to a later time when the application is not running in the foreground.

How can I have different UIUserNotificationSettings when there are many kinds of Notification

In my project I have a problem: there are two different notifications.
One of them need two UIMutableUserNotificationActions (OK and Cancel) and the other needs only one (Remind me later).
Here is the code:
let completeAction = UIMutableUserNotificationAction()
completeAction.identifier = "OK" // the unique identifier for this action
completeAction.title = "OK" // title for the action button
completeAction.activationMode = .Background // UIUserNotificationActivationMode.Background - don't bring app to foreground
completeAction.authenticationRequired = false // don't require unlocking before performing action
completeAction.destructive = true // display action in red
let cancelAction = UIMutableUserNotificationAction()
cancelAction.identifier = "Cancel"
if #available(iOS 9.0, *) {
cancelAction.parameters = [UIUserNotificationTextInputActionButtonTitleKey : "Send"]
} else {
// Fallback on earlier versions
}
cancelAction.title = "Cancel"
if #available(iOS 9.0, *) {
cancelAction.behavior = UIUserNotificationActionBehavior.TextInput
} else {
// Fallback on earlier versions
}
cancelAction.activationMode = .Background
cancelAction.destructive = false
cancelAction.authenticationRequired = false
let todoCategory = UIMutableUserNotificationCategory() // notification categories allow us to create groups of actions that we can associate with a notification
todoCategory.identifier = "TODO_CATEGORY"
todoCategory.setActions([cancelAction, completeAction], forContext: .Minimal) // UIUserNotificationActionContext.Default (4 actions max)
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge , .Sound], categories: NSSet(array: [todoCategory]) as? Set<UIUserNotificationCategory>))
But there's only one condition of UIUserNotificationSettings.
Finally , i found an answer and solve my problem perfectly. I copy the code here in case someone find the same problem that i did.
there's a way that IOS allow you have different notification actions, UIMutableUserNotificationCategory
let cancelCategory = UIMutableUserNotificationCategory() // notification categories allow us to create groups of actions that we can associate with a notification
cancelCategory.identifier = "Notification_Category"
cancelCategory.setActions([cancelAction], forContext: .Default) //
And
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge , .Sound], categories: NSSet(array: [todoCategory,cancelCategory]) as? Set<UIUserNotificationCategory>)
method allow you have several notification categories.
Last step. when you backend wanna push a notification. you just should build a part of key value ("category"=>"your category identifier"), and every thing has done.
(body['aps'] = array('alert' => '','sound' => 'default','link_url' => '','category' => 'Notification_Category',);)

How can I add action buttons/actions to UILocalNotification alert?

I have a local notification scheduled in my app, and right now I get a generic cancel (cross) button as I swipe the alert to the left.
I'm curious if I can add custom buttons/actions to it like on the image below?
I prepared for you some snipped code which shows notification with one button 10 second after ViewDidLoad method did shown.
import UIKit
class TestViewController: UIViewController {
let category = UIMutableUserNotificationCategory()
override func viewDidLoad() {
super.viewDidLoad()
let restartAction = UIMutableUserNotificationAction()
restartAction.identifier = "xx"
restartAction.destructive = false
restartAction.title = "Restart"
restartAction.activationMode = .Background
restartAction.authenticationRequired = false
let categoryIdentifier = "category.identifier"
category.identifier = categoryIdentifier
category.setActions([restartAction], forContext: .Minimal)
category.setActions([restartAction], forContext: .Default)
let categories = Set(arrayLiteral: category)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: categories)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
let localNotif = UILocalNotification()
localNotif.alertBody = "testBody"
localNotif.category = categoryIdentifier
// Notification will be shown after 10 second (IMPORTANT: if you want to see notification you have to close or put app into background)
localNotif.fireDate = NSDate().dateByAddingTimeInterval(10)
UIApplication.sharedApplication().scheduleLocalNotification(localNotif)
}
}
Note: you have to handle action in AppDelegate method:
func application(application: UIApplication, handleActionWithIdentifier identifier: String?,
forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
completionHandler()
}
Of course my code is not as clean as it should be, but you have to know that I wrote it only for presentation purposes.
This code is written in Swift but convertion to Objective C should be very simple.

iOS locale notification pop-up doesn't appear

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
}

Resources