Как использовать фоновую задачу с API? - PullRequest
0 голосов
/ 21 января 2020

Я пытаюсь запустить API с помощью фоновой задачи, но получаю следующее сообщение об ошибке:

Не удается завершить BackgroundTask: не существует фоновой задачи с идентификатором 3 (0x3), или она может иметь уже было закончено. Взлом UIApplicationEndBackgroundTaskError () для отладки.

Ниже приведен код, который я использую.

Я не знаю, где я ошибаюсь. Пожалуйста, помогите мне.

     {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        registerBackgroundTaks()
        registerLocalNotification()
        return true
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        cancelAllPandingBGTask()
        scheduleAppRefresh()
        scheduleImageFetcher()

    }

    //MARK: Regiater BackGround Tasks
    private func registerBackgroundTaks() {

        BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.SO.imagefetcher", using: nil) { task in
            //This task is cast with processing request (BGProcessingTask)
            self.scheduleLocalNotification()
            self.handleImageFetcherTask(task: task as! BGProcessingTask)
        }

        BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.SO.apprefresh", using: nil) { task in
            //This task is cast with processing request (BGAppRefreshTask)
            self.scheduleLocalNotification2()
            self.handleAppRefreshTask(task: task as! BGAppRefreshTask)
        }
    }
}

    extension AppDelegate {

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

    func scheduleImageFetcher() {
        let request = BGProcessingTaskRequest(identifier: "com.SO.imagefetcher")
        request.requiresNetworkConnectivity = true // Need to true if your task need to network process. Defaults to false.
        request.requiresExternalPower = true

        request.earliestBeginDate = Date(timeIntervalSinceNow: 1 * 60 ) // Featch Image Count after 1 minute.
        //Note :: EarliestBeginDate should not be set to too far into the future.
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule image featch: \(error)")
        }
    }

    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.SO.apprefresh")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 2 * 60) // App Refresh after 2 minute.
        //Note :: EarliestBeginDate should not be set to too far into the future.
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule app refresh: \(error)")
        }
    }

    func handleAppRefreshTask(task: BGAppRefreshTask) {
        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1

        let op = BlockOperation {
            self.runApi2(task: task)
        }

        task.expirationHandler = {
            //This Block call by System
            //Canle your all tak's & queues
            op.cancel()
        }
        scheduleLocalNotification()
        queue.addOperation(op)
    }

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


        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1

        let op = BlockOperation {
            self.runApi(task: task)
        }

        //Todo Work
        task.expirationHandler = {
            //This Block call by System
            //Canle your all tak's & queues
            op.cancel()
        }

        queue.addOperation(op)

    }

    func runApi(task: BGProcessingTask) {
        let url = URL(string: "http://www.stackoverflow.com")!

        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            guard let data = data else { return }
            print(String(data: data, encoding: .utf8)!)
            task.setTaskCompleted(success: true)
        }

        task.resume()
    }

    func runApi2(task: BGAppRefreshTask) {
        let url = URL(string: "http://www.stackoverflow.com")!

        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            guard let data = data else { return }
            print(String(data: data, encoding: .utf8)!)
            task.setTaskCompleted(success: true)
        }

        task.resume()
    }
}

    extension 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 scheduleLocalNotification2() {
        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.getNotificationSettings { (settings) in
            if settings.authorizationStatus == .authorized {
                self.fireNotification2()
            }
        }
    }

    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))")
            }
        }
    }

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

        // Configure Notification Content
        notificationContent.title = "processs"
        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))")
            }
        }
    }
}

1 Ответ

0 голосов
/ 24 января 2020

Вы должны добавить идентификаторы планировщика задач в файл info.plist. Как это

...