Is it possible to get the UNNotificationRequest identifier of a tapped local notification button or any other information about the notification? Maybe via a delegate?
Thankyou
The identifier of the notification is obtained like so:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let identifier = response.notification.request.identifier
switch response.actionIdentifier {
case "snoozeAction":
print ("Snooze Tapped - identifier :", identifier)
nc.post(name: Notification.Name("didTapSnooze"), object: nil)
default:
break
}
completionHandler()
}
Related
I'm working on an app that handles push notifications.
For some reason,
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
Works as expected, but
func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
is never called.
Anyone ever come across this situation?
All the usual suspects are in place:
UNUserNotificationCenter.current().delegate = self
is set in didFinishLaunchingWithOptions
let center = UNUserNotificationCenter.current()
UNUserNotificationCenter.current().delegate = self
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options:options) { (granted, error) in
if error == nil{
DispatchQueue.main.async() {
UIApplication.shared.registerForRemoteNotifications()
completion(granted)
}
}
}
is returning true (permission granted)
Other items worth mentioning:
The Push notifications are sent via SendBird
When the app is in the background, everything works as expected.
Times and again, read the documentation.
Apple states for func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void):
Asks the delegate how to handle a notification that arrived while the app was running in the foreground.
That is, only when your app is running in FORGROUND and you get a notification will the system call this method to ask you whether this notification should still be shown to the user since they're already inside your app. You can call the completionHandler and pass in options like alert and sound so the user will still see the banner and hear the sound. If you only pass back sound, then the user sees no banner and only hears the notification sound.
I need to get local notification data from lock screen or apps was kill. Is there a way to detect it or any handler that would trigger after show?.
i try using UNUserNotificationCenter present and UNUserNotificationCenter didReceive but still not working..
response.notification.request.content.userInfo contains the notification data
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
completionHandler()
guard let bodyText = response.notification.request.content.userInfo["body"] as? String else {return}
}
func application(_ application: UIApplication, didReceiveRemoteNotification
userInfo: [AnyHashable : Any])
{
if application.applicationState == .inactive || application.applicationState == .background
{
//opened from a push notification when the app was on background
}
}
Please tell me how can I know when local notification is trigger in Swift 4? I have tried everything it seem not working.
You can create local notification as
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: true)
let content = UNMutableNotificationContent.init()
content.title = "Danger Will Robinson"
content.subtitle = "Something This Way Comes"
content.body = "I need to tell you something, but first read this."
let notification = UNUserNotificationCenter.current()
notification.add(UNNotificationRequest.init(identifier: "notification", content: content, trigger: trigger), withCompletionHandler: nil)
When notification is triggered in background and user taps the notification.
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Swift.Void)
When notification is triggered and app is in foreground.
public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Swift.Void)
You must confirm UNUserNotificationCenterDelegate to get the triggers.
So best approach is you initialise local notification in appDelegate.
I have the following code blocks in my AppDelagate:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
}
func showMessage()
{
let notification = UNMutableNotificationContent()
notification.title = "Test"
notification.subtitle = "This is a test"
notification.body = "I need to tell you something, but first read this."
notification.categoryIdentifier = "TESTAPP"
notification.sound = UNNotificationSound.default()
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.5, repeats: false)
let request = UNNotificationRequest(identifier: "notification1", content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
func applicationDidEnterBackground(_ application: UIApplication) {
let center = UNUserNotificationCenter.current()
center.delegate = self
self.showMessage()
}
My notification comes up and when I click on the notification to open the app, the app opens up and the console shows this:
App is Open
2017-07-23 14:48:56.182 Form[3255:198009] Warning:
UNUserNotificationCenter delegate received call to
-userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
but the completion handler was never called.
So it looks like my print to type out "App is open" it displaying but I am getting the completion handler error right below it.
Add completionHandler() under your code in
userNotificationCenter
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
completionHandler()
}
You need to make sure you call the completion handler within the method to let the system know you are done processing the notification.
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
// Execute completion handler
completionHandler()
}
How do I set up my AppDelegate to handle push notifications that occur when the app is in the foreground and in the background with swift 3 and ios 10? Including how to make the phone vibrate while in the foreground if I receive a notifcation.
Here is how I set up my AppDelegate file to do this:
To handle push notifications, import the following framework:
import UserNotifications
To make the phone vibrate on any device import the following framework:
import AudioToolbox
Make your AppDelegate a UNUserNotificationCenterDelegate:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
In your "didFinishLaunchingWithOptions" add this:
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert], completionHandler: {(granted, error) in
if (granted) {
UIApplication.shared.registerForRemoteNotifications()
} else{
print("Notification permissions not granted")
}
})
This will determine if the user has previously said that your app can send notifications. If not, handle it how you please.
To get access to the device token once it is registered:
//Completed registering for notifications. Store the device token to be saved later
func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) {
self.deviceTokenString = deviceToken.hexString
}
hexString is an extension I added to my project:
extension Data {
var hexString: String {
return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
}
}
To handle what happens when your app receives a notification in the foreground:
//Called when a notification is delivered to a foreground app.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
//Handle the notification
//This will get the text sent in your notification
let body = notification.request.content.body
//This works for iphone 7 and above using haptic feedback
let feedbackGenerator = UINotificationFeedbackGenerator()
feedbackGenerator.notificationOccurred(.success)
//This works for all devices. Choose one or the other.
AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate), nil)
}
To handle what happens when a users presses on a notification they receive (from your application) while your app is in the background, call the following function:
//Called when a notification is interacted with for a background app.
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
//Handle the notification
print("did receive")
let body = response.notification.request.content.body
completionHandler()
}
I would add to havak5's answer that you can set push notifications to be shown as iOS default push, just like this:
swift code:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
if UIApplication.shared.applicationState == .active {
completionHandler( [.alert,.sound]) // completionHandler will show alert and sound from foreground app, just like a push that is shown from background app
}
}