Send NSNotification on background thread in Appdelegate.m - ios

I am receiving a remote notification. I want to post a nsnotification. I can post the notification, but I can't receive it in my current view controller.
Here is my code.
I know this gets called:
AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:CHAT_MESSAGE_RECEIVED object:nil userInfo:messageIdDict];
}
This gets called before the above code gets called
MyViewController.m
-(void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(messageReceived:)
name:CHAT_MESSAGE_RECEIVED
object:self];
}
-(void)messageReceived:(NSDictionary *)userInfo
{
NSLog(#"Logged");
}

Here is how i would do it:
In AppDelegate:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:CHAT_MESSAGE_RECEIVED
object:messageIdDict
userInfo:nil];
}
In MyViewController:
-(void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(messageReceived:)
name:CHAT_MESSAGE_RECEIVED
object:nil];
}
-(void)messageReceived:(NSNotification *)notification
{
NSDictionary *userInfo = NSDictionary dictionaryWithDictionary:[notification object]];
NSLog(#"Logged");
}
Hope this helps

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-->>>");
}

Parse Push Notifications, how do I modify a variable in the current view controller when a notification is recieved?

when my app receives a push notification I want to increment a variable i.e. totalMessages++. I know that :
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[PFPush handlePush:userInfo];
}
is called when a push is received and the app is currently open. However this is declared in AppDelegate.m. How would I modify a variable in the currently displayed view controller i.e. FriendDisplayViewController?
You may want to begin by handling the notification & payload (read: userInfo) yourself, e.g.:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[NSNotificationCenter defaultCenter] postNotificationName:superUniqueNotificationName
object:nil
userInfo:userInfo];
}
For the appDelegate & your viewController to use the same notificationName, you'll want to share it somewhere centrally (e.g.: AwesomeConstants.h/.m):
FOUNDATION_EXTERN NSString * const superUniqueNotificationName; // .h
NSString * const superUniqueNotificationName = #"superUniqueNotificationName"; // .m
Leaving your viewController to include something like
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receivedParseNotification:)
name:superUniqueNotificationName
object:nil];
}
-(void)dealloc {
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
-(void)receivedParseNotification:(NSNotification *)parseNotification {
NSLog(#"got %# in FriendDisplayViewController, let's rock some variables", parseNotification);
}

How to Show Push Notifications on another ViewController. I am receiveing it on Appdelegate page on all the three cases

Please tell me how to send the appdelegate to another viewcontroller using NSdoctionary and receive it on the new view controller and show it.
-(void)application:(UIApplication*)application didReceiveRemoteNotification: (NSDictionary*)userInfo
{
NSLog(#"Push received: %#", userInfo);
}
There are few ways/ But I prefer using https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/index.html
Somrewere in constants
NSString *const NOTIFICATION_ID = #"com.yourapp.notificationID";
ViewController.m
- (void)viewDidLoad
{
NSNotificationCenter * notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:#selector(notificationRecieved:)
name:NOTIFICATION_ID
object:nil];
}
- (void)notificationRecieved:(NSNotification*)notification
{
NSLog(#"Push received: %#", notification.userInfo);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIFICATION_ID object:nil];
}
AppDelegate.m
-(void)application:(UIApplication*)application didReceiveRemoteNotification: (NSDictionary*)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ID object:nil userInfo:userInfo];
}
Use Notifications. The app delegate will post the notification with the notification dictionary, the view controller will be listening for it.

PushNotification redirect to respected viewcontroller

I am using push notification in my application. My question is, if user receives a push notification out of the app, user should be able to click that notification banner and be
brought to the activities page where notification is displayed.
Anybody can help me how to solve this issue. I am new in push notification.
//Use this code in your AppDelegate.m
-(void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//code for navigate to viewcontroller
ActivityViewController *objActivity = [[ActivityViewController alloc] initWithNibName:#"ActivityViewController" bundle:nil];
[self.navigationcontroller pushViewController: objActivity animated:YES];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSString *aPayload=[userInfo objectForKey:#"payload"];
NSDictionary *JSON =
[NSJSONSerialization JSONObjectWithData: [aPayload dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: NULL];
if ([[JSON objectForKey:#"activity"]isEqualToString:#"encore"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Piggyback"
message: [[userInfo objectForKey:#"aps"] objectForKey:#"alert"]
delegate: nil
cancelButtonTitle:#"DONE"
otherButtonTitles: nil];
self.likeBedge=self.likeBedge+1;
[alert show];
[[NSNotificationCenter defaultCenter] postNotificationName:#"likeComment" object:self userInfo:userInfo];
}
else if ([[JSON objectForKey:#"activity"]isEqualToString:#"like"]||[[JSON objectForKey:#"activity"]isEqualToString:#"comment"]){
self.likeBedge=self.likeBedge+1;
[[NSNotificationCenter defaultCenter] postNotificationName:#"likeComment" object:self userInfo:userInfo];
}
else if ([[JSON objectForKey:#"activity"]isEqualToString:#"started playing"]){
self.postBedge=self.postBedge+1;
NSLog(#"%d",self.postBedge);
[[NSNotificationCenter defaultCenter] postNotificationName:#"started playing" object:self userInfo:userInfo];
}
else if ([[JSON objectForKey:#"activity"]isEqualToString:#"stopped playing"]){
[[NSNotificationCenter defaultCenter] postNotificationName:#"stopped playing" object:self userInfo:userInfo];
}
else if ([[JSON objectForKey:#"activity"]isEqualToString:#"#user play"]||[[JSON objectForKey:#"activity"]isEqualToString:#"#user comment"]){
[[NSNotificationCenter defaultCenter] postNotificationName:#"likeComment" object:self userInfo:userInfo];
}
return;
}
i have already done this above code but when app is in background and if notification is come user tap on banner it should redirect to activity page
So when the application goes to background and you receive a notification the method you are going to call in appdelegate.m file is
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// Here present the class you want
}

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