Push Notification "willPresent" not called but "didReceive" works - swift

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.

Related

Notification permission request window does not appear in swift

My app has a function that pops up information in a notification in a few seconds when a button is clicked.
It used to work before, but these days it does not.
I checked and the permission request window does not appear.
Do I need to fix something? Code is below:
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound]) { (result, Error) in
print("result = \(result)")
}
AppDelegate:
UNUserNotificationCenter.current().delegate = self
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions)
-> Void) {
completionHandler([.alert, .badge, .sound])
}

Handle notification dismiss action when app is on the background

I'm trying to listen user clear push notification action. I've the code below, It's working when the app is on the foreground but when i put the app on the background it doesn't go into that function. Is there any way that i can do some coding when the user clear the notification on the background state?
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
if(response.actionIdentifier == UNNotificationDismissActionIdentifier){
...
//I need to do some coding here!
}
}
I use this for receiving remote notifications behind the scenes:
extension AppDelegate: UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// Process this userInfo dictionary
processNotification(dictionary: userInfo)
}
In my willFinishLaunchingWithOptions in AppDelegate I call this:
fileprivate func setupAPN(application: UIApplication) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
// For iOS 10 data message (sent via FCM)
MobilePlatformPush.setRemoteDelegate(delegate: self)
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { _, _ in }
application.registerForRemoteNotifications()
}

Swift UNNotificationRequest identifier of action button tapped local notification

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()
}

How to know when ios local notification is triggered?

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.

How do I handle ios push notifications when the app is in the foreground?

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
}
}