BackgroundTask iOS 13 Swift
Asked Answered
M

0

18

I want to run the function in the background. But I get an error. The error I received is

"nw_connection_receive_internal_block_invoke.

Why am I getting this problem? I'm trying it on an iOS 13 device. But I can't run the application in the background. I added a background run feature in Info.plist. I want to run the interator.tickTimer function in the background. But I'm getting an error. Does not work in the background. In the background, I want to periodically retrieve data from firebase.

import BackgroundTasks

  @available(iOS 13.0, *)
  extension AppDelegate {

      func cancelAllPandingBGTask() {
          BGTaskScheduler.shared.cancelAllTaskRequests()
      }

      func scheduleImageFetcher() {
          let request = BGProcessingTaskRequest(identifier: "....")
          request.requiresNetworkConnectivity = true // Need to true if your task need to network process. Defaults to false.
          request.requiresExternalPower = false
          request.earliestBeginDate = Date(timeIntervalSinceNow: 40)

          do {

              try BGTaskScheduler.shared.submit(request)
          } catch {
              print("Could not schedule image featch: \(error)")
          }
      }


      func handleAppRefreshTask(task: BGAppRefreshTask) {

          task.expirationHandler = {

          }
         DispatchQueue.main.async {

         let interator =  MainTableViewController()
         interator.tickTimer()


           }
          task.setTaskCompleted(success: true)
      }

      func handleImageFetcherTask(task: BGProcessingTask) {
          scheduleImageFetcher() // Recall

          //Todo Work
          task.expirationHandler = {

          }
          task.setTaskCompleted(success: true)

      }
  }
  xtension AppDelegate {

      func registerLocalNotification() {
          let notificationCenter = UNUserNotificationCenter.current()
          let options: UNAuthorizationOptions = [.alert, .sound, .badge]

          notificationCenter.requestAuthorization(options: options) {
              (didAllow, error) in
              if !didAllow {
                 // print("User has declined notifications")
              }
          }
      }

      func scheduleLocalNotification() {
          let notificationCenter = UNUserNotificationCenter.current()
          notificationCenter.getNotificationSettings { (settings) in
              if settings.authorizationStatus == .authorized {
                  self.fireNotification()
              }
          }
      }

      func fireNotification() {
          // Create Notification Content
          let notificationContent = UNMutableNotificationContent()

          // Configure Notification Content
          notificationContent.title = "Bg"
          notificationContent.body = "BG Notifications."

          // Add Trigger
          let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1.0, repeats: false)

          // Create Notification Request
          let notificationRequest = UNNotificationRequest(identifier: "local_notification", content: notificationContent, trigger: notificationTrigger)

          // Add Request to User Notification Center
          UNUserNotificationCenter.current().add(notificationRequest) { (error) in
              if let error = error {
                  print("Unable to Add Notification Request (\(error), \(error.localizedDescription))")
              }
          }
      }
  }
  @UIApplicationMain
  class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {

      var window: UIWindow?
   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if #available(iOS 13.0, *) {
              registerBackgroundTaks()
              registerLocalNotification()

          } else {
              // Fallback on earlier versions
          }

          return true
     }

      func applicationDidEnterBackground(_ application: UIApplication) {
          if #available(iOS 13.0, *) {
              cancelAllPandingBGTask()
                     scheduleImageFetcher()
          } else {
              // Fallback on earlier versions
          }

      }

      //MARK: Regiater BackGround Tasks
      @available(iOS 13.0, *)
      private func registerBackgroundTaks() {

          BGTaskScheduler.shared.register(forTaskWithIdentifier: "....-...", using: nil) { task in
              //This task is cast with processing request (BGProcessingTask)
              self.scheduleLocalNotification()

              self.handleImageFetcherTask(task: task as! BGProcessingTask)
          }   
      }

Markettamarkey answered 8/8, 2019 at 13:21 Comment(8)
Timers don't run in the background.Fizzy
Can't I call the function at regular intervals in the background? @FizzyDabney
If you're in the background you're not running. There is no need to call anything at regular intervals. You have not explained why you think you need to.Fizzy
In the background, I want to periodically retrieve data from firebase. @FizzyDabney
Well, you don't get to do that in an iOS app. And why would you need to? If you're in the background, the app is not showing. There is no interface. So what could there be for you to update? If you need occasional background updates, use the background refresh feature.Fizzy
Here's a sample from Apple regarding the new iOS 13 Background Tasks (which deprecates Background Refresh): developer.apple.com/documentation/backgroundtasks/…. There's a related 2019 WWDC video there about it. Check if the errors happen in the sample since could be debug entries in Xcode and might need a better way to test background tasks.Absorptance
Seems to be fixed in Xcode 11.1Caporetto
I don't know the details, but documentation says you can invoke a task with a background push notification developer.apple.com/documentation/usernotifications/…Kleeman

© 2022 - 2024 — McMap. All rights reserved.