applicationShouldTerminate called unexpectedly in macOS Swift app - swift

Many people appear to have a problem where their AppDelegate's applicationShouldTerminate is never called. I have the opposite problem!
Often (at a guess 20% of the time) when I come back to my Mac in the morning, I discover that something caused my app's applicationShouldTerminate to fire. My app then ran its cleanup code, after which applicationWillTerminate fired. However the app never shut down — it's still marked as running in my dock, and when I click on it there, applicationDidFinishLaunching fires and it starts up. Because it was already running, the dock icon does not bounce.
The logs indicate this seems to only happen when I wrap up for the day and my Mac goes to sleep, possibly only after having been plugged back in after running off its battery.
At first I thought it might be because my Mac was trying to shutdown apps to install a system update but this happens even when there are no updates available. And no other apps on my system have the issue.
The same happens with my app on a friend's Mac.
I do have a "tricky" applicationShouldTerminate to get around run loop issues (nb. I'm using Promises):
var shuttingDown: Bool = false
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
log.debug("applicationShouldTerminate")
if shuttingDown { return .terminateNow }
shuttingDown = true
StuffController.shared.terminateRunningStuff()
.timeout(20) // If it hasn't shutdown within 20 seconds, force it.
.always {
// Tell the app it should now actually terminate.
NSApplication.shared.terminate(self)
}
return .terminateCancel
}
Can anyone suggest a reason my applicationShouldTerminate is firing without the user asking it to quit?

