带有UIBackgroundFetchResult的didReceiveRemoteNotification在IOS中不起作用

时间:2018-09-19 19:05:37

标签: ios objective-c firebase apple-push-notifications firebase-cloud-messaging

我正在尝试使用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

0 个答案:

没有答案