如何通过 API 使用后台任务?
Posted
技术标签:
【中文标题】如何通过 API 使用后台任务?【英文标题】:How to use background task with API? 【发布时间】:2020-01-21 06:24:46 【问题描述】:我正在尝试使用后台任务访问 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.***.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.***.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】:您应该将任务调度程序标识符添加到 info.plist 文件。赞this
【讨论】:
以上是关于如何通过 API 使用后台任务?的主要内容,如果未能解决你的问题,请参考以下文章
如何确定我的后台任务将在生产中调用多少个 3rd 方 Web api 调用?