skip to Main Content

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


  1. The Apple docs state that for applicationWillTerminate

    "You should use this method to perform any final clean-up tasks for your app, such as freeing shared resources, saving user data, and invalidating timers. Your implementation of this method has approximately five seconds to perform any tasks and return."

    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

    Login or Signup to reply.
  2. 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.

     func sceneDidDisconnect(_ scene: UIScene) {
    // write your code here.
      }
    

    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.

    static let shared = AppDelegate()
    

    And after,
    in viewDidLoad() method.

    AppDelegate.shared.delegate = self
    

    The second option is to use NotificationCenter so, you don’t need to use the protocol delegate pattern.
    Add observer in viewDidLoad() method.

    override func viewDidLoad() {
      super.viewDidLoad()
      NotificationCenter.default.addObserver(self, selector: #selector(self.willTerminateNotification), name: UIApplication.willTerminateNotification, object: nil)
    }
    
    // This function will call when the application terminates.
    @objc private func willTerminateNotification() {
         
    }
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search