set badge on tabbar item when notification received - ios

I tried to set badgeValue for UITabBarItem when push notification is received.I am using this code. Here the UITabBarController is not a rootViewController. I tried the same thing in resign active method but there also its not working.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UITabBarController *tabBarController = (UITabBarController *)[[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"tabBarController"] ;
[[tabBarController.tabBar.items objectAtIndex:2] setBadgeValue:#"1"];
}

I think that you can use NSNotificationCenter to post notification when you received a remoteNotification
In your UITabBarController initialize method
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myNotificationReceived:) name:#"pushNotification" object:nil];
And
In myNotificationReceived:
[[self.tabBar.items objectAtIndex:2] setBadgeValue:#"1"];
When you receive a remote notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"pushNotification" object:nil userInfo:userInfo];
In this way, you can get whole RemoteNotification information

Related

ios How to launch application in push notification

I am facing issue in launch of particular application page when user will get push notification in ios.
is this possible to do?
if yes, can you please help me in that.
You could send a notification to yourself when you get any remote notification and by registering the UIViewController to this notification, you could open a particular UIViewController once notification is received.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
[[NSNotificationCenter defaultCenter] postNotificationName:#"pushNotification" object:nil userInfo:userInfo];
}
In your FirstViewController.m register for listening to this notification.
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pushNotificationReceived) name:#"pushNotification" object:nil];
}
Inside the method you could open particular viewController
-(void)pushNotificationReceived{
[self presentViewController:self.secondViewController animated:YES completion:nil];
}
Finally un-register current viewController from notification in dealloc method
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Let me know if you face any problem with this.

Open ViewController from didFinishLaunchingWithOptions

I'm sending push notification to app which is terminated and it seems that only this method is triggered. I want to open ViewController when app is launched with push notification, but it doesn't do anything just opens app.
I tried to achieve that with this code:
if (launchOptions != nil) {
NSDictionary* userInfo = [launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo)
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"openNews" object:nil userInfo:userInfo];
}
}
and tried this as well ..
if (launchOptions != nil) {
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil)
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"openNews" object:nil userInfo:userInfo];
}
}
Any ideas how to launch ViewController when app is terminated with push notification?
So I have tried to save notification info to NSUserDefaults if launchOptions != nil just to check if Im receiving notification info and that part of code is triggered and it is but for some reason this part is not working:
[[NSNotificationCenter defaultCenter] postNotificationName:#"openNews" object:nil userInfo:userInfo];
but Im using same method and everywhere and it works fine
That won't work because you are posting a notification with no one to catch it yet.
Hmm, what you can do here is to set the initial ViewController of your application when it receives the launchOptions you specified.
You can set it using this:
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"YourStoryboard" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"YourStoryboardId"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
Be careful though in designing your navigations. Especially if you want your initial ViewController to be a page with back button that access the navigation stack.
Since you will make it your initial view controller, if it tries to popViewController, it will pop to nothing.
EDIT:
If you want it to be opened from the MainVC with a delay, you can put tnis in your MainVC
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(openAnotherVC:)
name:#"YourPostNotificationName" object:nil];
Then navigate to your desired VC in openAnotherVC: method

load storyboard viewcontroller from didReceiveRemoteNotification

I have used storyboard. The app is tab bar controller based.
When push notification is clicked, I want to open specific "Notification Event" view controller from storyboard."
I have no idea what code goes into didReceiveRemoteNotification.
here my code is:
NSString *notification = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
Dashboard *ds = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"Dashboard"] ;
NotificationTable *nt = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"NotificationBoard"] ;
UIStoryboardSegue *segue = [UIStoryboardSegue segueWithIdentifier:#"NotificationBoardTable"
source:ds
destination:nt
performHandler:^{
}];
[ds performSegueWithIdentifier:#"NotificationBoardTable" sender:ds];
Let's see if this is what you want:
[[NSNotificationCenter defaultCenter] postNotificationName:kReceiveNotification object:nil userInfo:YOUR_DATA_PASSING];
Then receive it in your custom tab view controller:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(YOUR_HANDLE_METHOD:) name:kReceiveNotification object:nil];
Don't forget to remove the observer when deallocating:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Finally in that method:
[self setSelectedIndex:xxx];//If you want to switch tab

Notify UI update in AppDelegate (UITabBarController badge)

In my app, UITabBarController is an initial ViewController build in storyBoard. I would like to observe data updating in my whole app. So I add an observer in appDelegate...
AppDelegate.m
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(shipCountBadge:) name:kShipCountBadge object:nil];
- (void)shipCountBadge:(NSNotification *)notification{
Groups *vc = [[Groups alloc] init];
[vc addBadgeCount:notification.object];
}
Group.m
- (void)addBadgeCount:(NSNumber *)count{
NSLog(#"d",[count intValue]);
[[self.tabBarController.tabBar.items objectAtIndex:2] setBadgeValue:[NSString stringWithFormat:#"%d",[count intValue]]];
}
Its doesn't change the UI at all. I would like to know how to update UI in AppDelegate actually? Anyone has an idea :)?

Handle UILocalNotification in UIViewController using NSNotification after the app has been terminated

I'm working with UILocalNotification and I would like to notify one of my controller that the notification has been received even if the app has been terminated.
In my appDelegate I implemented this function:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if ([application applicationState] == UIApplicationStateInactive) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"localNotificationReceived" object:notification.userInfo];
}
}
In my UIViewController I implemented the observer on the viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didlocalNotificationReceived:) name:#"localNotificationReceived" object:nil];
}
It works perfectly when the app run in background. Since the viewDidLoad method has already been called and the Observer is waiting..
The issue is when I kill the app. Then the observer of my controller is gone and the didlocalNotificationReceived method is never called.
I think that it's because when I receive the localNotification and run the app again. The didReceiveLocalNotification: method is called before the viewDidLoad of my UIViewController. Then the observer is created after the PostNotificationName then the observer receives nothing.
I would like to know if there is some best practices or pattern to handle this kind of issue.
I know that the didFinishLaunchingWithOptions method is called before didlocalNotificationReceived so there is probably something to do there.
UPDATE :
I also discovered that when is app is terminated. Once you tap the notification, It opens the app, call the function didFinishLaunchingWithOptions but never call didReceiveLocalNotification. So I think that I'm gonna handle both cases differently.
Ok I found the answer.
I actually, initialize manually my storyboard, and be cautious that I initialize my main view before posting the NSNotification
My didFinishLaunchingWithOptions: method in my appDelegate looks like that:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
UIViewController *vc =[storyboard instantiateInitialViewController]; //call the initWithCoder: method of my controller
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
[[NSNotificationCenter defaultCenter] postNotificationName:#"localNotificationReceived" object:localNotification.userInfo];
}
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
return YES;
}
Then in my UIViewController I create the NSNotification observer in the initWithCoder: method instead of in viewDidLoad:
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didlocalNotificationReceived:) name:#"localNotificationReceived" object:nil];
}
return self;
}
- (void)didlocalNotificationReceived:(NSNotification *)notification
{
//Execute whatever method when received local notification
}
And when the app is not killed I still use the didReceiveLocalNotification: method:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if ([application applicationState] == UIApplicationStateInactive) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"localNotificationReceived" object:notification.userInfo];
}
}
I'm not sure if it's the best practice. But it works well !
Hope it'll help :)

Resources