How to open UIUserNotificationSettings in any uiviewcontroller - ios

Usually, I set UIUserNotificationSettings in Appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//some codes
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert
| UIUserNotificationTypeBadge
| UIUserNotificationTypeSound
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Register Remote Notifications error:{%#}",[error localizedDescription]);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Receive remote notification : %#",userInfo);
}
but now I want to use it in a UIViewcontroller, such as there's a UIButton in a UIViewcontroller, when I click it, it will call this function, any ideas?

Try this one:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Receive remote notification : %#",userInfo);
YourViewController *login=[storyboard instantiateViewControllerWithIdentifier:#"YourViewContollerIDName"];
MainNavigationViewController *mainNavigation=[storyboard instantiateViewControllerWithIdentifier:#"MainNavigationViewController"];
[mainNavigation setViewControllers:#[login] animated:NO];
self.window.rootViewController=mainNavigation;
}
OR
Appdelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Receive remote notification : %#",userInfo);
[[NSNotificationCenter defaultCenter]postNotificationName:#"Notification" object:self userInfo:userInfo];
}
YourViewContoller.m
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"Notification"
object:nil];
}
- (void)receiveNotification:(NSNotification *) notification{
if ([[notification name] isEqualToString:#"Notification"]) {
//call your function
}
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

You do basically the same thing as a reaction to pressing the button, just use UIApplication.shared instead of using application provided by AppDelegate, so e.g. (Swift syntax):
UIApplication.shared.registerForRemoteNotifications()
Moreover, I would recommend implementing your own custom UserNotificationManager :
class UserNotificationManager: NSObject, UNUserNotificationCenterDelegate { ... }

I hope below code helps you,
create a new class called UIUserNotifications, and add the following code to the .h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface UIUserNotificationsHandler : NSObject
+ (void)registerUserNotifications;
#end
and following code to the .m file. Then call that function from your ViewController class
#import "UIUserNotificationsHandler.h"
#implementation UIUserNotificationsHandler
+ (void)registerUserNotifications{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert
| UIUserNotificationTypeBadge
| UIUserNotificationTypeSound
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
#end

Related

iOS Firebase notifications only appear in background

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?

Unable to get push notifications to work

I am trying to implement push notifications in my application. I am using APNs Authentication Key. Every guide I found so far has either deprecated method or it's in Swift. I am interested in a guide like this one but in Objective C.
What I have done so far, inside AppDelegate.m :
#import Firebase;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FIRApp configure];
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo) {
[self application:application didReceiveRemoteNotification:userInfo];
}
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
didReceiveRemoteNotification:(NSDictionary *)userInfo {
// Perform different operations depending on the scenario
if (application.applicationState == UIApplicationStateInactive) {
// Opening the app
NSLog(#"Firebase opening app");
}
else if (application.applicationState == UIApplicationStateBackground) {
// Coming from background
NSLog(#"Firebase background");
}
else {
// Active
NSLog(#"Firebase active");
}
}
Unfortunately when I send a message from firebase I get nothing, no output in xcode Console and no notification.
I would appreciate it if you can point me to the right direction.
You do not implement the firebase apn token neither you connect to the database. Why not just implement it like here firebase example.
Did you even setup the plist and the POD libs? In the code example above there is only deprecated code for the iOS part of version 8/9 - means u can ignore these code lines.
Please use this method:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//Do something
}
instead of this:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Do something
}
Update:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FIRApp configure];
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)])
{
#ifdef __IPHONE_8_0
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert
| UIUserNotificationTypeBadge
| UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
#endif
}
else
{
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
return YES;
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
}

UILocalNotification not called when is in background

I'm try to fire UILocalNotification when app is in background and is in active state. I use following:
In App Delegate i want to "catch" notification callback by this (it's not called):
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo{
NSLog(#"recieve-old-notif-here");
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSLog(#"recieve-old-notif");
}
Here is how i declared local notification:
NSString *strToShow = [NSString stringWithFormat:#"Время вставать"];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:15];
notification.alertBody = strToShow;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Please note that i already achieve that task with iOS 10 notifications, but i want to support this feature on older version devices.
So, my delegate methods suppose to call but their does not, why?
Add below code to the didFinishLaunchingWithOptions method in delegate :
ifdef __IPHONE_8_0
//Right, that is the point
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
else
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
endif
and below delegate methods;
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:#"declineAction"]){
}
else if ([identifier isEqualToString:#"answerAction"]){
}
}
#endif

handleActionWithIdentifier doesn't work

I use UILocalNotification in one app and in iOS 7 or earlier is working fine, but in iOS 8 didReceiveLocalNotification is not being called at all.
After some research I found out that in iOS 8 we have to use handleActionWithIdentifier instead, and so I tried it but also this void is not being called when LocalNotification run.
Here is my code:
I've got this code in didFinishLaunchingWithOptions and it works ok, first time I launched the app I've been asked permission to give notifications etc.
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
Then I got:
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification
completionHandler:(void(^)())completionHandler
{
NSLog(#"handleAction");
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"didReceive");
}
When the localNotification run and I slide my finger on the message that appears on the screen nothing happens... logs are not called at all...
I also noticed that if the app is active and running, when the localNotification run, it get called the method didReceiveLocalNotification
Anyone know what am I doing wrong? Thanks for any help
add this to your didFinishLaunchingWithOptions:
if ([[UIApplication sharedApplication]respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
// iOS 8 Notifications
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
// iOS < 8 Notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
You forgot to add this line:
[[UIApplication sharedApplication] registerForRemoteNotifications];
According to the Apple documentation of application:handleActionWithIdentifier:forLocalNotification:completionHandler::
Your implementation of this method should perform the action associated with the specified identifier and execute the block in the completionHandler parameter as soon as you are done. Failure to execute the completion handler block at the end of your implementation will cause your app to be terminated.
Your implementation above is missing the completion handler block.
To make it work, modify your application:handleActionWithIdentifier:forLocalNotification:completionHandler: to be as follows:
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler
{
NSLog(#"handleAction");
if (completionHandler) {
completionHandler();
}
}
This method calle when the user taps a custom action in the alert for a remote or local notification’s.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandle
{
//some action
}
When you slide finger on screen called this method
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
}
While I see you are handling the "forRemoteNotification:" case,
I don't see this being defined in your original block of code:
application:handleActionWithIdentifier:forLocalNotification:completionHandler:

Silent push notification

Just wanted a confirmation. Does the app ask for user permission if i have used silent push notification service like it use to ask when push notification was used. Any help would be appreciated
No. It's silent, meaning it works in the background, without user confirmation at the time of the notification.
At app install it asks for confirmation like a normal push notification.
For silent push you have to set JSON like this (php file),
$body['aps'] = array(
'sound' => '',
'content-available' => 1
);
don't send alert and badge.
In xcode file select target -> capabilities and enable background modes and tick remote notification
in appdelegate.m file just use this message to receive silent push
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
//Success this method will automatically call when device receives push notification
handler(UIBackgroundFetchResultNewData);
}
// eg code to register for apps
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
return YES;
}
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:#"declineAction"]){
}
else if ([identifier isEqualToString:#"answerAction"]){
}
}
#endif
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}

Resources