Why can't I read push message data in Swift5? - ios

I have a problem that I cannot read the push message data at this time. I get a message normally.
I can receive both when the app is in Foreground or Background when I press the Home button.
But I can't see the message data in the log.
AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
...
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
guard
let aps = data[AnyHashable("notification")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
Log.Info("Title: \(title) \nBody:\(body)")
Messaging.messaging().appDidReceiveMessage(data)
// Print full message.
Log.Info(data)
}
...
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
Log.Info("fcmToken \(fcmToken)")
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
Log.Info("remort \(remoteMessage.appData)")
}
Data I Send
{
notification : {
"title" : "test title.",
"body" : "test context."
},
data : {
"image" : "http://11.111.111.111:100000000/_img/sample_01.jpg",
"page_url" : "http://11.111.111.111:100000000/Point?address=",
"type" : "point"
}
}
Logs cannot be viewed in any function. What am I missing? Please let me know what's wrong.
EDIT
I modified the wrong data and changed the location of the log. But I don't have any logs on me.
AppDelegate.swift
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Print full message.
Log.Info(data)
guard
let aps = data[AnyHashable("notification")] as? NSDictionary,
let body = aps["body"] as? String,
let title = aps["title"] as? String
else {
// handle any error here
return
}
Log.Info("Title: \(title) \nBody:\(body)")
Messaging.messaging().appDidReceiveMessage(data)
}
send test message in firebase
I have two messaging functions in addition to application functions of the application. Are these message functions not needed by me? These functions have never shown me a log.

The method that you are using was deprecated in iOS 10.
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623117-application
The Notifications framework replaced this method with the updated one from iOS 10 onwards:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void)
More details of the Notifications framework are available here

This solved this problem using a different function.
I solved it using a different function, but I wish there was another good solution.
I wonder what the fundamental problem was. This is just another alternative.
#available(iOS 10, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let data = response.notification.request.content.userInfo
guard
let aps = data[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String
else {
Log.Error("it's not good data")
return
}
Log.Info(body)
completionHandler()
}

Related

How to run the function without showing the push message when it is sent?

I have a problem to solve with a push message. If I send a push message to Firebase,I will receive it well and I will see the message well.
And when I click on the push message, the userNotificationCenter function in the AppDelegate file is executed and the list of actions in the function is executed.
Can I execute a function without receiving a specific message and displaying a message?
Where I'm currently receiving and processing push messages.
#available(iOS 10, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let data = response.notification.request.content.userInfo
guard
let push = data[AnyHashable("push")] as? String,
let getdata = data[AnyHashable("getdata")] as? String,
let pushdata = data[AnyHashable("pushdata")] as? String
else {
print("it's not good data")
return
}
print(push)
print(getdata)
print(pushdata)
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([.alert, .badge, .sound])
}
My purpose is to execute the function without showing the push message to the user when sending a specific message (Ex: push = "noShowPush") from the Firebase.
EDit
I was tried "content_available": true
but get log 6.10.0 - [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
// Override point for customization after application launch.
//create the notificationCenter
Messaging.messaging().delegate = self
FirebaseApp.configure()
//Register App For Push Notification
// self.registerAppForPushNotificaition()
let center = UNUserNotificationCenter.current()
let inviteCategory = UNNotificationCategory(identifier: "Notification", actions: [], intentIdentifiers: [], options: UNNotificationCategoryOptions.customDismissAction)
let categories = NSSet(objects: inviteCategory)
center.delegate = self
center.setNotificationCategories(categories as! Set<UNNotificationCategory>)
DispatchQueue.main.async(execute: {
UIApplication.shared.registerForRemoteNotifications()
})
application.registerForRemoteNotifications()
self.updateAppViewUI()
self.window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if Auth.auth().canHandleNotification(userInfo) {
completionHandler(UIBackgroundFetchResult.noData)
return
}
completionHandler(UIBackgroundFetchResult.newData)
}
I have it already Messaging.messaging().delegate = self.
The logs in the Firebase have warned you to set FirebaseAppDelegateProxyEnabled to No, so I added to the Info.list.
and Firebase log changed [Firebase/Core][I-COR000003] The default Firebase app has not yet been configured. Add '[FIRApp configure];' ('FirebaseApp.configure()' in Swift) to your application initialization. Read more:
Are the things I'm revising are going right?
How can I this solution?
I solved the problem. Here's the order in which I've worked out:
Write when you send a push "content_available": true". And don't
include the title and body.
And when I got these error logs, 6.10.0 -
[Firebase/Messaging][I-FCM002019] FIRMessaging received
data-message, but
FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
The logs in the Firebase have warned you to set
FirebaseAppDelegateProxyEnabled to No, so I added to the
Info.list.
and changed the order of execution of the function.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure() // Let it run first.
Messaging.messaging().delegate = self
self.window = UIWindow(frame: UIScreen.main.bounds)
...
And I installed 'Firebase/Analytics' on the pod.
pod 'Firebase/Analytics'
and inherited the MessagingDelegate and implemented the
Messaging function.
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("fcmToken \(fcmToken)")
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
Log.Info("remort \(remoteMessage.appData)")
let userInfo = remoteMessage.appData
}
This configuration allows you to receive push message data into the messaging function when a push message is sent. This is a push message with a 'contentAvailable' value of True and no title and body.

