IOS Using method from ViewController.m in AppDelegate.m? - ios

So I have a method in ViewController.m that posts a notification (to notification center) with a push of a button
heres the method from ViewController.m
- (IBAction)buttonPush:(id)sender {
//clear NC
[[UIApplication sharedApplication] cancelAllLocalNotifications];
//make mutablearray
NSMutableArray *list = [NSMutableArray array];
[list addObject:first];
[list addObject:second];
[list addObject:third];
//post notification
for (UITextField *thing in list) {
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.alertBody = thing.text;
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
NSLog(#"looped!");
}
}
what i want to do is use the above method in the following method (which is in AppDelegate.m):
- (void)applicationDidEnterBackground:(UIApplication *)application

You can register to receive a notification in your view controller to be notified when the application will enter the background:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(buttonPush:) name:UIApplicationWillResignActiveNotification object:nil];

Related

postNotificationName is not yet trigger in appdelegate class

In Appdelegate.m added postNotification method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if(application.applicationState == UIApplicationStateBackground) {
[[NSNotificationCenter defaultCenter] postNotificationName: #"SuggetionPushNotification" object:nil userInfo:userInfo];
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
SideMenuViewController *leftMenuViewController = [[SideMenuViewController alloc] init];
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController
containerWithCenterViewController:[[UINavigationController alloc]
initWithRootViewController:[[SuggetionViewController alloc] init]]
leftMenuViewController:leftMenuViewController
rightMenuViewController:Nil];
[self.window makeKeyAndVisible];
appDel.window.rootViewController = container;
}
}
ViewController B (SuggetionViewController) In viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"SuggetionPushNotification"
object:nil];
- (void) receiveTestNotification:(NSNotification *) notification {
NSLog(#"working");
}
But here not yet fire Notification, if added both post and addobserver in same class then only it fire. what wrong i made. I referred from Send and receive messages through NSNotificationCenter in Objective-C? Please help
Your View Controller B is not in memory when you are posting the notification thats why Controller B is unable to observe the notification. Add Delay before posting the notification will help.
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[[NSNotificationCenter defaultCenter] postNotificationName: #"SuggetionPushNotification" object:nil userInfo:nil];
});
You're calling your notification from the launch method in the app delegate before any view/viewcontroller hierarchy has a change to instantiate and load. The reason you are not getting the notification is because your SuggetionViewController has not been instantiated yet. If you want the notification to be received, you need to fire it after the view controller gets a change to be created.
You can't receive notification inside your SuggetionViewController if it's now loaded.
You add the observer in the viewDidLoad so it can happens that you recieve a remote notification while the SuggetionViewController is not loaded.
You should ensure that your controller is loaded before processing notifications.
In your AppDelegate implementation add this
static void displayStatusChanged(CFNotificationCenterRef center, void *observer,
CFStringRef name, const void *object,
CFDictionaryRef userInfo) {
if (name == CFSTR("com.apple.springboard.lockcomplete")) {
[[NSUserDefaults standardUserDefaults] setBool:YES
forKey:#"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
In applicationDidFinishLaunchingWithOptions, add this below code
CFNotificationCenterAddObserver(
CFNotificationCenterGetDarwinNotifyCenter(), NULL, displayStatusChanged,
CFSTR("com.apple.springboard.lockcomplete"), NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
Post it in your didRecieveRemoteNotification method.
[[NSNotificationCenter defaultCenter]postNotificationName:#"TestNotification" object:self];
Post this in your view controller viewDidLoad method.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"TestNotification"
object:nil];
Then it will trigger this method.
- (void) receiveTestNotification:(NSNotification *) notification
{
if ([[notification name] isEqualToString:#"TestNotification"]) {
NSLog (#"Successfully received the test notification!");
}
}
Your 'SuggetionViewController' object is not initialized when you post the notification. So there is no 'SuggetionViewController' object to catch the notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
if(application.applicationState == UIApplicationStateBackground) {
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
SideMenuViewController *leftMenuViewController = [[SideMenuViewController alloc] init];
SuggetionViewController *sug_controller = [[SuggetionViewController alloc] init]];
[sug_controller registerNotification];
[[NSNotificationCenter defaultCenter] postNotificationName: #"SuggetionPushNotification" object:nil userInfo:userInfo];
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController containerWithCenterViewController:[[UINavigationController alloc] initWithRootViewController:sug_controller leftMenuViewController:leftMenuViewController rightMenuViewController:Nil];
[self.window makeKeyAndVisible];
appDel.window.rootViewController = container;
}
}
Add the following instance method to SuggetionViewController
- (void)registerNotification
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveTestNotification:) name:#"SuggetionPushNotification" object:nil];
}
- (void)receiveTestNotification
{
NSlog(#"Notification recieved-->>>");
}

How to set badge for UIBarButtonItem from Appdelegate (whenever push notification comes) if UITabbarcontroller is not the rootviewcontroller?

How to set badge for UIBarButtonItem from Appdelegate (whenever push notification comes) if UITabbarcontroller is not the rootviewcontroller ?
I have a LoginViewController and a PinViewController before UITabbarcontroller. I'm setting LoginViewController as rootviewcontroller if user has not logged in and PinViewController as rootviewcontroller if user has already logged in. But I found that we could set badge for UIBarButtonItem from Appdelegate only if the rootviewcontroller is UITabbarcontroller.
Can anyone help me with this?
You can manage it by Posting Notifications
// In App Delegate Class
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSNumber *count = [NSNumber numberWithInt:5]; // This is static...
NSDictionary *dataDict = [NSDictionary dictionaryWithObject:count
forKey:#"count"];
application.applicationIconBadgeNumber = 0;
if (application.applicationState == UIApplicationStateActive)
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"getPushNotification" object:dataDict];
}
}
In Controller where you want to update badge count on bar.
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateBadgeCount:)
name:#"getPushNotification"
object:nil];
}
- (void)updateBadgeCount:(NSNotification *)note {
NSDictionary *theData = [note userInfo];
if (theData != nil) {
NSNumber *n = [theData objectForKey:#"count"];
// Do your stuff here...
}
}
Thanks.

Not Background Method called for LocalNotification

If i force close my app from background. then local notification come .And if tapped on local notification my method not called when app is running in foreground.I am newer in iOS. Please Help.
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Reh" object:nil];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Reminder"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil,nil];
[alert show];
NSLog(#"%#",notification.soundName);
// AudioServicesPlaySystemSound (1010);
MyNotificationViewController *profile=[[MyNotificationViewController alloc]initWithNibName:#"MyNotificationViewController" bundle:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshFoeByPush" object:nil];
self.viewController = [[SWRevealViewController alloc] initWithRearViewController:self.leftMenuController frontViewController:profile]; self.viewController.rightViewController=nil;
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionCurveEaseInOut
animations:^{self.window.rootViewController = self.viewController;} completion:nil];
application.applicationIconBadgeNumber = 0;
}
else
{
NSString *tokend= [[NSUserDefaults standardUserDefaults] stringForKey:#"token"];
if (tokend == (id)[NSNull null] || tokend.length == 0 )
{
}
else
{
MyNotificationViewController *profile=[[MyNotificationViewController alloc]initWithNibName:#"MyNotificationViewController" bundle:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshFoeByPush" object:nil];
self.viewController = [[SWRevealViewController alloc] initWithRearViewController:self.leftMenuController frontViewController:profile]; self.viewController.rightViewController=nil;
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionCurveEaseInOut
animations:^{self.window.rootViewController = self.viewController;} completion:nil];
}
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification != nil) {
[self showLocalNotificationAlert:localNotification];
}
return YES;
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[self showLocalNotificationAlert:notification];
}
-(void)showLocalNotificationAlert:(UILocalNotification *)notification {
// handle here what you want
}
ALSO
When local notification fire didReceiveLocalNotification method is called not handleActionWithIdentifier
And yes put your stuff in common method -(void)showLocalNotificationAlert:(UILocalNotification *)notification so you just needs to call
When app is in forground then didReceiveLocalNotification this will called.
When app is not in forground and you tapped on notification then this notification object can be get from didFinishLaunchingWithOptions
For Remote Notification
In didFinishLaunchingWithOptions
NSDictionary *remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification) {
[self showRemoteNotificationAlert:remoteNotification];
}
Dictionary contains payload for remotenotification
And also made common method for remote notification fire and remote notification tapped.
lol
When your app is killed and you tap on push notification this function will trigger;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
you should handle it like this,
UILocalNotification *localNotif = [launchOptionsobjectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
Parse or Do something
}

