Firebase 消息传递方法 swizzling 不起作用
Posted
技术标签:
【中文标题】Firebase 消息传递方法 swizzling 不起作用【英文标题】:Firebase messaging method swizzling not working 【发布时间】:2016-12-01 03:03:22 【问题描述】:您好,我正在实施 FCM(Fire base 云消息传递)。我已经让应用程序从 FCM 控制台接收通知和数据。我有我的服务器通知和 Firebase 通知。我想分别处理两种类型的通知(来自我的服务器和来自 FCM)。我已经浏览了文档,这可以通过在 AppDelegate 中调整通知处理程序来实现
但问题是我只能在
中获取FCM消息数据(ios 10)-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
和
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
FCM 委托的回调
// The callback to handle data message received via FCM for devices running iOS 10 or above.
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage
// Print full message
NSLog(@"Can get here firebase?%@", [remoteMessage appData]);
上面的回调永远不会被调用
我们如何使用 swizzling 单独设置 FCM 处理程序消息?
这是我的 Appdelegate didfinishlaunchingwith 选项
application.applicationIconBadgeNumber = 0;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max)
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
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] setDelegate:self];
// For iOS 10 data message (sent via FCM)
[[FIRMessaging messaging] setRemoteMessageDelegate:self];
#endif
[[UIApplication sharedApplication] registerForRemoteNotifications];
// [START configure_firebase]
[FIRApp configure];
// [END configure_firebase]
// Add observer for InstanceID token refresh callback.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshNotification:)
name:kFIRInstanceIDTokenRefreshNotification object:nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
_rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
[self.window setRootViewController:_rootViewController];
[self.window makeKeyAndVisible];
NSDictionary *remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification)
[self handleRemoteNotification:remoteNotification shouldPrompt:NO];
self.isFirstTime = true;
self.isJustForRefresh = 0;
return YES;
有人知道如何让它工作吗?
编辑:这是我的观察者观察函数和didregisterRemoteNotification函数
// [START refresh_token]
- (void)tokenRefreshNotification:(NSNotification *)notification
// Note that this callback will be fired everytime a new token is generated, including the first
// time. So if you need to retrieve the token as soon as it is available this is where that
// should be done.
NSString *refreshedToken = [[FIRInstanceID instanceID] token];
NSLog(@"InstanceID token: %@", refreshedToken);
// Connect to FCM since connection may have failed when attempted before having a token.
[self connectToFcm];
// TODO: If necessary send token to application server.
// [END refresh_token]
// [START connect_to_fcm]
- (void)connectToFcm
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error)
if (error != nil)
NSLog(@"Unable to connect to FCM. %@", error);
else
NSLog(@"Connected to FCM.");
];
// [END connect_to_fcm]
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
NSString *sanitizedDeviceToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:@"<" withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString:@" " withString:@""];
DLog(@"sanitized device token: %@", sanitizedDeviceToken);
[PushNotificationManager API_registerAPNSToken:sanitizedDeviceToken
onCompletion:^(BOOL success, NSError *error)];
[[FIRInstanceID instanceID]setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
更新:我已包含此功能但仍无法正常工作
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
if (userInfo[@"gcm.message_id"] != nil)
NSLog(@"Should get here FCM?");
[[FIRMessaging messaging]appDidReceiveMessage:userInfo];
else
NSLog(@"test fetchCompletion handler: %@",userInfo.description);
【问题讨论】:
你不应该使用 swizzling github.com/onmyway133/blog/issues/64 【参考方案1】:你可以看看这个答案吗?好像漏了FIRMessaging.messaging().connect()....
https://***.com/a/40881754/1005570
还有委托函数..
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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print(userInfo)
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
【讨论】:
对不起,代码很快。但我认为你可以得到它。 您好,更新我已经连接到 FCM 的代码,可以收到通知,但我的问题是使用 swizzling 方法?分别处理 FCM 通知和我自己的服务器通知(现在一切都按照意愿呈现和接收) 和测试IOS 10 哦,我明白你的意思了。那么用你上面实现的代码,你能从你自己的服务器收到任何通知吗?所以您遇到的问题是 1. 从两个来源收到通知但无法将它们分开。或者 2. 只收到来自 FCM 的通知,而不是您自己的服务器。 嗨谢谢我的问题是第一个。我可以收到通知,但无法将它们分开,并且永远不会调用 FCM 委托函数以上是关于Firebase 消息传递方法 swizzling 不起作用的主要内容,如果未能解决你的问题,请参考以下文章