Turns out this is a feature not a bug (lol). In Mac OS X Lion (10.7) Apple introduced a feature called "Automatic Termination" where apps would automatically quit after a while of inactivity.
Note that this is intended to be invisible to the end-user; the app appears to be running in the dock, and should restore itself when needed, as if nothing ever happened.
It can be enabled or disabled via the "Application can be killed to reclaim memory or other extraordinary circumstances" configuration in Xcode (the NSSupportsAutomaticTermination key in an app's Info.plist).

Related

How do I prevent my app from running in the "recent menu" on Android 12

Android 12 introduced the behavior where the last app you had active are continuing to run when inside the recent menu. I'm wondering if there's a flag or something to put in AndroidManifest file to prevent this behavior as it's conflicting with some logics in our app (which works fine for Android < 12). I've googled but it's hard to find unless you know exactly what this "feature" is called.
Steps:
Start app
Open recent menu
Observe that you can interact and that the app is still running as if you had it open/active
Why is this a problem? Because a user is now able to force quit the app (swiping it away) without entering the "paused" state in our game (using Unity) meaning some save logic won't run.
This can be worked around in one way or another, but for now I would like to just pause the app in recent menu if possible (our app has zero reason for being active in recent menu).
EDIT:
As #WyattL mentioned in his answer, android:excludeFromRecents="true" might work, but it will cause drop in playtime and retention of the game and would prefer to have a more proper solution to this "unnecessary" feature of Android 12.
I can't be sure without testing on every phone as it seems the issue varies by device (thanks Ruzihm), but if opening the Recent Apps screen generates an OnApplicationFocus() call, this would provide a solution.
In an active MonoBehaviour:
private void OnApplicationFocus( bool focus )
{
if( focus ) {
UnpauseLogic();
}
else {
PauseLogic();
SaveLogic();
}
}
(It might also be worth trying OnApplicationQuit() in case it's called on specific devices during a swipe termination, but in my own tests it was never called.)
According to some brief research, did you try adding
<activity>
...
android:excludeFromRecents="true"
android:label=""
...
</activity>
to the AndroidManifest.xml?

Minimized macOS application + distributedNotificationCenter (background mode on macOS)

I've implemented a macOS app + extension.
The extension might send notifications to the app via DistributedNotificationCenter.default() and postNotificationName(_ name: ...).
The questions is regarding to the app life cycle on macOS - what happens if the user minimized the app, and the extension (which is running) sends a notification with the 'deliverImmediately' flag.
Will the app be able to handle it, even while minimized? If no, any other way to achieve this behavior?
P.S - I didn't find anything at the documentation, and when trying to check what happens, sometimes the app got the notification, and sometime it didn't..so asking to check what is the expected behavior.
The app isn't paused while minimized. Being minimized is a state of NSWindow not NSApplication. The app's run loop still executes, perhaps less frequently, and of course, the window won't be receiving any keyboard or mouse events while minimized, but the app will still be able to process notifications, AppleEvents, network or file I/O, etc... You may need to "un"minimize if the notification involves user interaction in the minimized window with NSWindow.deminiaturize(_ sender: Any?).
If the app is hidden it also still runs, and you'll want to activate it with NSApplication.activate(_ sender: Any?) to do any UI.

How to exit app and return to home screen in iOS 8 using Swift programming

I'm trying to programmatically return to the home screen in an iOS8 App using Swift. I want to continue the application running in the background though. Any ideas on how to do this?
Thanks in advance for the help.
When an app is launched, the system calls the UIApplicationMain function; among its other tasks, this function creates a singleton UIApplication object. Thereafter you access the object by calling the sharedApplication class method.
To exit gracefully (the iOS developer library explicitly warns you not to use exit(0) because this is logged as a crash ) you can use:
UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
For example, my app exits when the user shakes the device. So, in ViewController.swift:
override func motionEnded(motion: UIEventSubtype,
withEvent event: UIEvent?) {
if motion == .MotionShake{
//Comment: to terminate app, do not use exit(0) bc that is logged as a crash.
UIControl().sendAction(Selector("suspend"), to: UIApplication.sharedApplication(), forEvent: nil)
}}
Swift 4:
UIControl().sendAction(#selector(NSXPCConnection.suspend),
to: UIApplication.shared, for: nil)
Edit: It's worth mentioning that in iOS 12 there's a bug that will prevent network connectivity if the app is brought back from background after sending the suspend action.
For that you should use following code
import Darwin
exit(0)
To force your app into the background, you can legally launch another app, such as Safari, via a URL, into the foreground.
See: how to open an URL in Swift3
UIApplication.shared.open() (and the older openURL) are a documented public APIs.
If you set the exits-on-suspend plist key, opening another app via URL will also kill your app. The use of this key is a documented legal use of app plist keys, available for any app to "legally" use.
Also, if your app, for some impolite reason, continues to allocate and dirty large amounts of memory in the background, without responding to memory warnings, the OS will very likely kill it.
How about setting of info.plist?
You can set "Application does not run in background" true in info.plist with editor.
Or Add this lines with code editor.
<key>UIApplicationExitsOnSuspend</key>
<true/>
There is no way to "programmatically return to the home screen" except for crashing, exiting your program or calling unofficial API. Neither is welcome by Apple. Plus the Human Interface Guidelines are also covering this.

My app not geting terminated after pressing the home button

i am developing a ebook reader and i am facing the following issue. if i close the app and reopen , then it opens exactly in the same state as it used to be before closing. I suspect this may lead to a lot memory leaks. Is this the right way for the app to function? and will this behavior cause any memory leaks?? can anyone help me with this... I dint know what title to put on top.. Please apologize me if the title was misleading.. thank you.
This is the expected behavior. After the introduction of iOS4, applications will keep their state between launches. Applications get terminated when the system is running low on memory, as the system terminates applications not recently used to free memory. This will not lead to memory leaks. For users running iOS3 pressing Home will terminate the application.
See Understanding an Application’s States and Transitions and Multitasking for more information.
right appropriate code in delegate file
-(void)applicationDidEnterBackground:(UIApplication *)application
{//exit(0);
}
if nothing works write exit(0) in this method.
You can add the BOOL key: "Application does not run in background" to your info.plist and set it to YES. Then your app should be terminated when you press the home button.

When i kill the application in multitasking bar,and run the program it's goes to same state where i was closing the app

Today i updated my 3GS i-phone to install my application to see it's functioning well in OS4,when i'm running the application and tap the home button it's goes to multitasking bar,then again i get the application from there it's goes to previous state where i was.i think the behavior is OK. but problem comes when i kill the application in multitasking bar and run it it's come to same state,simply it's ignore the login screen.
My question is when i kill the application i want to get my login screen, not the previous state, this application is working fine in 3GS,can some one please help me to fix this issue?
Thanks
Sam.
Sam,
If you don't want the OS to save state for you, you should place the key UIApplicationExitsOnSuspend in your info.plist file.
More information here: http://developer.apple.com/iphone/library/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW23
This will kill the app when the home button is pressed, instead of suspending it into the background (which is what iOS4 does for multi-tasking).