OneSignal 不调用 didReceiveRemoteNotification

OneSignal Not calling didReceiveRemoteNotification

我们从 UA 迁移到 One Signal。我们正在从

等云代码发送推送
var pushInfo = {
      "app_id" : "xxxxxx",          
      "data": {
          "objectId": objectId,
          "placeId": placeId,
      },
      "included_segments": ["All Users"],
      "contents": {"en": message}
};
var headers = {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Basic XXXXX"
};

var options = {
 host: "onesignal.com",
 port: 443,
 path: "/api/v1/notifications",
 method: "POST",
 headers: headers,
};

var https = require('https');
var req = https.request(options, function(res) {  
res.on('data', function(data) {
  console.log("Response:");
  console.log(JSON.parse(data));
});
});

req.on('error', function(e) {
console.log("ERROR:");
console.log(e);
 });  
req.write(JSON.stringify(pushInfo));
req.end();

在我的 AppDelegate.m 我做

[OneSignal initWithLaunchOptions:launchOptions appId:@"XXXXX"];

现在早些时候,当收到通知并且用户点击它时,它曾经调用

-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

问。现在不会调用它。我如何使用 OneSignal 处理它。 问:我需要做什么来处理静默通知(不可见 badge/banner 等)

application:didReceiveRemoteNotification:fetchCompletionHandler: is the correct selector for background silent content-available notifications. Make sure you are using the latest 2.2.2 OneSignal SDK 因为有一些修复来保持与旧 AppDelegate 选择器的兼容性。

您可能需要考虑将 UNNotificationServiceExtensionmutable-content 一起用于 iOS 10 台设备,因为当应用程序被刷掉后这仍然有效。

我假设您 testing/running 您的应用程序在 iOS10 设备上,

我查看了 OneSignal SDK 代码,我认为当在设备上检测到 iOS10 时,SDK 会自动使用新的 UserNotifications 框架(添加 iOS10)。

在这种情况下,您上面提到的 AppDelegate 方法不会被调用,而是 UNUserNotificationCenterDelegate 中的方法被调用,这些方法被 SDK 捕获以记录 clicks/views.

要解决此问题,请创建一个新的 class 实现 OSUserNotificationCenterDelegate 并使用 [OneSignal setNotificationCenterDelegate:yourCustomNotificationCenterDelegateInstance]

将其实例提供给 OneSignal

请注意,当静默推送通知(内容可用:1)到达时,application:didReceiveRemoteNotification:fetchCompletionHandler: 仍会被调用,但如果使用 UNUserNotificationCenterDelegate,则当用户点击通知时不会被调用。

此外,iOS 10.0.X 上有一个问题,其中调用了 application:didReceiveRemoteNotification 而不是 application:didReceiveRemoteNotification:fetchCompletionHandler: 请参阅:https://forums.developer.apple.com/thread/54332,但我怀疑你是不是这样。

一个信号通知集成

使用以下代码块处理 PushNotification 消息内容

在 AppDelegate 的 ApplicationDidFinishLaunch 选项方法中放入以下代码

    let notificationReceivedBlock: OSHandleNotificationReceivedBlock = { notification in

        print("Received Notification: \(notification!.payload.notificationID)")
    }

    let notificationOpenedBlock: OSHandleNotificationActionBlock = { result in
        // This block gets called when the user reacts to a notification received
        let payload: OSNotificationPayload = result!.notification.payload

        var fullMessage = payload.body
        print("Message = \(String(describing: fullMessage))")

        if payload.additionalData != nil {
            if payload.title != nil {
                let messageTitle = payload.title
                print("payload.category \(payload.category)")
                print("payload.subtitle \(payload.subtitle)")
                print("Message Title = \(messageTitle!)")
            }

            let additionalData = payload.additionalData
            if additionalData?["actionSelected"] != nil {
                fullMessage = fullMessage! + "\nPressed ButtonID: \(String(describing: additionalData!["actionSelected"]))"
            }
        }
    }

    let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false,
                                 kOSSettingsKeyInAppLaunchURL: true]

    OneSignal.initWithLaunchOptions(launchOptions,
                                    appId: "Your App Id",
                                    handleNotificationReceived: notificationReceivedBlock,
                                    handleNotificationAction: notificationOpenedBlock,
                                    settings: onesignalInitSettings)
   **Use following block of code To Receive OneSingnal Notification Content** 

    OneSignal.inFocusDisplayType = OSNotificationDisplayType.notification;

    // Recommend moving the below line to prompt for push after informing the user about
    //   how your app will use them.
    OneSignal.promptForPushNotifications(userResponse: { accepted in
        print("User accepted notifications: \(accepted)")
    })

