I have an iOS app with Firebase messaging added. The problem is the firebase push notifications only appear if the app is terminated or in the background. I'd like to be able to handle the message programmatically and display some kind of modal, but the didReceiveRemoteNotification method isn't even being called.
Here is my AppDelegate.m
#import "AppDelegate.h"
#import "MainViewController.h"
#import "AppName-Swift.h"
#import Firebase;
#import FirebaseMessaging;
#import FirebaseInstanceID;
#implementation AppDelegate {
LocationSyncManager* locationSyncManager;
bool isLocationLaunch;
}
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
isLocationLaunch = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
[self enablePushNotifications:application];
if(isLocationLaunch) {
if(AccountStore.shared.account != nil) {
locationSyncManager = [LocationSyncManager shared];
[locationSyncManager enable];
}
} else {
self.viewController = [[MainViewController alloc] init];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
return nil;
}
- (void) enablePushNotifications:(UIApplication*)application {
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
- (void)messaging:(nonnull FIRMessaging *)messaging didReceiveRegistrationToken:(nonnull NSString *)fcmToken {
[LocationSyncManager shared].deviceToken = fcmToken;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[FIRMessaging messaging].APNSToken = deviceToken;
[FIRMessaging messaging].shouldEstablishDirectChannel = YES;
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"--- didFailToRegisterForRemoteNotificationsWithError %#", error);
}
// In case the user tries to open the app while it is running in the background,
// allow the webview to initialize and disable the isLocationLaunch flag.
- (void)applicationWillEnterForeground:(UIApplication *)application {
if(isLocationLaunch) {
self.viewController = [[MainViewController alloc] init];
[self application:application didFinishLaunchingWithOptions:nil];
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"---- RECEIVED REMOVE NOTIFICATION %#", userInfo);
}
#end
I should be seeing ---- RECEIVED REMOVE NOTIFICATION in the logs after the server sends a PN, but it's not happening. Why isn't didReceiveRemoteNotification called in the foreground?
Related
I've configured for notification in iOS.
Generated certificate request locally and added apn to developer account.
Added the certificate to keychain access.
Configured and connected my firebase account in iOS using the package manager.
Added the Google-info.plist.
Did i miss any step in configuration. Also i followed the steps in react-native-firebase documentation for configuring for Cloud Messaging.
I've already followed the steps to configured the apn and firebase. including a step which has been missed by the rn-firebase documentation.
componentDidMount() {
this.messageListener = firebase.messaging().onMessage(message => {
// Process your message as required
Alert.alert('Notification',JSON.stringify(message))
console.info("Messaging ", message);
});
firebase.messaging().hasPermission().then(enabled => {
enabled ?
firebase.messaging().subscribeToTopic("testopic") :
firebase.messaging().requestPermission().then(enabledNow => {
enabledNow ?
firebase.messaging().subscribeToTopic("testopic") : '';
}).catch(err => {
Alert.alert('Notification', 'Enable notification to recieve attractive updates!')
});
})
// Background Notification handler
firebase.notifications().getInitialNotification()
.then((notificationOpen) => {
if (notificationOpen) {
// App was opened by a notification
// Get the action triggered by the notification being opened
const action = notificationOpen.action;
// Get information about the notification that was opened
const notification = notificationOpen.notification;
}
});
this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed((notification) => {
// Process your notification as required
// ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
});
this.notificationListener = firebase.notifications().onNotification((notification) => {
// Process your notification as required
Alert.alert('Notification',JSON.stringify(notification))
});
this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
// Get the action triggered by the notification being opened
const action = notificationOpen.action;
// Get information about the notification that was opened
const notification = notificationOpen.notification;
});
}
componentWillUnmount() {
this.notificationDisplayedListener();
this.notificationListener();
this.notificationOpenedListener();
}
Appdelegate.m File
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <RNGoogleSignin/RNGoogleSignin.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <UserNotifications/UserNotifications.h>
#import <Firebase.h>
#import "RNFirebaseMessaging.h"
#import "RNFirebaseNotifications.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
[RNFirebaseNotifications configure];
NSURL *jsCodeLocation;
#ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
jsCodeLocation = [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"customerapp"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
// Setup 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;
[FIRMessaging messaging].delegate = self;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) { NSLog(#"%#", 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];
[application registerUserNotificationSettings:settings];
}
[application registerForRemoteNotifications];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
// return YES;
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
}
// URL Scheme responder
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]
|| [RNGoogleSignin application:application openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}
#end
I have a problem which I've been unable to resolve. My knowledge of iOS/Xcode is limited, please forgive me.
I am trying to subscribe to an FCM topic for an iOS app using xcode/Objective C but when loading the App, it is not subscribing to the topic, in the debugger it doesn't even look like it is trying.
If I move the [[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
line to just below
[FIRMessaging messaging].delegate = self;
[application registerForRemoteNotifications];
[FIRApp configure];
(and above return YES;) then at least I get this error message indicating that it is at least trying.
2018-01-04 04:00:18.723760+0000 App[1049:1251125] [Firebase/Messaging][I-FCM002010] Cannot subscribe to topic: /topics/channel with token: (null)
So following the suggestion here (and a number of other places), I have tried to move it out into didRegisterUserNotificationSettings but it doesn't seem to be doing anything at all and there is no trace of it in the debugger.
This is my full AppDelegate.m code
//
// AppDelegate.m
//
#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
#import <Firebase/Firebase.h>
#import <FirebaseMessaging/FirebaseMessaging.h>
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#import <AFNetworking/AFNetworking.h>
#import Firebase;
#interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegate>
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setupNetworkReachability];
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error)
{
}];
[FIRMessaging messaging].delegate = self;
[application registerForRemoteNotifications];
[FIRApp configure];
//[[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UNNotificationSettings *)notificationSettings
{
[[FIRMessaging messaging] subscribeToTopic:#"/topics/channel"];
NSLog(#"Topic Registered");
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
#pragma mark - Public Methods
+ (AppDelegate *)sharedAppDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void)setupNetworkReachability
{
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
if (status == AFNetworkReachabilityStatusReachableViaWiFi || status == AFNetworkReachabilityStatusReachableViaWWAN)
self.isNetworkAvailable = YES;
else
self.isNetworkAvailable = NO;
NSLog(#"Reachability: %#", AFStringFromNetworkReachabilityStatus(status));
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
#pragma mark - FIRMessagingDelegate Methods
- (void)messaging:(nonnull FIRMessaging *)messaging didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage
{
NSLog(#"%#", remoteMessage.appData);
}
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage
{
NSLog(#"%#", remoteMessage.appData);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSLog(#"%#", notification.request.content.userInfo);
completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
}
#end
Would appreciate any help. Thank you.
Just to update, the App already receives message directly from FCM console, so that part works OK, it is just the topic subscription that is failing.
1: You should call [FIRApp configure]; before [FIRMessaging messaging].delegate = self;
2: As you post full code of your AppDelegate.m file. So it is missing the below method to update/send token to Firebase. You will receive a TOKEN with in this UIApplication's delegate method and you have to set it for Firebase (Just put this method in your AppDelegate.m file)
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString *strDevicetoken = [[NSString alloc]initWithFormat:#"%#",[[[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]] stringByReplacingOccurrencesOfString:#" " withString:#""]];
NSLog(#"Device Token = %#",strDevicetoken);
[FIRMessaging messaging].APNSToken = deviceToken;
//NSString *fcmToken = [FIRMessaging messaging].FCMToken;
//NSLog(#"FCM registration token: %#", fcmToken);
}
Now you have successfully set APNS Token at Firebase and you can now subscribe to your desired topic at Firebase
I am trying to implement App-to-App calling with Sinch in my IOS app. I have implemented Pushkit in my iOS app with Sinch but the push notification is not working when the app is in background.
I have two questions.
Do I need another web service to send push notification to my app for incoming app separately or Sinch handles it itself.
If it does handle itself then what am I missing in my code.
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[self handleLocalNotification:[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
[self.push registerUserNotificationSettings];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (id<SINClient>)client {
return _sinchClient;
}
-(void)clientDidFail:(id<SINClient>)client error:(NSError *)error{
NSLog(#"fail");
}
-(void)clientDidStart:(id<SINClient>)client{
NSLog(#"Start");
[self voipRegistration];
}
- (void)client:(id<SINClient>)client
logMessage:(NSString *)message
area:(NSString *)area
severity:(SINLogSeverity)severity
timestamp:(NSDate *)timestamp {
// If you want all messages remove the if statement
if (severity == SINLogSeverityCritical) {
NSLog(#"%#", message);
}
}
- (void)initSinchClientWithUserId:(NSString *)userId {
if (!_sinchClient) {
_sinchClient = [Sinch clientWithApplicationKey:#"<my-key>"
applicationSecret:#"<my-secret>"
environmentHost:#"sandbox.sinch.com"
userId:userId];
_sinchClient.delegate = self;
[_sinchClient setSupportCalling:YES];
[_sinchClient startListeningOnActiveConnection];
[_sinchClient enableManagedPushNotifications];
[_sinchClient start];
}
}
- (void)handleLocalNotification:(UILocalNotification *)notification {
if (notification) {
id<SINNotificationResult> result = [self.sinchClient relayLocalNotification:notification];
if ([result isCall] && [[result callResult] isTimedOut]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Missed call"
message:[NSString stringWithFormat:#"Missed call from %#", [[result callResult] remoteUserId]]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alert show];
}
}
}
-(void)voipRegistration
{
PKPushRegistry* voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[_sinchClient registerPushNotificationData:credentials.token];
}
-(void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type{
NSLog(#"invalidated");
}
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType: (NSString *)type
{
//notify
NSDictionary* dic = payload.dictionaryPayload;
NSString* sinchinfo = [dic objectForKey:#"sin"];
UILocalNotification* notif = [[UILocalNotification alloc] init];
notif.alertBody = #"incoming call";
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
if (sinchinfo == nil)
return;
dispatch_async(dispatch_get_main_queue(), ^{
[_sinchClient relayRemotePushNotificationPayload:sinchinfo];
});
}
If you integrated Pushkit and Sinch then push notification may can't catch on PushKit's delegate function - didReceiveIncomingPushWithPayload. But you can get push notification on SINManagedPushDelegate's function - didReceiveIncomingPushWithPayload.
Push notification is not coming but you can get incoming call event on there when app is in background. You can trigger local notification if app is in background to let user incoming call know.
Hope that would be helpful for you.
My app is live in iTunes Connect. To give support of iOS 10 I am using same certificate and provisioning that I was using in the last version. Currently, my XCode version is 8.1 (8B62). I am receiving remote notifications in development. But when I am testing the app in TestFlight, I am not receiving any remote notification. But It was working fine up to iOS 9 with XCode 7.
Here is my AppDelegate.h
#import <UIKit/UIKit.h>
#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 : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
#else
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#endif
#property (strong, nonatomic) UIWindow *window;
#property (copy ,nonatomic) void(^backgroundSessionCompletionHandler)();
#end
// Copied from Apple's header in case it is missing in some cases (e.g. pre-Xcode 8 builds).
#ifndef NSFoundationVersionNumber_iOS_9_x_Max
#define NSFoundationVersionNumber_iOS_9_x_Max 1299
#endif
Here is my AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
#pragma mark - Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self initPushnotificationService];
[self decideViewController];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// SOME CODE
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// SOME CODE
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// SOME CODE
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// SOME CODE
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// SOME CODE
}
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken
{
// SOME CODE
}
- (void)application:(UIApplication *)app
didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
// SOME CODE
}
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forLocalNotification:(UILocalNotification *)notification
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)())completionHandler{
// SOME CODE
}
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(UILocalNotification *)notification
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void (^)())completionHandler{
// SOME CODE
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// SOME CODE
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// SOME CODE
}
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
#pragma mark -
#pragma mark - UNUserNotificationCenterDelegate
#pragma mark FOREGROUND Delegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
// SOME CODE
}
#pragma mark BACKGROUND Delegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler {
// SOME CODE
}
#endif
#pragma mark - push notification setup
-(void)initPushnotificationService{
UIMutableUserNotificationAction *viewMessageAction;
viewMessageAction = [[UIMutableUserNotificationAction alloc] init];
[viewMessageAction setActivationMode:UIUserNotificationActivationModeBackground];
[viewMessageAction setTitle:#"Say OK"];
[viewMessageAction setIdentifier:NotificationActionSayOkMessage];
[viewMessageAction setDestructive:NO];
[viewMessageAction setAuthenticationRequired:NO];
UIMutableUserNotificationAction *replyMessageAction;
if( __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0){
replyMessageAction = [[UIMutableUserNotificationAction alloc] init];
[replyMessageAction setActivationMode:UIUserNotificationActivationModeBackground];
[replyMessageAction setTitle:#"Reply"];
[replyMessageAction setBehavior:UIUserNotificationActionBehaviorTextInput];
[replyMessageAction setIdentifier:NotificationActionReplyMessage];
[replyMessageAction setDestructive:NO];
[replyMessageAction setAuthenticationRequired:NO];
}
else{
replyMessageAction = [[UIMutableUserNotificationAction alloc] init];
[replyMessageAction setActivationMode:UIUserNotificationActivationModeForeground];
[replyMessageAction setTitle:#"Reply"];
[replyMessageAction setIdentifier:NotificationActionReplyMessage];
[replyMessageAction setDestructive:NO];
[replyMessageAction setAuthenticationRequired:NO];
}
UIMutableUserNotificationCategory *viewMessageActionactionCategory;
viewMessageActionactionCategory = [[UIMutableUserNotificationCategory alloc] init];
[viewMessageActionactionCategory setIdentifier:NotificationCategoryViewMessage];
[viewMessageActionactionCategory setActions:#[viewMessageAction, replyMessageAction]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:viewMessageActionactionCategory];
// Register for remote notifications
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
/// iOS 7.1 or earlier. Disable the deprecation warnings.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
#pragma clang diagnostic pop
}
else
{ /// iOS 8 or later
// [START register_for_notifications]
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else{
#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) {
if( !error ){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
#try {
UNNotificationAction *sayOkMessageAction = [UNNotificationAction actionWithIdentifier:NotificationActionSayOkMessage title:#"Say OK" options:UNNotificationActionOptionAuthenticationRequired];
UNTextInputNotificationAction *replyMessageAction = [UNTextInputNotificationAction actionWithIdentifier:NotificationActionReplyMessage title:#"Reply" options:UNNotificationActionOptionAuthenticationRequired textInputButtonTitle:#"Reply" textInputPlaceholder:#"Message"];
UNNotificationCategory *messageCategory = [UNNotificationCategory categoryWithIdentifier:NotificationCategoryViewMessage actions:#[sayOkMessageAction,replyMessageAction] intentIdentifiers:#[NotificationActionSayOkMessage,NotificationActionReplyMessage] options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories_set = [NSSet setWithObject:messageCategory];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories_set];
/// For iOS 10 display notification (sent via APNS)
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
}
#catch (NSException *exception) {
NSLog(#"%#",exception);
}
}
];
#endif
}
}
}
#end
#soumenSardar -
For new xode 8.1, you have to add a entitlement file
Targets ---> Capabilities and verify Push Notifications is all correct on that view --> Fix it.
It should works
Be careful push notifications are off by default in xcode 8.1
Check you PushNotification Certificates. Either they are revoked or may be not created correctly or may be you are using wrong certificates for distribution.
Below are the steps I follow if push is not working in production mode
Make sure your SANDBOX is OFF
Ask developer & make sure they are using production aps file
Make sure your provision profile is created after you add push notification setting.
Usually I found Option 1 is what they didn't make.
If Option 1, 2, 3 are fine, check from your end for coding.
I've faced similar problem when switched fron XCode 7.x to XCode 8.x. Try check in Capabilities the Push Notifications switch setting is ON:
The rilevant part is the second check, previosly it was handled by XCode under your radar, now it's a setting you must enable.
Hi I am a beginner in iOS. In my project I want to get GCM notifications for that I have written some code but it shows exception and my code is as following :
#import "AppDelegate.h"
#import <Google/CloudMessaging.h>
#import "GGLInstanceID.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound |
UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings
settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
_registrationHandler = ^(NSString *registrationToken, NSError *error){
if (registrationToken != nil) {
weakSelf.registrationToken = registrationToken;
NSLog(#"Registration Token: %#", registrationToken);
NSDictionary *userInfo = #{#"registrationToken":registrationToken};
[[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey
object:nil
userInfo:userInfo];
} else {
NSLog(#"Registration to GCM failed with error: %#", error.localizedDescription);
NSDictionary *userInfo = #{#"error":error.localizedDescription};
[[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey
object:nil
userInfo:userInfo];
}
};
return YES;
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]];
_registrationOptions = #{kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:#YES};
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID
scope:kGGLInstanceIDScopeGCM
options:_registrationOptions
handler:_registrationHandler];
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Notification received: %#", userInfo);
// This works only if the app started the GCM service
[[GCMService sharedInstance] appDidReceiveMessage:userInfo];
}
But it's shows Exception like
unresolved identifier "_registrationHandler" and "weakSelf" in
didFinishLaunchingWithOptions method and it exception in
didRegisterForRemoteNotificationsWithDeviceToken method like
unresolved identifier "_registrationOptions".
Please help me someone
Here I've refactored your code and it should work now.
static NSString *const INSTANCE_ID_REGISTRATION_NOTIF_KEY = #"instance-id-token";
static NSString *const GCM_SENDER_ID = #"<your sender id>"; // #"123456"
#interface AppDelegate ()
#property (nonatomic, strong, readwrite) GGLInstanceIDTokenHandler registrationHandler;
#property (nonatomic, strong, readwrite) NSString *registrationToken;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound |
UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings
settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]];
NSDictionary *registrationOptions = #{
kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:#YES
};
__weak typeof(self) weakSelf = self;
GGLInstanceIDTokenHandler handler = ^(NSString *registrationToken, NSError *error){
typeof(weakSelf) strongSelf = weakSelf;
NSDictionary *userInfo;
if (registrationToken != nil) {
strongSelf.registrationToken = registrationToken;
NSLog(#"Registration Token: %#", registrationToken);
userInfo = #{ #"registrationToken" : registrationToken };
} else {
NSLog(#"Registration to GCM failed with error: %#", error.localizedDescription);
userInfo = #{ #"error" : error.localizedDescription };
}
[[NSNotificationCenter defaultCenter] postNotificationName:INSTANCE_ID_REGISTRATION_NOTIF_KEY
object:nil
userInfo:userInfo];
};
[[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:GCM_SENDER_ID
scope:kGGLInstanceIDScopeGCM
options:registrationOptions
handler:handler];
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Notification received: %#", userInfo);
// This works only if the app started the GCM service
[[GCMService sharedInstance] appDidReceiveMessage:userInfo];
}
#end
PS: As #Epaga commented above you should really try to start off with a simple obj-c tutorial because your compiler issues were very trivial.