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.
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.
I have a method that I want to call not the first time the app launches from being not open at all, but whenever the app opens at all, whenever. So if the app is open, then the user closes it, but it is still running through multitasking, I want to the method to run when they resume the app as well.
applicationWillEnterForeground:
In iOS 4.0 and later, this method is called as part of the transition from the background to the active state. Specifically, it is not called when the application is launched for the first time -- which is what you are looking for.
- (void) applicationWillEnterForeground:(UIApplication *)application {
}
I'm developing an application for both iphone 3G and iPhone4,if i test my app in iPhone 4 everything works fine but if i test my app in iPhone 3G app works fine but if i click home button of my iPhone and soon if i click my app icon only splash screen shown and while showing splash screen only it is crashing if i wait for about 30 seconds after i close it is working, since in iPhone 4 it is having multitasking and more memory if i do the same process the app is not crashing.
I don't know what is the problem is this the problem of my code? or iPhone? or i need to handle any of appdelegate methods like
1.applicationDidBecomeActive:
2.applicationWillResignActive:
3.applicationDidEnterBackground:
4.applicationWillEnterForeground:
5.applicationDidFinishLaunching:
Any help is appreciated in advance.Thank You.
Make sure you are not doing any heavy processing in the following methods
applicationDidBecomeActive
applicationDidFinishLaunching
applicationWillEnterForeground
iOS will terminate your application if its taking time in the above methods, so keep these methods clean and do the processing in your RootViewController etc
I advise you using breakpoints during the following methods to know exactly what is happening in your program:
applicationDidBecomeActive
applicationDidEnterBackground
applicationDidFinishLaunching
viewDidUnload (and all previous methods just before the unloading of the
last view before you press your home button)
Allover your MainDelegate
Try making the application run in the background and see what happens.
Since the iPhone 3G is slower it is still closing your app when you try to start it again.
That it is not closed directly could be because you are doing some thing that take a lite longer then you would expect.
It is not really crashing, what you see it just the app closing it self. that is why if you try it after some second it will work.
Mainly these could be - (void)applicationWillTerminate:(UIApplication *)application or - (void)applicationDidEnterBackground:(UIApplication *)application.
Just make sure you exit you app as some a posible, by for example save any data before the user will close the app.
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.