feat(background): 增强iOS后台任务系统,添加processing任务类型支持

- 添加新的processing任务标识符到iOS配置文件
- 重构BackgroundTaskBridge支持不同任务类型(refresh/processing)
- 增强后台任务日志记录和调试信息
- 修复任务类型配置不匹配问题
- 改进任务调度逻辑和错误处理机制
- 添加任务执行时间戳记录用于调试
- 移除notification-settings中未使用的AuthGuard依赖
This commit is contained in:
richarjiang
2025-11-13 17:12:57 +08:00
parent 2dca3253e6
commit d282abd146
6 changed files with 129 additions and 26 deletions

View File

@@ -63,12 +63,25 @@ public class AppDelegate: ExpoAppDelegate {
forTaskWithIdentifier: identifier,
using: nil
) { [weak self] task in
NSLog("[AppDelegate] ✅ 后台任务被系统触发: \(identifier)")
// BackgroundTaskBridge
// bridge
self?.handleBackgroundTask(task, identifier: identifier)
}
NSLog("[AppDelegate] 后台任务已在应用启动时注册: \(identifier)")
// processing
let processingIdentifier = "com.anonymous.digitalpilates.processing"
BGTaskScheduler.shared.register(
forTaskWithIdentifier: processingIdentifier,
using: nil
) { [weak self] task in
NSLog("[AppDelegate] ✅ Processing 后台任务被系统触发: \(processingIdentifier)")
self?.handleBackgroundTask(task, identifier: processingIdentifier)
}
NSLog("[AppDelegate] Processing 后台任务已注册: \(processingIdentifier)")
}
@available(iOS 13.0, *)
@@ -76,11 +89,22 @@ public class AppDelegate: ExpoAppDelegate {
NSLog("[AppDelegate] ====== 后台任务被触发 ======")
NSLog("[AppDelegate] 任务标识符: \(identifier)")
NSLog("[AppDelegate] 任务类型: \(type(of: task))")
NSLog("[AppDelegate] 触发时间: \(Date().description)")
//
let defaults = UserDefaults.standard
defaults.set(Date().timeIntervalSince1970, forKey: "last_background_task_trigger")
NSLog("[AppDelegate] 已记录任务触发时间到UserDefaults")
// iOS 30
task.expirationHandler = {
task.expirationHandler = { [weak self] in
NSLog("[AppDelegate] ⚠️ 后台任务即将过期,强制完成")
task.setTaskCompleted(success: false)
//
if let strongSelf = self {
strongSelf.scheduleNextBackgroundTask(identifier: identifier)
}
}
// BackgroundTaskBridge
@@ -117,7 +141,9 @@ public class AppDelegate: ExpoAppDelegate {
@available(iOS 13.0, *)
private func executeBasicBackgroundMaintenance(task: BGTask, identifier: String) {
NSLog("[AppDelegate] 执行基本后台维护任务")
NSLog("[AppDelegate] ===== 执行基本后台维护任务 =====")
NSLog("[AppDelegate] 标识符: \(identifier)")
NSLog("[AppDelegate] 开始时间: \(Date().description)")
// 线
DispatchQueue.global(qos: .background).async {
@@ -139,9 +165,28 @@ public class AppDelegate: ExpoAppDelegate {
@available(iOS 13.0, *)
private func scheduleNextBackgroundTask(identifier: String) {
let request = BGAppRefreshTaskRequest(identifier: identifier)
// 15
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
NSLog("[AppDelegate] ===== 调度下一次后台任务 =====")
NSLog("[AppDelegate] 标识符: \(identifier)")
let request: BGTaskRequest
if identifier.contains("processing") {
request = BGProcessingTaskRequest(identifier: identifier)
if let processingRequest = request as? BGProcessingTaskRequest {
processingRequest.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
processingRequest.requiresNetworkConnectivity = false
processingRequest.requiresExternalPower = false
}
} else {
request = BGAppRefreshTaskRequest(identifier: identifier)
if let appRefreshRequest = request as? BGAppRefreshTaskRequest {
appRefreshRequest.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
}
}
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss"
let scheduledTime = formatter.string(from: Date(timeIntervalSinceNow: 15 * 60))
NSLog("[AppDelegate] 计划执行时间: \(scheduledTime)")
do {
try BGTaskScheduler.shared.submit(request)

View File

@@ -390,14 +390,27 @@ class BackgroundTaskBridge: RCTEventEmitter {
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: identifier)
NSLog("[BackgroundTaskBridge] 已取消之前的任务请求: \(identifier)")
// 使 BGAppRefreshTaskRequest BGProcessingTaskRequest
// BGAppRefreshTaskRequest
let request = BGAppRefreshTaskRequest(identifier: identifier)
//
// processing 使 BGProcessingTaskRequestfetch 使 BGAppRefreshTaskRequest
let request: BGTaskRequest
switch kind {
case .processing:
request = BGProcessingTaskRequest(identifier: identifier)
case .refresh:
request = BGAppRefreshTaskRequest(identifier: identifier)
}
//
//
//
request.earliestBeginDate = Date(timeIntervalSinceNow: delay)
if let appRefreshRequest = request as? BGAppRefreshTaskRequest {
appRefreshRequest.earliestBeginDate = Date(timeIntervalSinceNow: delay)
} else if let processingRequest = request as? BGProcessingTaskRequest {
processingRequest.earliestBeginDate = Date(timeIntervalSinceNow: delay)
processingRequest.requiresNetworkConnectivity = requiresNetworkConnectivity
processingRequest.requiresExternalPower = requiresExternalPower
}
do {
try BGTaskScheduler.shared.submit(request)
@@ -429,7 +442,10 @@ class BackgroundTaskBridge: RCTEventEmitter {
guard let self else { return }
self.currentTask = task
NSLog("[BackgroundTaskBridge] 开始处理后台任务: \(task.identifier)")
NSLog("[BackgroundTaskBridge] ===== 开始处理后台任务 =====")
NSLog("[BackgroundTaskBridge] 任务标识符: \(task.identifier)")
NSLog("[BackgroundTaskBridge] 任务类型: \(type(of: task))")
NSLog("[BackgroundTaskBridge] 当前时间: \(Date().description)")
if self.identifier == nil {
self.identifier = task.identifier
@@ -474,8 +490,10 @@ class BackgroundTaskBridge: RCTEventEmitter {
return
}
NSLog("[BackgroundTaskBridge] 发送后台任务执行事件到JS")
NSLog("[BackgroundTaskBridge] 准备发送后台任务执行事件到JS")
NSLog("[BackgroundTaskBridge] hasListeners: \(self.hasListeners)")
self.emitTaskToJS(payload: payload)
NSLog("[BackgroundTaskBridge] ✅ 事件已发送到JS层")
}
}
@@ -514,8 +532,22 @@ class BackgroundTaskBridge: RCTEventEmitter {
//
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: identifier)
let request = BGAppRefreshTaskRequest(identifier: identifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: self.defaultDelay)
// 使
let request: BGTaskRequest
switch self.kind {
case .processing:
request = BGProcessingTaskRequest(identifier: identifier)
if let processingRequest = request as? BGProcessingTaskRequest {
processingRequest.earliestBeginDate = Date(timeIntervalSinceNow: self.defaultDelay)
processingRequest.requiresNetworkConnectivity = self.requiresNetworkConnectivity
processingRequest.requiresExternalPower = self.requiresExternalPower
}
case .refresh:
request = BGAppRefreshTaskRequest(identifier: identifier)
if let appRefreshRequest = request as? BGAppRefreshTaskRequest {
appRefreshRequest.earliestBeginDate = Date(timeIntervalSinceNow: self.defaultDelay)
}
}
do {
try BGTaskScheduler.shared.submit(request)
@@ -542,11 +574,14 @@ class BackgroundTaskBridge: RCTEventEmitter {
pendingTaskTimeoutWorkItem?.cancel()
NSLog("[BackgroundTaskBridge] 缓存后台任务等待JS监听器...")
NSLog("[BackgroundTaskBridge] 等待超时时间: \(Int(pendingTaskWaitTimeout))")
let timeoutItem = DispatchWorkItem { [weak self] in
guard let self else { return }
guard self.waitingForJSListeners else { return }
NSLog("[BackgroundTaskBridge] 等待 JS 监听器超时,执行默认处理")
NSLog("[BackgroundTaskBridge] ⚠️ 等待 JS 监听器超时,执行默认处理")
self.waitingForJSListeners = false
self.pendingTaskPayload = nil
self.pendingTaskTimeoutWorkItem = nil
@@ -555,6 +590,7 @@ class BackgroundTaskBridge: RCTEventEmitter {
pendingTaskTimeoutWorkItem = timeoutItem
queue.asyncAfter(deadline: .now() + pendingTaskWaitTimeout, execute: timeoutItem)
NSLog("[BackgroundTaskBridge] 已设置超时计时器")
}
private func emitPendingTaskIfPossible() {
@@ -573,10 +609,12 @@ class BackgroundTaskBridge: RCTEventEmitter {
private func emitTaskToJS(payload: [String: Any]) {
DispatchQueue.main.async { [weak self] in
guard let self else { return }
NSLog("[BackgroundTaskBridge] 正在发送事件到JS层...")
self.sendEvent(
withName: "BackgroundTaskBridge.execute",
body: payload
)
NSLog("[BackgroundTaskBridge] ✅ 事件发送成功")
}
}
}

View File

@@ -6,6 +6,7 @@
<array>
<string>com.expo.modules.backgroundtask.processing</string>
<string>com.anonymous.digitalpilates.task</string>
<string>com.anonymous.digitalpilates.processing</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
@@ -26,7 +27,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0.24</string>
<string>1.0.25</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>