我正在尝试使用content_available: true
在IOS中实现FCM通知。这样,当新通知到达时,IOS会通知我的应用程序,而无需在通知托盘中添加该通知,因此我可以进行后台获取,然后在我的应用程序准备好内容时显示本地通知。
我能够用FCM实现一个示例应用程序,该应用程序可以按照我前面提到的要求工作。当我尝试将工作代码与应用程序集成时,我不再通过content_available: true
接收数据通知触发器。但是,没有content_available: true
的常规通知实现(新通知到达时不会通知用户和App的新通知)正在正常工作。
我唯一看到的区别是Firebase启动代码的触发方式不同,如下所示。
在工作项目中,通过 AppDelegate
初始化Firebase@interface AppDelegate () <UNUserNotificationCenterDelegate>
@end
@implementation AppDelegate
NSString *const kGCMMessageIDKey = @"gcm.message_id";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self initFirebase];
return YES;
}
在不起作用的项目中,当用户单击按钮时,我正在从 ViewController 初始化firebase。
#import "LoginPageViewController.h"
@import UserNotifications;
@interface LoginPageViewController () <UNUserNotificationCenterDelegate>
@end
@implementation LoginPageViewController
NSString *const kGCMMessageIDKey = @"gcm.message_id";
- (void)initFirebase{
[FIRApp configure];
.
.
.
}
这两个应用程序之间的所有其他方法都相同,并且所有触发器均正常工作,以下是处理FCM数据通知的方法,每当我发送FCM通知时,此方法就会在工作项目中被调用,但从未在其他项目中被调用。
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
printf("#B received notification!");
//NSLog(@"#B received notification");
//handle the notification here
}
有人成功实现了在AppDelegate类之外对其进行初始化的FCM集成吗? 在这种情况下,我如何确保didReceiveRemoteNotification被调用?任何指针将不胜感激。
如果有帮助,则下面是完整的LoginViewController.m。
//
// LoginPageViewController.m
// ios
//
// Created by user on 9/12/18.
// Copyright © 2018 binfer. All rights reserved.
//
#import "LoginPageViewController.h"
@import UserNotifications;
@interface LoginPageViewController () <UNUserNotificationCenterDelegate>
@end
@implementation LoginPageViewController
NSString *const kGCMMessageIDKey = @"gcm.message_id";
- (void)initFirebase{
[FIRApp configure];
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
printf("#B IOS 9");
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
// iOS 10 or later
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
printf("#B IOS 10+");
UNAuthorizationOptions authOptions =
UNAuthorizationOptionAlert
| UNAuthorizationOptionSound
| UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
}];
// For iOS 10 display notification (sent via APNS)
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
// For iOS 10 data message (sent via FCM)
[FIRMessaging messaging].delegate = self;
#endif
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
NSLog(@"#B fir token is %@",[[FIRInstanceID instanceID] token]);
printf("#B FCM token received: %s", [[[FIRInstanceID instanceID] token] UTF8String]);
}
- (void)initFirebase1{
//[START configure_firebase]
[FIRApp configure];
// [END configure_firebase]
// [START set_messaging_delegate]
[FIRMessaging messaging].delegate = self;
// [END set_messaging_delegate]
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
if ([UNUserNotificationCenter class] != nil) {
// iOS 10 or later
// For iOS 10 display notification (sent via APNS)
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// ...
}];
} else {
// iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
// [END register_for_notifications]
NSString *token = FIRMessaging.messaging.FCMToken;
printf("#B initFirebase done! %s,", [token UTF8String]);
}
// [START refresh_token]
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
printf("#B FCM token received: %s", [fcmToken UTF8String]);
NSLog(@"FCM registration token: %@", fcmToken);
// Notify about received token.
NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
[[NSNotificationCenter defaultCenter] postNotificationName:
@"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.
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
printf("#B Unable to register for remote notificaiton");
NSLog(@"#B Unable to register for remote notifications: %@", error);
}
// 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 device token can be paired to
// the FCM registration token.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"APNs device token retrieved: %@", deviceToken);
printf("#B APNs device token retrieved");
// With swizzling disabled you must set the APNs device token here.
// [FIRMessaging messaging].APNSToken = deviceToken;
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
// With swizzling disabled you must let Messaging know about the message, for Analytics
// [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
printf("#B Message recieved: %s,", [kGCMMessageIDKey UTF8String]);
NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(@"%@", userInfo);
printf("#B full Message recieved");
// Change this to your preferred presentation option
completionHandler(UNNotificationPresentationOptionNone);
}
// Handle notification messages after display notification is tapped by the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
if (userInfo[kGCMMessageIDKey]) {
printf("#B Message recieved: %s,", [kGCMMessageIDKey UTF8String]);
NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(@"%@", userInfo);
completionHandler();
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
printf("#B received notification!");
//NSLog(@"#B received notification");
//handle the notification here
}
- (void)messaging:(FIRMessaging *)messaging didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage {
printf("Recieved data message:");
NSLog(@"Received data message: %@", remoteMessage.appData);
}
// [START receive_message]
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// 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
// [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(@"%@", userInfo);
}
//////////////////////////////////////////////////////////////////////
- (IBAction)registrationClicked:(UIButton *)sender {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)loginButton:(UIButton *)sender {
}
- (IBAction)keepMeSignedInSwitch:(UISwitch *)sender {
}
@end