applicationDidBecomeActive getting called twice - iphone

My app delegate method applicationDidBecomeActive: is getting called twice for the first time launch of the application. I have some portion of code which I want to execute only once & that I have put into applicationDidBecomeActive:
What should I do?

I got the issue. I am using Location Services. When launching for the first time after I tap on "OK" on the location services alert, my applicationDidBecomeActive gets called one more time which is the normal iOS behavior.

If you want to call your code only once when app becomes active, try calling it from two methods.
didFinishLaunchingWithOptions
applicationWillEnterForeground
instead of calling it only from applicationDidBecomeActive.

This is because of location or push notification alert.
After the native location/push notification has been dismissed, applicationDidBecomeActive will be called.

I don't know if this will help, but I just had the same issue with a totally simple app that doesn't use Location Services, and I found out it's an illusion. Look at the logging messages I got:
2012-12-22 10:47:45.329 Bizarro[10416:907] start applicationDidBecomeActive:
2012-12-22 10:47:45.333 Bizarro[10416:907] end applicationDidBecomeActive:
2012-12-22 10:47:45.329 Bizarro[10416:907] start applicationDidBecomeActive:
2012-12-22 10:47:45.333 Bizarro[10416:907] end applicationDidBecomeActive:
Look closely. Look at the times. The first and third messages have the same time. The second and fourth messages have the same time. They are the same messages! It's an Xcode bug; it has nothing to do with my code. Xcode is reporting the same log messages twice.
In my case, I was able to prevent this by turning off all Behaviors for Running -> Generates Output.

What about:
Increment on applicationDidBecomeActive
Decrement on callback events of permissions requests or other alerts that trigger another applicationDidBecomeActive when closed.

With Xcode 6 there's a new reason this can happen: when you launch an app in a resizable simulator, applicationDidBecomeActive: will get called twice.
It launches the app with the default size class, and then applies the size you were last using—even if you were using the defaults. Any time a change in size class is applied, applicationDidBecomeActive: gets called.

When app launches first time
it calls sequentially,
didFinishLaunchingWithOptions
applicationDidBecomeActive (Twice)
When we open the Control Center it calls only,
applicationDidBecomeActive
When app come from background to foreground it calls sequentially
applicationWillEnterForeground
applicationDidBecomeActive

I'm currently seeing double notifications.
It's happening because my AppDelegate's init code is being called twice.
It's being called once when the main() does [[NSBundle mainBundle] loadNibNamed:#"MainMenu" owner:application topLevelObjects:&tl] (ie, when the .XIB file is loaded), becaues the .XIB file is setting up FirstResponder to my custom AppDelegate, and then it's being called again when main() calls [[myAppDelegate alloc] init].
The init code is what does the addObserver calls, so two observers are being set up for each notification I care about, which is why my notifications get called twice.
I'm a newbie OS X programmer, so I'm not yet sure of the best way to resolve these two, but wanted to post it here in case it's of help to others, another place to look.

Have you possibly created an instance of your class in Interface Builder AND in your AppDelegate code, perhaps?

If you have code you want called only once when the app starts up, then use
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
instead.
Otherwise, applicationDidBecomeActive will be called whenever your app becomes active again, so that doesn't just mean twice as in your case, but every time the user switches back to your app after switching to another.

If you use RxSwift, then you can just throttle the application event, so it doesn't call twice in the same second:
NotificationCenter.default.rx.notification(Notification.Name.UIApplicationDidBecomeActive)
.throttle(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
self.appEnteredFromBackground()
}.disposed(by: disposeBag)
private func appEnteredFromBackground() {
Analytics.trackPageView(withScreen: .home)
dataStore.checkIfAllowingRides()
}
I put this code in my actual view controller where the logic is supposed to happen on ApplicationDidBecomeActive.

I just check at top of applicationDidBecomeActive: if the request was really sent (I made a function for this, checking status), if so I return already.
The second time in applicationDidBecomeActive:, the function reads the status as Deny or Allowed, because this is after the User answered the Alert.

Related

applicationDidEnterBackground & applicationWillResignActive are not being called

I am creating a simple application which perform some task on main thread. I am printing process in NSLog so I can understand that my process is running or not.
Now when I press home button without starting the process (Process will be start when I tap on a button) application enters in background and my both of methods applicationDidEnterBackground & applicationWillResignActive are being called.
But when I first tap on my button and process starts on main thread after that if I press home button none of these two method being called. So my application can't know that app entered in background or not.
Even after that when I again active the app it shows me a black screen with status bar only.
Why this is happening?
Why app not entering in background?
Why apple's methods not being called?
Is there a way to solve it?
UPDATE
Here is my appdelegate class code
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
All methods have no implementation.
Thanks in advance.
I am creating a simple application which perform some task on main thread.
Don't perform long-running operations on the main thread.
The delegate callbacks happen on the main thread. If the main thread is busy, then the callbacks won't happen until you return to the "run loop".
When foregrounding your app, the OS actually displays a screenshot if available, falling back to the launch image (Default.png). The screenshot is taken after -applicationDidEnterBackground: returns, which allows you to customize what gets saved (you might want to do this for security reasons, or to hide UI elements which might not make sense to show when relaunching e.g. a countdown timer).
The black screen is probably because your app has no launch image. If your app takes more than about 10 seconds to enter the background (and it does, since the main thread is blocked), it gets killed. Except the debugger is attached and catches SIGKILL, so it's easy to miss unless you're watching Xcode.
there are some cases
if UIApplicationExitsOnSuspend key set to true in your app's Info.plist, the applicationWillResignActive method is not called when the user hits the home button. and may b some thing other. check keys here Apple keys and see if something new you added to plist. and there is no other case that you say your delegate method not calling. it may also some time due to project in appropriate behavior. try cleaning your project and rebuild.
this is going to sound strange but for those it helps. I had the same issue and cleaned my project and then it started working again.

