我正在使用FCM服务器进行远程通知,它可以完美地发送和接收通知。
我的问题是,当设备处于后台时,此功能func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
没有被调用。
我尝试过的解决方案:
此功能:
userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
。否则,它不会被触发。
向有效负载添加"content-available": true, "priority": "high"
。另外,我尝试了此值"content-available": 1
。
这是我的功能代码:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("userInfo: \(userInfo)")
completionHandler(.newData);
}
答案 0 :(得分:2)
您需要查看的所有后台和前台远程通知,并在应用运行时显示为警报,这是我在代码中使用的appDelegate.swift:
import Firebase
import UserNotifications
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm_message_id"
var deviceID : String!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
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()
FirebaseApp.configure()
Fabric.sharedSDK().debug = true
return true
}
func showNotificationAlert(Title : String , Message : String, ButtonTitle : String ,window : UIWindow){
let alert = UIAlertController(title: Title, message: Message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: ButtonTitle, style: .cancel, handler: nil))
window.rootViewController?.present(alert, animated: true, completion: nil)
}
// [START receive_message] remote notification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// 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) {
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
}
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
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.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
if let aps = userInfo["aps"] as? NSDictionary {
if let alert = aps["alert"] as? NSDictionary {
if let title = alert["title"] as? NSString {
let body = alert["body"] as? NSString
showNotificationAlert(Title: title as String, Message: body! as String, ButtonTitle: "Ok", window: window!)
}
} else if let alert = aps["alert"] as? NSString {
print("mohsen 6 =\(alert)")
}
}
// Print full message.
print(userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
deviceID = 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.
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
// [END ios_10_data_message]
}
答案 1 :(得分:1)
如果您要使用 Postman 进行测试,请尝试将"content-available": true
更改为"content_available" : true
。 可用内容将发送通知,但不会调用didReceiveRemoteNotification
。
答案 2 :(得分:0)
您需要检查的第一件事是Background Mode > Remote Notification
已打开。否则,它将不会在后台模式下调用。
答案 3 :(得分:0)
步骤1 –添加框架
import UserNotifications
第2步 –使用AppDelegate
UNUserNotificationCenterDelegate
final class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {}
步骤3 –对registerPushNotifications
进行适当的更改,并将其命名为didFinishLaunchingWithOptions
private func registerPushNotifications() {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: { granted, error in
if granted {
UIApplication.sharedApplication().registerForRemoteNotifications()
} else {
// Unsuccessful...
}
})
} else {
let userNotificationTypes: UIUserNotificationType = [.Alert, .Badge, .Sound]
let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
步骤4 –实施新的处理程序
// leave this for older versions
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
}
// For iOS10 use these methods and pay attention how we can get userInfo
// Foreground push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler(.Badge)
}
// Background and closed push notifications handler
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
// Getting user info
}
completionHandler()
}
答案 4 :(得分:0)
您尝试过,我相信每件事,后台许可均已启用,内容可用是有效负载的一部分,您还收到处于活动状态的通知,最后一件将是int main (int argc, char **argv)
{
char buffer[100];
int num_chars = 0;
FILE *input;
input = fopen(argv[1], "rb");
FILE *output;
output = fopen(argv[2], "w");
if (input == NULL){
printf("ERROR: Input file needed!");
return -1;
}
if (output == NULL){
printf("ERROR: Output file needed!");
return -1;
}
for (int i = fgetc(input); i != EOF; i = fgetc(input)) {
if (isspace(i)){
printf("The magic number is: %c\n", i);
ungetc(i, input);
} else if (i == '#') {
for (int j = i; isspace(j); j = fgetc(input)){
buffer[num_chars++] = j;
printf("Comment found: %c\n", j);
ungetc(i, input);
}
}
}
return 0;
}
,您需要检查的是电源保存已关闭;就像您的手机处于省电模式一样,后台刷新和其他进程都处于受限状态,因此应用不会在后台调用Power save mode
。
答案 5 :(得分:0)
仅添加接受的答案:在我的情况下,问题是相同的,但是当我通过http "POST" NSMUtableRequest
发送通知时,应用接受的答案的方法是将其实际添加到通知参数中带有声音,徽章,瓷砖等。
let postParams: [String : Any] = [
"to": receiverToken,
"notification": [
"badge" : 1,
"body": body,
"title": title,
"subtitle": subtitle,
"sound" : true, // or specify audio name to play
"content_available": true, // this will call didReceiveRemoteNotification in receiving app, else won't work
"priority": "high"
],
"data" : [
"data": "ciao",
]
]
希望这对其他人也有帮助,因为我花了很长时间试图弄清楚如何应用此解决方案。 非常感谢。