Using NSNotifier to call a method when app is in the background

I am using the NSNotifier to create an Alarm Clock that calls a method when the time set is reached. I can get this to work successfully when the App is in the foreground. But when in the background, I can only get a notification to be presented.
Is it possible to call a method using the NSNotifier, when the app is in the background? If so how do I accomplish this?
Here is my code so far:-
appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ProcessDidComplete:) name:#"ProcessDidComplete" object:nil];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"ProcessDidComplete" object:nil];
}
- (void) ProcessDidComplete:(NSNotification *)pNotification
{
NSString *processData;
processData = #"Processing Data";
}
viewcontroller.m
-(void)addLocalNotification
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.repeatInterval = NSMinuteCalendarUnit;
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
notification.alertBody = #"This is local notification!";
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
According to documentation, -application:didReceiveLocalNotification: only gets called when the application is in the foreground.
See documentation for UIApplicationDelegate and handling local and remote notifications.

Where is the best place to remove Observer from Notification Center

I think that should be here:
-(void) viewWillDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self];
}
or maybe in -dealloc.
Both sound strange to me so I´m not totally sure of it.
First, in my AppDelegate I´m listening to a Remote Notification Via Parse
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
NSString * urlToGo = [userInfo objectForKey:#"url"];
NSLog (#"Recibo notificación con paremetro url: %#", urlToGo);
NSNotification *note = [NSNotification
notificationWithName:PUSH_NOTIFICATION
object:self
userInfo:userInfo];
[[NSNotificationCenter defaultCenter] postNotification:note];
}
and in myViewController
- (void) viewDidLoad {
[super viewDidLoad];
_lastMenuSelected=menu1;
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[center addObserverForName:PUSH_NOTIFICATION
object:nil
queue:mainQueue
usingBlock:^(NSNotification *note) {
// Save in property to load parameter in prepareForSegure
_urlToLoadFromPush = urlToGoReceivedFromPush;
[self showPush:self];
}];
}
- (void)showPush:(id)sender {
PushViewController * pushViewController=(PushViewController*)[self.storyboard instantiateViewControllerWithIdentifier:#"PushId"];
pushViewController.url = _urlToLoadFromPush;
UINavigationController* nVC=[[UINavigationController alloc] initWithRootViewController:pushViewController];
[self presentViewController:nVC animated:YES completion:^{
//[_delegate logout];
}];
}
Since you seem to be adding the observer in the viewDidLoad method (which is only called once as of iOS 6), you should remove the observer in the dealloc method.
Don't remove the observer in viewWillDisappear beacause generally we require to post the notification when the view is in the stack but not appearing. So always try to remove the observers in -(void)dealloc with the name of observer.

Resources