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 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
iOS面试粮食Runtime—消息传递和转发机制Method Swizzling
使用 Firebase 云消息传递 (FCM) 时未调用 AppDelegate 方法
Firebase 云消息传递的 getToken() 仅在我省略 usePublicVapidKey 方法时才有效,为啥?