Notification from Firebase stopped appearing on iOS

Last night I was testing Push Notifications from Firebase in my iOS app, and it was working as expected
I was able to send a notification from at Cloud Function to a specific FCM token.
This morning notification doesn't arrive when using the same method.
Cloud Function
Here's the function that I use to send the notification:
function sendNotification(title: string, body: string, token: string): Promise<void> {
const message: admin.messaging.Message = {
apns: {
headers: {
'apns-priority': '10'
},
payload: {
aps: {
alert: {
title: title,
body: body,
},
sound: "default"
}
}
},
token: token
}
return admin.messaging().send(message).then(response => { console.log(`Notification response ${response}`) }).then(justVoid)
}
Here token is the token I received from the InstanceId in the iOS app.
When this function is triggered, I see the following in Firebase web console's Cloud Function log:
Notification response projects/project-name/messages/0:1571998931167276%0f7d46fcf9fd7ecd
Which, as far as I understand, is a success message. So I'm expecting the notification to show up on the device at this point, but nothing.
iOS App
I've followed this guide to troubleshoot, and am sure that the setup is right: https://firebase.google.com/docs/cloud-messaging/ios/first-message?authuser=0
I did try to re-install the app on the device on which Im testing: I've verified that the app does through these step after re-install:
call: UNUserNotificationCenter.current().requestAuthorization(options:, completionHandler:)
call: UIApplication.shared.registerForRemoteNotifications()
listen to updated FCM token by implementing: func messaging(_ messaging:, didReceiveRegistrationToken fcmToken:)
call: InstanceID.instanceID().instanceID(handler:)
double check that notifications is allowed for my application in the iOS settings app.
Test Notification from console
I've tried sending a Test Notification in from Notification Composer, using a the recent FCM token for the test device, but this notification doesn't show up either, and it doesn't give me any feedback on screen whether the notification is successfully sendt or not.
What am I doing wrong here?
Any Suggestions to how I can debug this issue?
When we are working with Push Notification then it is very harder to debug issue.
As per my experience, there is nothing wrong with your typescript or iOS code because earlier it was worked perfectly. Below is the possible reason if the push notification is not working.
Generally, the APNS related issue occurs due to the certificate.
Make sure you are uploading the correct APNS profile to the firebase
console for both development and release mode.
Make sure you have enabled the notification in capabilities.
Your Project -> capabilities -> turn on Push Notifications
Make sure you're added correct GoogleService-Info.plist to the
project.
APNS Certificate is not expired.
Make sure you're using the latest version of the firebase.
Your device time should be automatic, not feature time.
If you still think it is code related issue and the above solution is not working then you can go with the below wrapper class of HSAPNSHelper class which is created by me and it is working for iOS 10 and later .
import Foundation
import UserNotifications
import Firebase
class HSAPNSHelper: NSObject {
static let shared = HSAPNSHelper()
let local_fcm_token = "local_fcm_token"
var notificationID = ""
func registerForPushNotification(application:UIApplication){
FirebaseApp.configure()
self.getFCMToken()
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
DispatchQueue.main.async {
self.getFCMToken()
}
}
application.registerForRemoteNotifications()
}
}
extension HSAPNSHelper:UNUserNotificationCenterDelegate {
fileprivate func getFCMToken() {
InstanceID.instanceID().instanceID(handler: { (result, error) in
if error == nil, let fcmToken = result?.token{
print("FCM Token HS: \(fcmToken)")
UserDefaults.standard.set(fcmToken, forKey: self.local_fcm_token)
}
})
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("didFailToRegisterForRemoteNotificationsWithError : \(error)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var token = ""
for i in 0..<deviceToken.count {
token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
}
Messaging.messaging().apnsToken = deviceToken
getFCMToken()
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo as! [String: Any]
print(userInfo)
completionHandler([.alert, .badge, .sound])
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
self.notificationRedirection()
}
private func notificationRedirection(){
}
func fcmToken() -> String{
return UserDefaults.standard.string(forKey:local_fcm_token) ?? ""
}
}
How to use?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//For Push notification implementation
HSAPNSHelper.shared.registerForPushNotification(application: application)
return true
}
Use fcmToken() to get current FCM token.

