I am trying to make an API write to Firebase when my application force terminates by the user. I tried updating my info.plist to include "App does not run in foreground" to No and calling my method from func ApplicationWillEnterBackground within the AppDelegate file, but I have not had success either. In fact, I cannot get any print statements to register with that method. My print statements are registering under ApplicationWillTerminate but I am guessing the application instance is getting killed before the Firebase write can occur. Does anyone know the proper way to do this? Newbie here. Code below:
APP DELEGATE (DEFAULT METHODS NOT INCLUDED):
protocol ForcedOfflineDelegate {
func goOffline(_ AppDelegate: AppDelegate)
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var delegate: ForcedOfflineDelegate?
func applicationWillTerminate(_ application: UIApplication) {
self.delegate?.goOffline(self)
}
MY VIEW CONTROLLER:
class MyViewController: UIViewController, ForcedOfflineDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = AppDelegate()
appDelegate.delegate = self
}
func goOffline(_ AppDelegate: AppDelegate) {
// API Call to Firebase etc. etc.
}
}
2
Answers
The Apple docs state that for applicationWillTerminate
This means that if you are wanting to save information, or make that last call to firebase, you application has 5 seconds to do it from this route. If you need more time you can call
beginBackgroundTask(expirationHandler:)
The applicationDidEnterBackground method is used to prep the app to come back after going to the background.
To make that last minute post to firebase when the app is force closed, applicationWillTerminate is the one you want
Since iOS 13, Apple introduces SceneDelegate so, the AppDelegate method does not work so, you need to write the logic in the SceneDelegate file. If in project have SceneDelegate class file then use below method.
Also, If in your project does not have a SceneDelegate class file then in your code you are creating an AppDelegate instance in the view controller viewDidLoad() method this will not work. Use existing AppDelegate shared instance.
Create a shared instance in the AppDelegate file.
And after,
in viewDidLoad() method.
The second option is to use NotificationCenter so, you don’t need to use the protocol delegate pattern.
Add observer in viewDidLoad() method.
Note: And as per @Jwoodland answer use beginBackgroundTask(expirationHandler:) because when you call firebase API it will take time to perform this task so you need more time to update the offline status.