applicationWillEnterForeground never called - iphone

Hey there, I'm trying Multitasking in the Simulator (I only have a 2nd gen iPod and an iPad) and I'm still having some problems. My testing methods look like this:
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"Entering %s",__FUNCTION__);
if (enteredFromBackground) {
NSLog(#"Entering from Background");
enteredFromBackground = NO;
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(#"Entering %s",__FUNCTION__);
enteredFromBackground = YES;
}
Unforntunately, I'm not seeing the NSLog from applicationWillEnterForeground, that's why I added the line to show me something in applicationDidBecomeActive.
All I get is the
2010-11-20 15:58:12.796 iBeat[45997:207] Entering -[AppDelegate_Shared applicationDidEnterBackground:]
2010-11-20 15:58:18.160 iBeat[45997:207] Entering -[AppDelegate_Shared applicationDidBecomeActive:]

After having this problem in iOS 13, I found out that I was waiting for applicationWillEnterForeground(_ application: UIApplication) to be called instead of sceneWillEnterForeground(_ scene: UIScene).
For more information, read this answer:
enter link description here

Finally I found my problem!
Since I have a universal Application, I have an Appdelegate_Shared, an Appdelegate_iPhone, and an Appdelegate_iPad.
I had an empty implementation of "applicationWillEnterForeground" in the two subclasses but didn't call super!
And then I wondered why the method in Appdelegate_Shared never got called o.O

Related

Duplicate declaration of method 'application:didRegisterUserNotificationSettings:'

I am working on "react-native-firebase": "^5.5.6", and "react-native-push-notification": "^3.1.9", using react native and I am stuck with error Duplicate declaration of method 'application:didRegisterUserNotificationSettings:' on appDelegate.m
I have tried various solutions found over web and If I comment one of the method, I got error "native module cannot be null"
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings {
[[RNFirebaseMessaging instance]
didRegisterUserNotificationSettings:notificationSettings];
}
// Required to register for notifications
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings
{
[RCTPushNotificationManager
didRegisterUserNotificationSettings:notificationSettings];
}
I need both the methods in my code without any error. I can use if else or other solutions as well but as I am new to this technology, therefore any help will be appreciated.
Thanks in advance!
I would not recommend mixing features however try this:
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings {
[[RNFirebaseMessaging instance]
didRegisterUserNotificationSettings:notificationSettings];
[RCTPushNotificationManager
didRegisterUserNotificationSettings:notificationSettings];
}
So you initialize both, in the same method. Again, not sure why you need both and you should try to keep only one.

iOS - setIdleTimerDisabled:NO Not Working

I have an app that utilizes the video camera so the screen cannot dim. Inhibiting the screen from dimming works fine like so:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
However when the app is closed and enters the background, setting the IdleTimer back to NO is not working. The screen stays on forever on the home screen. This is how I am trying to accomplish this.
- (void)applicationWillResignActive:(UIApplication *)application
{
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
}
Is there a better place to add this line of code?
The same problem was occuring with me. Actually it does work but only works when your device is not connected to xCode. Try disconnecting the device and then test this functionality.
Why don't you try using your code in
applicationWillEnterForeground
delegegate method.
Hope that work's for you.
Swift version:
public func applicationWillResignActive(application: UIApplication) {
UIApplication.sharedApplication().idleTimerDisabled = false
}
public func applicationDidBecomeActive(application: UIApplication) {
UIApplication.sharedApplication().idleTimerDisabled = true
}

How to tell if leaving iOS app entered foreground from fast-app switching or manually?

Is there a way to tell if an iOS app enters the foreground from fast-app switching or manually? I need to know by the time applicationWillEnterForeground is called, so some specific code can be executed (or not executed) depending on the condition in which the app entered the foreground.
EDIT:
It turned out that this was more of a design issue for me. I moved my code to applicationDidBecomeActive. I also added a BOOL property to the appDelegate called fastAppSwitching (probably the wrong name for it). I set this to YES in application:handleOpenURL and application:openURL:sourceApplication:annotation. Then I added the following code to application:didFinishLaunchingWithOptions:
if (launchOptions) {
self.fastAppSwitching = YES;
}
else {
self.fastAppSwitching = NO;
}
In applicationDidBecomeActive, I used the following code:
if (fastAppSwitching == YES) {
self.fastAppSwitching = NO; //stop, don't go any further
}
else {
...
}
EDIT2: MaxGabriel makes a good point below: "Just a warning to others taking the solution described here, applicationDidBecomeActive: is called when the user e.g. ignores a phone call or text message, unlike applicationWillEnterForeground". This is actually also true for in-app purchases and Facebook in-app authorization (new in iOS 6). So, with some further testing, this is the current solution:
Add a new Bool called passedThroughWillEnterForeground.
In applicationWillResignActive:
self.passedThroughWillEnterForeground = NO;
In applicationDidEnterBackground:
self.passedThroughWillEnterForeground = NO;
In applicationWillEnterForeground:
self.passedThroughWillEnterForeground = YES;
In applicationDidBecomeActive:
if (passedThroughWillEnterForeground) {
//we are NOT returning from 6.0 (in-app) authorization dialog or in-app purchase dialog, etc
//do nothing with this BOOL - just reset it
self.passedThroughWillEnterForeground = NO;
}
else {
//we ARE returning from 6.0 (in-app) authorization dialog or in-app purchase dialog - IE
//This is the same as fast-app switching in our book, so let's keep it simple and use this to set that
self.fastAppSwitching = YES;
}
if (fastAppSwitching == YES) {
self.fastAppSwitching = NO;
}
else {
...
}
EDIT3: I think we also need a bool to tell if app was launched from terminated.
If your application is launched by another application, the
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
sourceApplicarion:(NSString *)bundleID
annotation:(id)info;
method is called on your app delegate. You can use this method to e. g. set a Boolean switch to true that indicates whether the app was launched by another program.
The peoblem is that this method is called after applicationWillEnterForeground:, so you can't tell in that method whether your app was launched manually or automatically.
However, I suspect that if you need this to be detected in a particular method, you may have a design problem and you should probably reorganize your code.
In the case where your app is opened from another app, application:openURL:sourceApplication:annotation will be called on your app delegate.

Iphone - UISwitch Turned Off On Exit

I want to set a switch to off when the app enters into background. I am trying to do it using the following code. It isn't working :( When I resume app the switch is still "on" on animation on the screen. How can I fix this?
- (void)applicationWillResignActive:(UIApplication *)application {
[registrationSwitch setOn:NO animated:YES];
}
You need to set the value in userDefaults. Add a boolean check like:
if (userDefaultBool == 1){
registrationSwitch setOn
}
else{
registration setOff
}
put that in your viewDidLoad

Implementing Testflight.com and Flurry.com exception handling

We are using both testflight.com sdk and flurry.com sdk to track unhandled exceptions. The issue is that no exceptions are picked up by flurry after we added the testflight.com sdk.
The method triggered when an unhandled exception occur looks like this:
void uncaughtExceptionHandler(NSException *exception)
{
[FlurryAnalytics logError:#"ERROR_NAME" message:#"ERROR_MESSAGE" exception:exception];
}
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if !TARGET_IPHONE_SIMULATOR
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
struct sigaction newSignalAction;
memset(&newSignalAction, 0, sizeof(newSignalAction));
newSignalAction.sa_handler = &signalHandler;
sigaction(SIGABRT, &newSignalAction, NULL);
sigaction(SIGILL, &newSignalAction, NULL);
sigaction(SIGBUS, &newSignalAction, NULL);
[FlurryAnalytics startSession:kFlurryKey];
[TestFlight takeOff:kTestflightKey];
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
#endif
.
.
.
I'm not sure how testflight.com does it, but it seems like they intercept the exception and register the data for themselves without letting the registered method be run?
Are there any way for both of these to coexist?
I got confirmation from the Testflightapp.com team that this is a known issue. They hope to fix in in the next version they said.
I'm not able to test this directly, but the TestFlight documentation seems to say this:
If you do use uncaught exception or signal handlers install your handlers before calling takeOff. Our SDK will then call your handler while ours is running.
They even give some example code which might help you get this working.
I have found a solution on a blog, not sure if it works for Flurry as well, what it says is to call UninstallCrashHandlers method (declared in TestFlight.h) twice after [TestFlight takeOff:#"KEY"] method, and then register other service for which you want to use for crash reporting. See example code for TestFlight vs Crashlytics
Disabling TestFlight’s crash reporting is quite simple. Add the following code your includes in AppDelegate.m:
...
#import TestFlight.h
// Function prototype for UninstallCrashHandler
extern void UninstallCrashHandlers(BOOL restore);
In didFinishLaunchingWithOptions call this method first with NO and then with YES, like:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[TestFlight takeOff:#"<TestFlightKey>"];
UninstallCrashHandlers(NO);
UninstallCrashHandlers(YES);
[Crashlytics startWithAPIKey:#"<CrashlyticsKey>"];
return YES;
}
ref: http://www.grahamdennis.me/blog/2012/10/21/how-to-disable-testflights-crash-handlers/