FCM push for iOS callback not called

I have a problem with FCM push notifications.
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Swift.Void)
and
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Swift.Void)
are not called when I receive a push. The notification is generated in my iPhone.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
is called instead but I don't understand why because it's deprecated.
The content of my notification:
{
"to": "FCM Token",
"priority": "high",
"content_available": true,
"notification": {
"sound": "default",
"title": "Test",
"body": "Test",
"description": "Test"
},
"data": {
"id": 123456,
"status": "11",
}
}
In my AppDelegate.swift:
import UIKit
import CoreData
import Firebase
import Fabric
import Crashlytics
import GoogleMaps
import GooglePlaces
import FBSDKLoginKit
import GoogleSignIn
import NotificationBannerSwift
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
return ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(_ application: UIApplication) {
pprint(" - applicationWillResignActive - ")
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
AppEvents.activateApp()
}
func applicationDidEnterBackground(_ application: UIApplication) {
pprint(" - applicationDidEnterBackground - ")
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
pprint(" - applicationWillEnterForeground - ")
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
pprint(" - applicationDidBecomeActive - ")
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
pprint(" - applicationWillTerminate - ")
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
private func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
pprint("apns token: ", deviceToken)
Messaging.messaging().apnsToken = deviceToken as Data
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
print(" ")
print("-- New message classique --")
print("Notification received : \(userInfo)")
print(" ")
// Print full message.
print(userInfo)
completionHandler(.noData)
}
// MARK: - UNUserNotificationCenterDelegate methods
extension AppDelegate: UNUserNotificationCenterDelegate {
// FOREGROUND: The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Swift.Void) {
DispatchQueue.main.async {
// print("will present: ", notification)
// Messaging.messaging().appDidReceiveMessage(notification.request.content.userInfo)
// completionHandler(.alert)
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
print(" ")
print("Notification received : \(notification)")
print("-- New message from Notification ios10 only --")
print(" ")
guard
let aps = userInfo[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
let banner = NotificationBanner(title: title, subtitle: body, style: .success)
banner.show()
// Change this to your preferred presentation option
//completionHandler([])
}
}
// BACKGROUND: The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from applicationDidFinishLaunching:.
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Swift.Void) {
DispatchQueue.main.async {
print("didReceive")
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo["gcmMessageIDKey"] {
print("Message ID: \(messageID)")
}
print(userInfo)
if let body = userInfo["body"] as? String {
print("inbody")
NotificationCenter.default.post(name: Notification.Name("userInfo"), object: body)
}
//Push().handlePush(info: userInfo)
// Print full message.
print(userInfo)
Messaging.messaging().appDidReceiveMessage(response.notification.request.content.userInfo)
completionHandler()
}
}
}
// MARK: - MessagingDelegate methods
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
//log.info("FCM registration token received = \(fcmToken)")
print("FCM registration token received = \(fcmToken)")
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
//log.info("didReceive message = \(remoteMessage)")
print("didReceive message = \(remoteMessage)")
}
func applicationReceivedRemoteMessage(_ remoteMessage: MessagingRemoteMessage) {
print(" - - - FIR Remote message - - - ")
print("%#", remoteMessage.appData)
//Push().handlePush(info: remoteMessage.appData)
}
}
In my Info.plist I have FirebaseAppdelegateProxyEnable set to NO
In capabilities, I have Push Notifications enabled and Remote Notifications are enabled too in Background Mode.
I'm using Xcode 11.1. I have converted my project to Swift 5 (it was created with Swift 3), I have changed the build system to the new one.
I have two targets with this project I don't know if it can be related to my issue.
I try with an empty new project with the same AppDelegate.swift, same bundle identifier and it works.
try this
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
// put your code here
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
// put your code here
}

