• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

374
Views
Can I make an api call when the user terminates the app?

I need to make an API call when the user terminates the app (force close). The straight forward implementation I did is as below.

In the app delegate, I added the following code.

func applicationWillTerminate(_ application: UIApplication) {
    print("________TERMINATED___________")
    testAPICall()
}

func testAPICall(){
    let url = getURL()
    let contentHeader = ["Content-Type": "application/json"]
    Alamofire.request(url,
                  method: .put,
                  parameters: ["username": "abc@xyz.com"],
                  encoding: JSONEncoding.default,
                  headers: contentHeader).responseJSON { (response) -> Void in
                    print("-----")
                  }
}

However, the call is not being made. And on going through the documentation, I have found that I get only 5 seconds for completing the task in this method and above all, making api call is not a task to be done here. So I wonder, what would be the way to do this.

about 3 years ago · Santiago Trujillo
3 answers
Answer question

0

This is a two fold question

Phase 1: Ensuring API Call starts every time user terminates the app/ before it turns in active

You can always make use of expiration handler background mode of iOS application In your appdelegate

declare var bgTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0);

and in your appdelegate

 func applicationDidEnterBackground(_ application: UIApplication) {

    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    bgTask = application.beginBackgroundTask(withName:"MyBackgroundTask", expirationHandler: {() -> Void in
        // Do something to stop our background task or the app will be killed
        application.endBackgroundTask(self.bgTask)
        self.bgTask = UIBackgroundTaskIdentifier.invalid
    })

    DispatchQueue.global(qos: .background).async {
        //make your API call here
    }
    // Perform your background task here
    print("The task has started")
}

Background expiration handler will ensure you will get enough time to start your API call every time you put your application turns inactive or gets terminated

Phase 2: Ensuring API call started finishes successfully

Though expiration handler might ensure that you get enough time to start your API call it can't ensure the successful completion of API call. What if API call takes longer and while the request is in flight and time runs out??

The only way you to ensure that API call gets successful once started is to make sure to use proper configuration for URLSession

As per docs

Background sessions let you perform uploads and downloads of content in the background while your app isn't running.

link: https://developer.apple.com/documentation/foundation/nsurlsession?language=objc

So make use of Background session and use upload task. Rather than having a plain get/post API which you will hit with some parameter, ask your backend developer to accept a file and put all your param data in that file (if you have any) and start an upload task with background session.

Once the upload task starts with background session iOS will take care of its completion (unless u end up in a authentication challenge obviously) even after your app is killed.

This I believe is the closest you can get to ensure starting a API call and ensuring it finishes once app gets inactive/terminated. I kind a had a discussion with a apple developer regarding the same, and they agreed that this can be a probable solution :)

hope it helps

about 3 years ago · Santiago Trujillo Report

0

The main idea here is to make a sync call before app terminate

func applicationWillTerminate(_ application: UIApplication) {
        
     let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
     let request = NSMutableURLRequest(URL:url)
     let task = NSURLSession.sharedSession().dataTaskWithRequest(request, 
                     completionHandler: {
            taskData, _, error -> () in
            
            dispatch_semaphore_signal(semaphore);
      })
      task.resume()
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}

Tips:

A dispatch semaphore is an efficient implementation of a traditional counting semaphore. Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. If the calling semaphore does not need to block, no kernel call is made.

You increment a semaphore count by calling the signal() method, and decrement a semaphore count by calling wait() or one of its variants that specifies a timeout.

about 3 years ago · Santiago Trujillo Report

0

here is simple way to achieve this task-

func applicationWillTerminate(_ application: UIApplication) {
    
let sem = DispatchSemaphore(value: 0)
startSomethingAsync(completionHandler: {

sem.signal()//When task complete then signal will call
 })
sem.wait()//waiting until task complete
}
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error