我的后台任务,按照苹果的文档实现,只运行一次或两次,而不是一个接一个地连续运行。寻求帮助解决此问题
AppDelegate
import UIKit
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let apiKey = "xxxxxxx" // jsonbin x-master-key
let timestampUserDefaultsKey = "Timestamps"
static let backgroundAppRefreshTaskSchedulerIdentifier = "com.process"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Register a background task
if #available(iOS 13.0, *) {
let status = BGTaskScheduler.shared.register(
forTaskWithIdentifier: AppDelegate.backgroundAppRefreshTaskSchedulerIdentifier, using: .global()) { task in
self.handleBackgroundTask(task: task as! BGProcessingTask)
}
print(status)
}
return true
}
func handleBackgroundTask(task: BGProcessingTask) {
self.scheduleAppRefresh()
task.expirationHandler = {
task.setTaskCompleted(success: false)
self.scheduleAppRefresh()
}
let backgroundQueue = DispatchQueue.global(qos: .background)
backgroundQueue.async {
self.postToJsonBin(prefix:"P-Background") { result in
switch result {
case .success(let responseJSON):
// Handle the success and responseJSON
print("Response JSON: \(responseJSON)")
task.setTaskCompleted(success: true)
case .failure(let error):
task.setTaskCompleted(success: false)
// Handle the error
print("Error: \(error.localizedDescription)")
}
}
}
}
func scheduleAppRefresh() {
if #available(iOS 13.0, *) {
let request = BGProcessingTaskRequest(identifier: AppDelegate.backgroundAppRefreshTaskSchedulerIdentifier)
// Fetch no earlier than 15 seconds from now.
request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 5) // 60 seconds
// request.requiresNetworkConnectivity = true
do {
try BGTaskScheduler.shared.submit(request)
print("bg App Refresh requested")
} catch {
print("Could not schedule app refresh: \(error)")
}
}
}
func postToJsonBin(prefix:String, completion: @escaping (Result<Any, Error>) -> Void) {
// Define the URL for jsonbin.io with the collection ID
let apiUrl = URL(string: "https://api.jsonbin.io/v3/b")!
// Define your JSON data including the timestamp parameter
let jsonData: [String: Any] = ["timestamp": Date().currentTimestampInIST(), "prefix":prefix]
do {
// Serialize the JSON data
let requestData = try JSONSerialization.data(withJSONObject: jsonData)
// Create the URLRequest
var request = URLRequest(url: apiUrl)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(apiKey, forHTTPHeaderField: "X-Master-Key") // Replace with your API key
request.setValue(prefix, forHTTPHeaderField: "X-Bin-Name")
// Set the HTTP body with the serialized JSON data
request.httpBody = requestData
// Create a URLSession task
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
if let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 {
if let responseData = data {
do {
// Parse the response data and call the completion handler
let responseJSON = try JSONSerialization.jsonObject(with: responseData, options: [])
completion(.success(responseJSON))
} catch {
completion(.failure(error))
}
}
} else {
completion(.failure(NSError(domain: "JsonBinErrorDomain", code: 0, userInfo: nil))) // Replace with appropriate error handling
}
}
// Start the URLSession task
task.resume()
} catch {
completion(.failure(error))
}
}
}
extension Date {
func currentTimestampInIST() -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(identifier: "Asia/Kolkata") // Set the time zone to IST
// Define your desired date format
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
// Get the current date and time
let currentDate = Date()
// Format the date as a string in IST
let istTimestamp = dateFormatter.string(from: currentDate)
return istTimestamp
}
}
场景委托
func sceneDidEnterBackground(_ scene: UIScene) {
if #available(iOS 13.0, *) {
let request = BGProcessingTaskRequest(identifier: AppDelegate.backgroundAppRefreshTaskSchedulerIdentifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 5 )
do {
try BGTaskScheduler.shared.submit(request)
print("bg App Refresh requested")
} catch {
print("Could not schedule app refresh: \(error)")
}
}
}
观察
以5分钟为最早开始时间间隔,观察18小时,观察到仅执行两次或有时仅执行一次。
我想要的
1.我希望后台任务能够连续执行,即使执行时间超过预期。
1.密码有问题吗?
1.如果这是正常行为,那么我如何才能达到第1点。
1条答案
按热度按时间vktxenjb1#
如果你希望后台任务每5分钟运行一次,你可以这样做:
通过后台推送唤醒应用
这确实需要大量的真实的工作来使APNS工作(请记住,静默后台通知 * 不是 * 本地通知)。
话虽如此,我认为您的方法对于您所描述的应用程序特性并不理想,我认为注解很好地解释了这一点。通过网络加载应用程序数据的视觉延迟是一个常见的问题,除了让本地后台任务进行轮询/数据拉取之外,还有很多方法可以解决这个问题。