When to show Alert for Startup and coming out of background?

In my project I show an Alert to the user to indicate an 'empty list'.
Right now, I show it in AppDelegate>applicationDidBecomeActive.
I'm doing this because I want the alert to show if the list is empty
at app startup and when coming out of the background (iOS 4.2 through 5.x).
EDIT:
I use a method in the AppDelegate, and call it with a slight delay, and I still get this notice.
[self performSelector:#selector(checkForNoMessages) withObject:nil afterDelay:1.0];
However, this causes a "wait_fences" notice in the debugger and I'd prefer not to submit to Apple with this notice.
Where is the proper place to put a popup Alert so that it appears:
1) At App startup
AND
2) When the App is coming out of the background?
Do I need the Alert in more than one place?
I recommend writing a method in your AppDelegate or better in your root view controller which shows the message. Maybe with some arguments, so you can reuse it but that's up to you.
If you are following the MVC architecture ask your model about existing entries and trigger the Alert message if necessary. But encapsulate this behavior in a controller as well.
application:didFinishLaunchingWithOptions: and applicationDidBecomeActive: are the places where you want to delegate this task to your controller.
More about iOS Multitasking: https://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
Edit:
Don't forget that you have to call the methods from the main thread.
And do all startup stuff first.
OK - the problem wasn't where I called the alert, it was because it was in a method. Once I moved the code from a method into applicationDidBecomeActive, all is well.

ViewDidAppear Home Button

I have a timer with a countdown. In recent testing, I've noticed that if I hit the home button and return to the app, the timer is off (fewer seconds have ticked off than should).
I've noticed in testing that ViewDid and ViewWill Appear do not fire when re-opening the app. I know that:
- (void)applicationWillEnterForeground:(UIApplication *)application
Fires, but how do I make it specific to certain part of a viewController that was active?
You probably want applicationDidBecomeActive: and applicationWillResignActive:, which are sent to your app delegate. There are also notifications posted (e.g. UIApplicationDidBecomeActiveNotification) you could listen for.
Those are also posted when, e.g., a system alert comes in. If you just want to be told when you're going to the background, try applicationDidEnterBackground: and applicationWillEnterForeground:
See the Apple Docs on lifecycle for details.
Just for the sake of follow up, as the question was answered above.
I had the exact same problem as Eric and then I implemented Jesse's suggestion about using applicationDidBecomeActive: on the delegate. I just wanted to make sure how all the different methods were being called, and I found this:
application:didFinishLaunchingWithOptions: is called at the very start, as expected.
Then, is the main view controller's viewDidLoad turn.
Then viewWillAppear: is called.
Back in the application delegate, applicationDidBecomeActive: is triggered (here I call my reactivateTimer method which I implemented in the main view controller).
The reactivateTimer method is executed.
The last step is the call to the main view controller's viewDidAppear:

iOS4: application termination event?

I would like to know how i can detect when an application is about to be terminated. I mean really terminated, not just going into background mode. I have used this event, and it doesn't fire :
applicationWillTerminate
What i would really like to achieve is get some kind of event or notification when the user taps Home twice and presses the red baloon on the app. I don't care about the application going into background mode, there are a couple of events that handle this properly and they all work fine.
I need this so that i can "inform" my server to stop sending push notifications to APNS for apps that are terminated and aren't running in the background.
If you know of an easier way to achieve this, i'd be glad to hear :)
Thank you
Register your object (view controller, etc.) to listen for the UIApplicationWillTerminateNotification notification, and/or override the application delegate's -applicationWillTerminate: method and put your code there.
Angel, what you're asking for cannot be done. The app will be terminated with SIGKILL. Unstoppable, not catchable, no notifications. There is no difference between a system-initiated termination or one requested by the user.
You'll get applicationWillTerminate only if your app doesn't support background processing.
From UIApplicationDelegate docs on the matter:
For applications that support
background execution, this method is
generally not called when the user
quits the application because the
application simply moves to the
background in that case. However, this
method may be called in situations
where the application is running in
the background (not suspended) and the
system needs to terminate it for some
reason.
Seems to me that unless your background process is actively doing something in the background (not being suspended) it the applicationWillTerminate method will never get called.
I guess it depends what you definition of "being in the background" is.
IIRC it goes like this:
On start:
didFinishLaunchingWithOptions
applicationDidBecomeActive
Pressing home:
applicationWillResignActive
applicationDidEnterBackground
Coming back from home screen:
applicationWillEnterForeground
applicationDidBecomeActive
applicationWillTerminate is called when your application exits due to a call or the OS kills it for some reason.

iphone: applicationDidFinishLaunching method & iOS 4.0+

I currently have an iPhone application that makes a call to an API to obtain an Access Token.
This function is currently executed in my -applicationDidFinishLaunching method in the AppDelegate.m file.
However, with iOS4.0 and its ability to multitask, does this method get called each time the app is opened?
If not, is there a special delegate method that is called whenever the app is opened?
If your application is placed in the background, your delegate will receive the applicationDidEnterBackground message. If it is opened while still in the background, it will receive the applicationWillEnterForeground message, not the applicationDidFinishLaunching message.
You can read about the new application lifecycle transitions here.