I add this function to post a notification when the app enter foreground:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName: #"UIApplicationWillEnterForegroundNotification" object: nil];
}
In my own class:
- (void) handleEnterForeground: (NSNotification*) sender
{
[self reloadTableData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnterForeground:)
name: #"UIApplicationWillEnterForegroundNotification"
object: nil];
}
but the handleEnterForeground: function will called twice, I don't know why. The
reloadTableData: function will call remote webService , so when the app enter
foreground, it will stuck for a while.
The system will call that event automatically. The reason it fires twice is because you manually fire it again.
P.S. It's better to use the variable name UIApplicationWillEnterForeground, instead of a NSString literal.
EDIT: I realize now the confusion is coming from the fact that you didn't know that this even name was already taken. As a note to other people who run into this kind of problem, it is a good practice to prefix your event names with your project prefix (i.e. XYZEventNotification) to avoid collisions.
Related
I bult an iOS app and in -(void)viewDidLoad I parse data from web, and display it on load. But often when I open my app it displays old data(app loads fast) and I need to kill it and open it again, after that it parses data and shows new. Why is that happening?
It doesn't work that way because viewDidLoad is only called once, when the view is created. After backgrounding and returning, your view still exists.
If you want to reload your data whenever the app returns from the background, you need to either override applicationDidBecomeActive: in your UIApplicationDelegate implementation, or you need to listen for the appropriate notification:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
// reload your data here.
}
Don't forget to remove yourself as an observer when you no longer need the notification.
I'm getting data off the server via JSON and displaying it on Labels.
I've added that method in viewDidLoad.
I want to refresh the data when the user opens the app again. Currently, even if I kill the app in the simulator and start the app again, it doesn't refresh.
I tried the viewDidAppear method, but it isn't being executed for some reason.
-(void)viewDidAppear{
NSLog(#"Called viewDidAppear");
}
This is never called. I tried to minimize the app but it didn't work.
You can listen for notifications and respond appropriately. Try using these and decide what works for your intended workflow.
UIApplicationDidBecomeActiveNotification
UIApplicationWillEnterForegroundNotification
You can use respond to the notification like this.
[[NSNotificationCenter defaultCenter] addObserverForName: UIApplicationDidBecomeActiveNotification object: nil queue: [NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
// LOAD JSON
}];
I followed this tutorial - http://leejon.es/notifying-a-viewcontroller-with-uiapplicationdidbecomeactivenotification/
First, attach to the notification in the viewWillAppear method of the target view controller:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector( appActivated: )
name: UIApplicationDidBecomeActiveNotification
object: nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self ];
}
- (void)appActivated:(NSNotification *)note
{
[self update];
}
The viewDidAppear: method takes a bool parameter wether the view was displayed with an animation which you are missing. Also you have to call the implementation of the superclass:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear: animated];
NSLog(#"Called viewDidAppear");
}
In your app delegate implementation, there is a method called:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
This method is called each time the app is launched, so I think it fits your needs. If you place your code here, it should work.
Also, be aware you should not perform a synchronous call here, because you will delay the app launch.
EDIT:
This method will be only called when the app launches. You could place your code inside a method, and call it from application didFinishLaunchingWithOptions, and then also call it from the method:
- (void)applicationWillEnterForeground:(UIApplication *)application;
This method will be called when the application enters the foreground, but not after the first launch, so beware.
I also think you should check the UIApplicationDelegate methods from apple developer page: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
Also, check out the application state changes:
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
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];
}
I'm developing an iOS app with latest SDK.
It's a fullscreen app.
I have a method on viewWillAppear method that has to be called every time the apps comes from background.
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setUpVideo];
}
On setUpVideo I set up AVCaptureVideoPreviewLayer because I lose the video when the apps come back from background.
As I have read, viewWillAppear isn't called when the apps come back from background and now, I don't know where to put that code.
On this question, occulus suggest to use [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doMyLayoutStuff:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; but it doesn't work for me.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(setUpVideo:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
}
Any advice?
Observe UIApplicationWillEnterForegroundNotification instead.
- (void)viewDidAppear {
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(enterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
// ...
}
- (void)enterForeground:(NSNotification *)notification {
// do stuff
}
Don't call viewWillAppear: directly from the enterForeground: method. Instead move all required code to a separate method and call that from both viewWillAppear: and enterForeground:.
applicationWillEnterForeground will trigger when app comes from background
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
Additionally, you can use UIApplicationDidBecomeActiveNotification for firing some method
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleMethod:)
name: UIApplicationDidBecomeActiveNotification
object: [UIApplication sharedApplication]];
Try posting this notification from
- (void)applicationDidBecomeActive:(UIApplication *)application of AppDelegate(or observe corresponding notification which is better)
When my app is first opened there is a long loading time so I can display a loading screen. When the user exits the app by clicking the home button then re-opens it (the viewDidLoad/viewDidAppear methods aren't called again) the app has another loading period, I guess while it's "waking up".
What method can I use to detect the user hitting the home button to send the app into the background and what method can I use to detect that the app has been revived from the background?
This should be sufficient enough to provide my loading screen properly but just in-case. Is there also a method for detecting when the loading has finished after a "revival"?
You can register a notification for UIApplicationWillEnterForegroundNotification. There you can do your stuff.
- (void)viewDidLoad
{
[super viewDidLoad];
// Register for the notifcation
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(refreshView) name:UIApplicationWillEnterForegroundNotification object:nil];
}
-(void)refreshView
{
/*
Invoked when application enters foreground. Do your stuff
*/
}
To remove observer
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
Albert you can detect home button click on this two method declared in AppDelegate
- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidEnterBackground:(UIApplication *)application
and these are notification you can use
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(setFlag:)
name: UIApplicationWillResignActiveNotification
object: [UIApplication sharedApplication]];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(setFlag1:)
name: UIApplicationDidEnterBackgroundNotification
object: [UIApplication sharedApplication]];