How to store ios push notifications when the app is killed using swift

I use my own server, use FCM to push notifications to the ios device, push notifications are successful, I also use the Realm database system to help me store the fcm push notifications, but the storage will only succeed in the following two cases.
Case1: When the app is running.
Case2: The app is killed, or running in the background, when you click to push the banner notification.
But this is not my main intention. I know that when the app is killed, I can't handle the push notifications, so I want to be able to store the push notifications when the user opens the app.
Sorry, my English is not good. If there is something unclear, please let me know.
Realm class
class Order: Object {
#objc dynamic var id = UUID().uuidString
#objc dynamic var name = ""
#objc dynamic var amount = ""
#objc dynamic var createDate = Date()
override static func primaryKey() -> String? {
return "id"
}
let realm = try! Realm()
let order: Order = Order()
AppDelegate.swift (when app runing store fcm message)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo //
print("userInfo: \(userInfo)")
guard
let aps = userInfo[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
order.name = title
order.amount = body
try! realm.write {
realm.add(order)
}
completionHandler([.badge, .sound, .alert])
}
click to push the banner notification
AppDelegate.swift (when app killed or on backgroung click to push the banner notification)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("userInfo: \(userInfo)")
guard
let aps = userInfo[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
order.name = title
order.amount = body
try! realm.write {
realm.add(order)
}
completionHandler()
}
Please have experienced people to help me, thank you very much.
You can store notifications into your database when your app is killed.
Add "Notification Service Extention" to your app.
Enable Background fetch/Remote notifications Capabilities into your app.
Enable "App Groups" into your app and enable the same with your "Notification Service Extention".
Now you can access your database using "App Groups", and can insert notifications into your database as soon as you receive the notification.
To access database using "App Group" use,
var fileMgr : FileManager!
let databasePathURL = fileMgr!.containerURL(forSecurityApplicationGroupIdentifier: "<APP_GROUPS_ID>")
From above code once you get the path for database, you can perform your insert operation into database. It would be your normal insert operation that you are performing.
Insert code for saving data in this file and in the method highlighted in below image.
For accessing your files into Extention follow the below image.
If you need any other help, Do let me know.

How to get userInfo when user click in notification when app is closed?

I'm doing an app that schedule local notifications and save an userInfo. That's part its ok.
But when app is closed, Notification appear, but when user click, the method is not called and I can't handle userInfo.
I saw that there's a new way to receive notification with UNUserNotificationCenter. But is not working too.
That's my implementation in AppDelegate:
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let lNotification = UILocalNotification()
lNotification.userInfo = response.notification.request.content.userInfo
applicationWorker.manage(localNotification: lNotification)
}
Anyone to help me? I saw all the questions related here and didn't found anything.
Thanks!
EDIT:
If someone are looking for a solution, I added UNUserNotificationCenter.current().delegate = self in didFinishLaunchingWithOptions and it worked.
From iOS 10 onwards, the method you mention should be called whether app is opening from background or inactive state. Perhaps you are not accessing the userInfo correctly. The example below works for me.
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let yourData = userInfo["yourKey"] as? String {
// Handle your data here, pass it to a view controller etc.
}
}
Edit: as per the edit to the question, the notification centre delegate must be set in the didFinishLaunching() method, or the method above will not get called.
UNUserNotificationCenter.current().delegate = self
You can got the notification user info from launch option when application open from notification. Here is the code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: AnyObject] {
if let aps = notification["aps"] as? NSDictionary
{
}
}
}

Resources