I followed OneSignal's set up guide, added an extension all named properly and have this file that they provided:
#import <OneSignal/OneSignal.h>
#import "NotificationService.h"
#interface NotificationService ()
#property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
#property (nonatomic, strong) UNNotificationRequest *receivedRequest;
#property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
#end
#implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.receivedRequest = request;
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
[OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
#end
Also copied all their code for AppDelegate as outlined in their setup guide here:
https://documentation.onesignal.com/docs/ios-sdk-setup plus some other code to create the 'center' variable as someone recommended on github. Adding this instance in AppDelegate did make it so that 'didReceiveRemoteNotification' gets called, but not didReceiveNotificationExtensionRequest.
#import "AppDelegate.h"
#interface AppDelegate ()
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#end
#import <OneSignal/OneSignal.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Replace '11111111-2222-3333-4444-0123456789ab' with your OneSignal App ID.
[OneSignal initWithLaunchOptions:launchOptions
appId:#"xxxxxxx (my app id is here)"
handleNotificationAction:nil
settings:#{kOSSettingsKeyAutoPrompt: #false}];
OneSignal.inFocusDisplayType = OSNotificationDisplayTypeNotification;
// Recommend moving the below line to prompt for push after informing the user about
// how your app will use them.
[OneSignal promptForPushNotificationsWithUserResponse:^(BOOL accepted) {
NSLog(#"User accepted notifications: %d", accepted);
}];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
// Call syncHashedEmail anywhere in your iOS app if you have the user's email.
// This improves the effectiveness of OneSignal's "best-time" notification scheduling feature.
// [OneSignal syncHashedEmail:userEmail];
return YES;
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void
(^)(UIBackgroundFetchResult))completionHandler
{
// iOS 10 will handle notifications through other methods
if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( #"10.0" ) )
{
NSLog( #"iOS version >= 10. Let NotificationCenter handle this one." );
// set a member variable to tell the new delegate that this is background
//this block here gets called when I debug
return;
}
NSLog( #"HANDLE PUSH, didReceiveRemoteNotification: %#", userInfo );
// custom code to handle notification content
if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
{
NSLog( #"INACTIVE" );
completionHandler( UIBackgroundFetchResultNewData );
}
else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
{
NSLog( #"BACKGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
else
{
NSLog( #"FOREGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
}
}
#end
I need 'didReceiveNotificationExtensionRequest' since I'm trying to use iOS 10's mutable content feature. I've put in breakpoints and am sure that didReceiveNotificationExtensionRequest is never called, I'm wondering if I need to hook up the class somewhere else because the .m file never does anything. Any help appreciated
If it matters my phone is running ios 10.0 (so should support the mutable content) and OneSignal version is (2.5.4)
Thanks
On iOS 10 didReceiveRemoteNotification method will not be called...you should go for
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
Related
i've the following situation.
2 identical react-native apps (differs only for bundleId, app icon etc) structured like this:
-> project structure
My goal it's to emit an event from native side to the JS layer through the bridge when a push notification has been received or tapped by the user (assuming that the app is in foreground and app has finished launching).
On the first App the following code works as expected when i trigger a push notification to my simulator with the command xcrun simctl push <device-id> <bundleId> <filename>.apns, the second app crash immediatly with the following error:
Thread 1: "Error when sending event: pushDelivered with body: <the string passed as body>. RCTCallableJSModules is not set. This is probably because you've explicitly synthesized the RCTCallableJSModules in CustomEventsEmitter, even though it's inherited from RCTEventEmitter."
-> xcode view
Here is the code implementation of RCTEventEmitter's sendEventWithName that provoke the assertion.
I don't know if it's a problem with my implementation. In 1 of the 2 apps works like a charm, in the other 💥.
Anyone can help me find the problem in the code ? Probably a problem with the bridge?
i've tried many times to reinstall pods, clean project and rebuild. The code works on the project A and not on the project B.. i cannot figure out the reason
AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridgeModule.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, RCTBridgeModule, UNUserNotificationCenterDelegate>
#property (nonatomic, strong) UIWindow *window;
#property (nonatomic, strong) NSDictionary *receivedNotificationUserInfo;
#end
AppDelegate.mm
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTAppSetupUtils.h>
#import <UserNotifications/UserNotifications.h>
#import "CustomEventsEmitter.h"
#implementation AppDelegate
bool hasFinishedLaunching = false;
CustomEventsEmitter *customEventsEmitter = NULL;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
hasFinishedLaunching = true;
customEventsEmitter = [CustomEventsEmitter allocWithZone: nil];
RCTAppSetupPrepareApp(application);
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"MyAppName", initProps);
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
-(void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
// The method will be called on the delegate when the user responded to the notification by opening
// the application, dismissing the notification or choosing a UNNotificationAction. The delegate
// must be set before the application returns from applicationDidFinishLaunching:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
NSLog(#"didReceiveNotificationResponse response: %#", response);
NSDictionary *userInfo = response.notification.request.content.userInfo;
if (userInfo[#"_od"]){
// if no listeners has been registered yet, store the value
// this is the case when the notification was clicked from closed app
if(![customEventsEmitter hasListeners]) {
// handle this case ...
}
// if listeners has been registered, emit an event
// this is the case when the notification was clicked from foreground app
else {
[self emitPushTappedEvent:userInfo[#"_od"]];
}
}
if (completionHandler != nil) {
completionHandler();
}
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo;
NSLog(#"User Info : %#", userInfo);
[self emitPushDeliveredEvent:userInfo[#"_od"]];
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
-(void)emitPushDeliveredEvent:(NSString*)value {
NSLog(#"emitPushDeliveredEvent called");
[customEventsEmitter sendEventWithName:#"pushDelivered" body:value];
}
-(void)emitPushTappedEvent:(NSString*)value {
NSLog(#"emitPushTappedEvent called");
[customEventsEmitter sendEventWithName:#"pushTapped" body:value];
}
#end
And this are the CustomEventsEmitter files:
CustomEventsEmitter.h
#ifndef CustomEventsEmitter_h
#define CustomEventsEmitter_h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#interface CustomEventsEmitter : RCTEventEmitter <RCTBridgeModule>
- (void)sendEventName:(NSString *)eventName body:(id)body;
- (bool)hasListeners;
#end
#endif
CustomEventsEmitter.m
#import "CustomEventsEmitter.h"
#implementation CustomEventsEmitter
{
bool hasListeners;
}
RCT_EXPORT_MODULE(CustomEventsEmitter);
+ (id)allocWithZone:(NSZone *)zone {
static CustomEventsEmitter *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
- (NSArray<NSString *> *)supportedEvents {
return #[#"pushDelivered", #"pushTapped"];
}
// Will be called when this module's first listener is added.
-(void)startObserving {
hasListeners = YES;
// Set up any upstream listeners or background tasks as necessary
}
// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
hasListeners = NO;
// Remove upstream listeners, stop unnecessary background tasks
}
-(bool)hasListeners {
return hasListeners;
}
- (void)sendEventName:(NSString *)eventName body:(id)body {
if (hasListeners) {
NSLog(#"CustomEventsEmitter sendEventName emitting event: %#", eventName);
[self sendEventWithName:eventName body:body];
} else {
NSLog(#"CustomEventsEmitter sendEventName called without listeners: %#", eventName);
}
}
#end
HELP ME UNDERSTAND PLEASEEEE
Oh i've solved it!
It was a mistake of mine.
The AppModule didn't invoke the CustomEventsEmitter's methods correctly..
changing the code like below makes the events be emitted correctly through the RN bridge
-(void)emitPushDeliveredEvent:(NSString*)value {
NSLog(#"emitPushDeliveredEvent called");
[customEventsEmitter sendEventName:#"pushDelivered" body:value];
//[customEventsEmitter sendEventWithName:#"pushDelivered" body:value];
}
-(void)emitPushTappedEvent:(NSString*)value {
NSLog(#"emitPushTappedEvent called");
[customEventsEmitter sendEventName:#"pushTapped" body:value];
//[customEventsEmitter sendEventWithName:#"pushTapped" body:value];
}
I tried to send push notifications to my iOS and Android physical devices through PinPoint campaigns. Android got it, but not iOS. In exported segment file I see that both my device id's included in segment, but when campaign is finished I see the next:
BTW, Test messaging works on both devices.
Both APNs is enabled:
I'm using React Native, there are hook where I configure Amplify:
export const useConfigureAmplifyNotifications = () => {
useEffect(() => {
Amplify.configure(awsconfig);
PushNotification.configure(awsconfig);
PushNotification.onRegister(token => {
console.log('in app registration: ', token);
PushNotification.updateEndpoint(token);
const endpointId = Analytics.getPluggable('AWSPinpoint')._config.endpointId;
console.log('ENDPOINT ID: ', endpointId);
});
// NativeModules.RNPushNotification.getToken(token => {
// console.log(`PushToken: ${token}`);
// });
PushNotification.onNotification(notification => {
console.log('in app notification', notification);
if (Platform.OS === 'ios') {
notification.finish(PushNotificationIOS.FetchResult.NoData);
}
});
if (Platform.OS === 'ios') {
PushNotification.requestIOSPermissions({
alert: true,
badge: true,
sound: false,
});
}
}, []);
};
My AppDelegate.h file:
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate,
UNUserNotificationCenterDelegate>
#property (nonatomic, strong) UIWindow *window;
#end
And AppDelegate.m part with notifications:
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
...
#implementation AppDelegate
// Required for the register event.
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after
handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:
(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo
fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
...
UNUserNotificationCenter *center = [UNUserNotificationCenter
currentNotificationCenter];
center.delegate = self;
return YES;
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void
(^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionSound |
UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
What I'm doing wrong?
#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
#import "MainViewController.h"
#interface AppDelegate () <UNUserNotificationCenterDelegate>
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.viewController = [[MainViewController alloc] init];
[self registerForNotification];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
// This method are not getting called
completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(nonnull UNNotificationResponse* )response withCompletionHandler:(nonnull void (^)(void))completionHandler {
// This method are not getting called
NSDictionary *userInfo = response.notification.request.content.userInfo;
completionHandler();
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"DEVICE_TOKEN :: %#", deviceToken);
const unsigned *tokenBytes = [deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:#"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSString *apnDeviceToken = hexToken;
NSLog(#"APN_DEVICE_TOKEN :: %#", apnDeviceToken);
}
-(void)registerForNotification
{
if(#available(iOS 10.0, *))
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if(!error)
{
dispatch_async(dispatch_get_main_queue(), ^ {
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog(#"Push registration success." );
});
}
else
{
NSLog(#"Push registration FAILED" );
NSLog(#"ERROR: %# - %#", error.localizedFailureReason, error.localizedDescription );
NSLog(#"SUGGESTIONS: %# - %#", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
}
#end
The didReceiveNotificationResponse and willPresentNotification did not trigger. I'm not able to handle Other APNS notification which is not related to one signal Cordova plugin SDK notification.
Is there any way that my app delegate methods for UserNotifications delegate methods will trigger in Cordova ios when one signal plugin used?
I suspect that due to swizzling the app delegate methods by one signal callbacks are not triggered in the original Appdelegate file.
Please help on this if we have any other way to get my app delegate
UserNotifications delegate methods trigger.
As one signal uses the static frameworks in Cordova there is no way to change the code inside the plugin.
This is the one signal plugin for Cordova github https://github.com/OneSignal/OneSignal-Cordova-SDK
FCM notifications not working in background - delegate methods also not being called.
I know this is a repeated question. I have gone through all the solutions but no luck.
The delegate method is not being called when the app is in background and when application come from background to foreground then all the earlier notifications are getting delivered.
I have set the priority = high and "content_available" = 1 and tried too.
Here is my code:
#import Firebase;
#import FirebaseInstanceID;
#import FirebaseMessaging;
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
#import UserNotifications;
#endif
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
#interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegate>
#end
#endif
#ifndef NSFoundationVersionNumber_iOS_9_x_Max
#define NSFoundationVersionNumber_iOS_9_x_Max 1299
#endif
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
#implementation AppDelegate
NSString *const kGCMMessageIDKey = #"gcm.message_id";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[NSThread sleepForTimeInterval:3.0];
self.defaults = [NSUserDefaults standardUserDefaults];
//[self.defaults setObject:#"1" forKey:#"remember"];
[FIRApp configure];
self.selectedIndexArray = [[NSMutableArray alloc]init];
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
UIRemoteNotificationType allNotificationTypes =
(UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge);
[application registerForRemoteNotificationTypes:allNotificationTypes];
#pragma clang diagnostic pop
} else {
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 {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions =
UNAuthorizationOptionAlert
| UNAuthorizationOptionSound
| UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
}];
[FIRMessaging messaging].remoteMessageDelegate = self;
#endif
}
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(tokenRefreshNotification:)
name:kFIRInstanceIDTokenRefreshNotification object:nil];
return YES;
}
- (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
// [[Messaging messaging] appDidReceiveMessage:userInfo];
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(#"%#", userInfo);}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UILocalNotification *not = [UILocalNotification new];
[not setAlertTitle:#"Title"];
[not setAlertBody:#"Body"];
[[UIApplication sharedApplication]presentLocalNotificationNow:not];
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// 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
// [[Messaging messaging] appDidReceiveMessage:userInfo];
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(#"%#", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)messaging:(FIRMessaging *)messaging didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage {
NSLog(#"Received data message: %#", remoteMessage.appData);
}
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
- (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
// [[Messaging messaging] appDidReceiveMessage:userInfo];
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(#"%#", userInfo);
// Change this to your preferred presentation option
completionHandler(UNNotificationPresentationOptionNone);
}
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set [Messaging messaging].shouldEstablishDirectChannel to YES.
#endif
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
NSLog(#"remoteMessage 1234 :%#",remoteMessage.appData);
NSString *notResStr = remoteMessage.appData[#"data"];
self.notificationArray = [notResStr componentsSeparatedByString:#","];
UILocalNotification *not = [UILocalNotification new];
NSLog(#"self.notificationArray :%#",self.notificationArray);
for (int i =0 ; i<self.notificationArray.count; i++) {
if([(NSString *) [self.notificationArray objectAtIndex:i] containsString:#"\"title\""]){
NSString *title = [self.notificationArray objectAtIndex:i];
NSArray *arr = [title componentsSeparatedByString:#":"];
[not setAlertTitle:[arr objectAtIndex:1]];
}
if([(NSString *) [self.notificationArray objectAtIndex:i] containsString:#"\"message\""]){
NSString *title = [self.notificationArray objectAtIndex:i];
NSArray *arr = [title componentsSeparatedByString:#":"];
[not setAlertBody:[arr objectAtIndex:1]];
}
}
[[UIApplication sharedApplication]presentLocalNotificationNow:not];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
// Print full message.
NSLog(#"%#", userInfo);
NSLog(#"%#", response);
completionHandler();
}
#endif
- (void)tokenRefreshNotification:(NSNotification *)notification {
NSString *refreshedToken = [[FIRInstanceID instanceID] token];
[self.defaults setObject:refreshedToken forKey:#"deviceToken"];
[self connectToFcm];
}
- (void)connectToFcm {
if (![[FIRInstanceID instanceID] token]) {
return;
}
[self.defaults setObject:[[FIRInstanceID instanceID] token] forKey:#"deviceToken"];
[[FIRMessaging messaging] disconnect];
NSLog(#"fcm back");
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
if (error != nil) {
} else {
}
}];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Unable to register for remote notifications: %#", error);
}
- (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken {
// 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.
NSLog(#"FCM registration token: %#", fcmToken);
// TODO: If necessary send token to application server.
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// for development
NSLog(#"didRegisterForRemoteNotificationsWithDeviceToken");
[[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
// for production
// [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeProd];
NSLog(#"APNs device token retrieved: %#", deviceToken);
// With swizzling disabled you must set the APNs device token here.
// [Messaging messaging].APNSToken = deviceToken;
}
#pragma mark Shared Instance
+ (AppDelegate*) sharedInstance{
return (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[FIRMessaging messaging] disconnect];
NSLog(#"app is in background");
// [self connectToFcm];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self connectToFcm];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[self.defaults synchronize];
}
#end
receiving payload response like this
{data = "{\"Nick\":\"Mario\",\"Room\":\"PortugalVSDenmark\"}";
from = 608855029366;notification = "{\"body\":\"Test Body\",\"title\":\"Test Title\"}";to = "my fcm ID";priority : "high";content-available : "1";}
even notification string is there in payload the delegate method is not calling when the app is in background.
How to show local notification always, even in foreground, using new (from iOS 10) notification framework UserNotifications https://developer.apple.com/reference/usernotifications?language=objc ?
#import <UserNotifications/UserNotifications.h>
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
//interface
#interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
#end
//implementation
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self registerForRemoteNotifications];
return YES;
}
- (void)registerForRemoteNotifications {
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(#"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}
else {
// Code for old versions
}
}
////...........Handling delegate methods for UserNotifications........
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(#"User Info : %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(#"User Info : %#",response.notification.request.content.userInfo);
completionHandler();
}
May this will help you. :)
You can do this way.
//in Appdelegate
-(void)application:(UIApplication *)application didReceiveLocalNotification(UILocalNotification *)notification
{
dispatch_async(dispatch_get_main_queue(),^{
NSLog(#"alertbody ..%#", notification.alertBody);
NSLog(#"title ..%#", notification.alertTitle);
NSLog(#"action ..%#", notification.alertAction);
NSLog(#"userinfo..%#", notification.userInfo);
[[NSNotificationCenter defaultCenter]postNotificationName:#"NotificationReceived" object:nil userInfo:notification.userInfo];
});
}
//in present view controller
-(void)viewDidLoad
{
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(notificationReceivedMethod:) name:#"NotificationReceived" object:nil];
}
-(void) viewWillDisappear:(BOOL)animated {
{
[[NSNotificationCenter defaultCenter]removeObserver:self name:#"NotificationReceived" object:nil];
}
-(void)notificationReceivedMethod
{
//create you custom popup or view
}