How to stop background services after logout the application? - ios

I have created iPhone application with some Background fetching service process for data local notification purpose. Now the problem is I had logout my application then It's successfully gone from home screen to Login screen but still now I am receiving notification, I mean still running background services. I want to stop all the activities from my app after clicking the logout button.
My source within Logout button event method
- (void)logoutButtonClick:(id)sender
{
NSLog(#"Logout Clicked");
Login *loginview = [[Login alloc]init];
[self.navigationController pushViewController:loginview animated:YES];
}

If its NSTimer invalidate it on logout like [timer invalidate], if you already register local notifications then you can cancel them on logout like get all notifications [[UIApplication sharedApplication] cancelAllLocalNotifications].
Update: You post notification from logouButtonAction like this [[NSNotificationCenter defaultCenter] postNotificationName:#"ApplciaitonDidLoggedOut" object:nil];
Your onlogoutbutton method should be like this
- (void)logoutButtonClick:(id)sender
{
NSLog(#"Logout Clicked");
Login *loginview = [[Login alloc]init];
[self.navigationController pushViewController:loginview animated:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:#"ApplciaitonDidLoggedOut" object:nil];
}
And in app delegate add observer for this notification in didFinishLaunch [[NSNotificationCenter defaultCenter ] addObserver:self selector:#selector(onLogut) name:#"ApplciaitonDidLoggedOut" object:nil];
and add method in appDelegate class
- (void) onLogut
{
//considering you have a timer property in app delegate,if not add one
[self.timer invalidate];
// if you want to cancel local notification
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}

Related

Turn off uiswitch from AppDelegate

I'm using LocalNotifications in my AppDelegate.m
If the user has the app open, the notification comes in the form of an alert.
The AppDelegate.m receives the clickedButtonAtIndex event. Regardless of the current view the user sees, the alert shows and everything works fine so far.
However, when receiving the event, I'd like to change the state of a UISwitch that exists on a UIVIewController.
EDIT: ADDED MORE CODE
My App is set up this way:
AppDelegate.m has this code:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
// Called from the local notification above when the View button is clicked and the app reopens
//called when app is open vs in background
NSLog(#"got notification");
UIApplicationState state=[application applicationState];
if(state==UIApplicationStateActive){
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Notice"
message:notification.alertBody
delegate:self cancelButtonTitle:#"Sleep"
otherButtonTitles:#"Turn Off", nil];
[alert show];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"clicked button");
if(buttonIndex==1){
SettingsPage *setPage = [[SettingsPage alloc] initWithNibName:nil bundle:nil];
[setPage clickedAlert];
}
}
SettingsPage.m has this code:
#interface SettingsPage()
#property (weak, nonatomic) IBOutlet UISwitch *alarmSwitch;
#end
#implementation SettingsPage
-(IBAction)setAlarm{
//clear all notifications before setting a new one
[[UIApplication sharedApplication] cancelAllLocalNotifications];
//set a new LocalNotification
UILocalNotification *localNotification=localNotification =[[UILocalNotification alloc] init];
if(localNotification!=nil){
localNotification.fireDate=[NSDate dateWithTimeIntervalSinceNow:60]; //seconds
localNotification.timeZone=[NSTimeZone defaultTimeZone];
localNotification.alertBody=#"Reminder!";
localNotification.hasAction=YES; //fires didreceive event, opens app
localNotification.soundName=UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; }
}
-(void)clickedAlert{
NSLog(#"clicked alert");
[self.alarmSwitch setOn:NO animated:YES];
}
This has the desired effect of setting the "alarmSwitch" to "Off" (and thus canceling further notices), but the switch itself still shows in the view as "On" (green).
How can I flip the actual switch on the SettingsPage via code from my AppDelegate.m so that it behaves the same as if the user did it (i.e. changes it's visual and executes the connected method)?
As CrimsonChris mentioned, you seem to be making a new instance of SettingsPage every time, thus you're not seeing the change you want.
You could fire off an NSNotification,
[[NSNotificationCenter defaultCenter] postNotificationName:#"ClickedButtonAtIndex1" object:nil];
..and listen to it in your UIViewController.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleIndex1Clicked) name:#"ClickedButtonAtIndex1" object:nil];
with your UIViewController doing what it needs to in the selector method:
-(void)handleIndex1Clicked
{
[self.setPage.alarmSwitch setOn:NO animated:YES];
}
PS. I'd suggest having extern const NSStrings holding your observer names.
Hope that helps!
It looks like you're getting a new SettingsPage and then setting its alarmSwitch to "Off". What you probably want is to get the existing SettingsPage instead of making a new one with alloc init.

Passing data received from a push notification from the AppDelegate to a ViewController

In my app, there's a collection view displaying a set of images retrieved from a web service. Each image has tags. So the app has the ability to filter images using tags as well.
Now I'm trying to add push notifications to this app. A push notification is sent when new images have been added to the server. These images are tagged say, latest. I'm passing that tag as the message via a push notification and what I need is when the user taps on the push notification to open the app, it should load the latest new images to the collection view.
I'm half way done. I receive the push notification with the message successfully to the didReceiveRemoteNotification method in the AppDelegate.m file. Now I need to pass it on to the view controller where the collection view is. I'm stuck at this point. I can't figure out how to send it over to the view controller.
I tried declaring a property in the App delegate, assign the message value to it and referring it from the view controller but it didn't work. I tied delegates, notification center, user defaults but nothing worked.
Can anyone please tell me how to accomplish this?
Thank you.
Edit:
Here's my code. The last method I tried was the local notifications.
AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"PushNotificationMessageReceivedNotification" object:nil userInfo:userInfo];
}
ViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(remoteNotificationReceived:) name:#"PushNotificationMessageReceivedNotification"
object:nil];
}
- (void)remoteNotificationReceived:(NSNotification *)notification
{
NSLog(#"Notification: %#", notification.userInfo);
NSString *msg = [[notification.userInfo valueForKey:#"aps"] valueForKey:#"alert"];
self.label.text = msg;
}
Case 1: if your app is background and user launches app with notification click then you have the check if app launched form notification or normal
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSDictionary *remoteNotificationPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotificationPayload) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"notification" object:nil userInfo:remoteNotificationPayload];
}
return YES; }
Case2: If your app is in forground notification will be received in didReceiveRemoteNotification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"userinfo %#",userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"notification" object:nil userInfo:userInfo];
}
Now you and add a observer in any controller with Local notification and do what you wand to do
I don't know it will work or not,its only my suggestion. I did't tried it before but in your case may be it work
user NSUserDefaults for this.
in your appDelegate.m
[[NSUserDefaults standardUserDefaults] setObject:imageArrayFromServer forKey:#"MyAppSpecificGloballyUniqueString"];
in your viewController.m
NSArray *myArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyAppSpecificGloballyUniqueString"];

UIApplicationDidBecomeActiveNotification filter notifications

I registered my main view controller for listening to UIApplicationDidBecomeActiveNotification because I want to display a UIAlertView each time the user enters my app :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(someMethod:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
It's working like a charm, my only problem is if my app gets interrupted (by an UIAletView, such as a calendar event, or a popup asking for picture access confirmation), the notification gets called once the alert view's dismissed.
Any idea on how to detect ONLY when my app comes back from background mode ?
why don't you use AppDelegate method,
- (void)applicationWillEnterForeground:(UIApplication *)application
{
//do whatever you want when app comes from background to foreground
}
I know this is an old thread, but there is a UIApplicationWillEnterForegroundNotification. Works like this:
[[NSNotificationCenter defaultCenter]addObserver:self
selector:#selector(myMethod)
name:UIApplicationWillEnterForegroundNotification
object:nil];
Best regards,
Gabriel Tomitsuka
Check state (active/background) of your application by following code:
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateActive)
{
/// your stuff of code:
}
Above code might be useful in your case:

View Controller method for lock button pressed?

Is there an available view controller method that is called when the user presses the lock button? I'm looking for something like viewDidDisappear: or viewWillDisappear:, but specific to the case of the lock button being pressed.
A notification called UIApplicationDidEnterBackgroundNotification is posted when the user locks their phone. Here's how to listen for it:
In viewDidLoad: of your ViewController:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(screenLocked) name:UIApplicationDidEnterBackgroundNotification object:nil];
Then, define a method (mine was called screenLocked above) and write code you want to be executed when the screen is locked.
-(void)screenLocked{
//do stuff
}
Also, to do some necessary cleanup, add this method to your ViewController too.
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
Try this :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
NSLog(#"Sent to background by locking screen");
} else if (state == UIApplicationStateBackground) {
NSLog(#"Sent to background by home button/switching to other app");
}
}

Call a method every time a UIViewController is shown

I want to show a full page image Ad every time a UIViewController is shown.
I think I have to call the method inside a viewDidAppear or ViewWillAppear, but they are being called once.
- (void) viewDidAppear:(BOOL)animated{
[self showAds];
}
- (void) showAds{
//Do Something
}
What should I do to call a method every time a uiviewcontroller is shown( even if its already created)?
ViewWillAppear will be called every time a UIViewController is shown,but won't be called when the app is back to foreground.
you can use Notification to achieve your goal by following code,
This scenario is specially when your app is in background and user press HOME button to active it.
Register for Notifcation when your application enterForground in viewDidLoad only.
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground)
name: UIApplicationDidBecomeActiveNotification
object: nil];
write a method to invoke when application enterForground
-(void)handleEnteredBackground
{
NSLog(#"%s",__FUNCTION__);
// Your stuff here
}
Dont forget to Remove Observer in viewDidUnload method
[[NSNotificationCenter defaultCenter] removeObserver:self];
Post New Notification everytime your application enterForground
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidBecomeActiveNotification object:nil];
}
ViewWillAppear should be called every time. Use:
- (void) viewWillAppear:(BOOL)animated{
[self showAds];
}

Resources