在我的例子中,我所要做的就是删除应用委托中的 Firebase 处理程序。 OneSignal 可以劫持来自 FCM 的事件。通过这种方式,我同时获得了 OneSingal 推送通知和 Firebase 发送的通知。至于一个信号,我使用了他们示例中的简单复制和粘贴。

这是我从 AppDelegate.m

中删除的部分
REMOVE IMPORTS -> #import "RNFirebaseMessaging.h"
REMOVE IMPORTS -> #import "RNFirebaseNotifications.h"

IN: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
REMOVE ->[RNFirebaseNotifications configure];

REMOVE HANDLERS:
- (void)application:(UIApplication *)application 
didReceiveLocalNotification:(UILocalNotification *)notification {
  [[RNFirebaseNotifications instance] 
didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application 
didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
                                                   
fetchCompletionHandler:(nonnull void (^). 
(UIBackgroundFetchResult))completionHandler{
  [[RNFirebaseNotifications instance] 
didReceiveRemoteNotification:userInfo 
fetchCompletionHandler:completionHandler];
  [UIApplication sharedApplication].applicationIconBadgeNumber += 1;
}

- (void)application:(UIApplication *)application 
didRegisterUserNotificationSettings:(UIUserNotificationSettings 
*)notificationSettings {
  [[RNFirebaseMessaging instance] 
didRegisterUserNotificationSettings:notificationSettings];
}

import { Platform } from 'react-native'
import OneSignal, { NotificationReceivedEvent, OpenedEvent } from 'react-native-onesignal'
import Config from '../../Config/Config'
import State from '../../State/State'

interface WithSuccess {
    success: boolean
}

interface ExternalUserIdResultI {
    push: WithSuccess
    email: WithSuccess
    sms: WithSuccess
}

class Messaging {

    public Init = () => {
        //OneSignal Init Code
        OneSignal.setLogLevel(Config.messaging.debugLevel, 0)
        OneSignal.setAppId(Platform.OS === 'ios' ? Config.messaging.iosAppId : Config.messaging.androidAppId)
        //END OneSignal Init Code

        //Prompt for push on iOS
        OneSignal.promptForPushNotificationsWithUserResponse((response: boolean) => {
            console.log("Prompt response:", response);
        })

        //Method for handling notifications received while app in foreground
        OneSignal.setNotificationWillShowInForegroundHandler((notificationReceivedEvent: NotificationReceivedEvent) => {
            console.log("OneSignal: notification will show in foreground:", notificationReceivedEvent);
            let notification = notificationReceivedEvent.getNotification();
            console.log("notification: ", notification);
            notificationReceivedEvent.complete(notification)
        })

        //Method for handling notifications opened
        OneSignal.setNotificationOpenedHandler((notification: OpenedEvent) => {
            console.log("OneSignal: notification opened:", notification);
        })

        OneSignal.addSubscriptionObserver(event => {
            console.log("OneSignal: subscription changed:", event);
        })
    }

    public SendTag = (key: string, value: string) => {
        OneSignal.sendTag(key, value)
    }

    public SetExternalUserId = (externalUserId: string) => {
        //@ts-ignore
        OneSignal.setExternalUserId(externalUserId, (results: ExternalUserIdResultI) => {
            // The results will contain push and email success statuses
            console.log('Results of setting external user id');
            console.log(results);
            
            // Push can be expected in almost every situation with a success status, but
            // as a pre-caution its good to verify it exists
            if (results.push && results.push.success) {
              console.log('Results of setting external user id push status:');
              console.log(results.push.success);
            }
            
            // Verify the email is set or check that the results have an email success status
            if (results.email && results.email.success) {
              console.log('Results of setting external user id email status:');
              console.log(results.email.success);
            }
          
            // Verify the number is set or check that the results have an sms success status
            if (results.sms && results.sms.success) {
              console.log('Results of setting external user id sms status:');
              console.log(results.sms.success);
            }
          });
    }

    public RemoveExternalUserId = () => {
        //@ts-ignore
        OneSignal.removeExternalUserId((results: ExternalUserIdResultI) => {
            // The results will contain push and email success statuses
            console.log('Results of removing external user id');
            console.log(results);
            // Push can be expected in almost every situation with a success status, but
            // as a pre-caution its good to verify it exists
            if (results.push && results.push.success) {
              console.log('Results of removing external user id push status:');
              console.log(results.push.success);
            }
            
            // Verify the email is set or check that the results have an email success status
            if (results.email && results.email.success) {
              console.log('Results of removoing external user id email status:');
              console.log(results.email.success);
            }
          });
    }

}

export default new Messaging()