添加未读消息的后台更新逻辑

This commit is contained in:
anlicheng 2025-07-29 18:10:06 +08:00
parent ea022e56d3
commit b0c89d9998
5 changed files with 87 additions and 25 deletions

View File

@ -10,6 +10,11 @@
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
<string>fetch</string>
</array>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.jihe.dimensionhub.refresh</string>
</array>
</dict>
</plist>

View File

@ -8,28 +8,31 @@ import SwiftUI
//
extension View {
func autoDismiss(after seconds: Double) -> some View {
modifier(AutoDismissModifier(seconds: seconds))
func autoDismiss(isHidden: Binding<Bool>, after seconds: Double) -> some View {
modifier(AutoDismissModifier(isHidden: isHidden, seconds: seconds))
}
}
struct AutoDismissModifier: ViewModifier {
@Binding var isHidden: Bool
let seconds: Double
@State private var isVisible = true
func body(content: Content) -> some View {
if isVisible {
content
.onAppear {
Task {
try? await Task.sleep(for: .seconds(seconds))
withAnimation(.easeOut) {
isVisible = false
}
content
.opacity(isHidden ? 0 : 1)
.frame(height: isHidden ? 0 : nil)
.onAppear {
Task {
print("call me task: \(isHidden)")
try? await Task.sleep(for: .seconds(seconds))
withAnimation(.easeOut) {
isHidden = true
}
}
} else {
EmptyView()
}
}
.onChange(of: isHidden) { oldValue, newValue in
print("curernt value is: \(isHidden)")
}
}
}

View File

@ -25,7 +25,7 @@ struct IndexMainView: View {
@State private var showDateNavPopover: Bool = false
//
@State private var noMoreNewest: Bool = false
@State private var hasMoreNewest: Bool = true
@State private var hasMoreOldest: Bool = false
//
@ -72,10 +72,15 @@ struct IndexMainView: View {
ScrollView(.vertical, showsIndicators: false) {
ScrollViewOffsetReader(offset: $scrollOffset)
if noMoreNewest {
if !hasMoreNewest {
Text("没有了")
.foregroundColor(.black)
.autoDismiss(after: 1.5)
.task {
try? await Task.sleep(for: .seconds(1.5))
withAnimation(.easeOut) {
hasMoreNewest = true
}
}
}
MixGroupLabelView(fixedDramaGroup: indexModel.fixedDramaGroup) {
@ -125,15 +130,13 @@ struct IndexMainView: View {
//
self.headerRefreshing = true
self.noMoreNewest = false
Task { @MainActor in
await self.indexModel.loadPrevUpdateDramasTask(userId: self.userId) { hasData in
let loadNum = await self.indexModel.loadPrevUpdateDramasTask(userId: self.userId) { _ in
DispatchQueue.main.async {
self.headerRefreshing = false
self.noMoreNewest = !hasData
}
}
self.hasMoreNewest = loadNum > 3
}
}
.onChange(of: scrollID) { _, newValue in
@ -174,7 +177,7 @@ struct IndexMainView: View {
return
}
Task { @MainActor in
let task = Task { @MainActor in
let num = await indexModel.loadMoreUpdateDramasTask(userId: self.userId)
if num > 3 {
self.hasMoreOldest = true

View File

@ -262,13 +262,15 @@ final class IndexModel {
return loadNum
}
func loadPrevUpdateDramasTask(userId: String, callback: (Bool) -> Void) async {
func loadPrevUpdateDramasTask(userId: String, callback: (Bool) -> Void) async -> Int {
guard !self.isMoreLoading else {
return
return 0
}
// id
let dramaIds = self.getDramaIds(self.updateDramaGroups)
var loadNum: Int = 0
// id
if let firstId = dramaIds.first {
self.isMoreLoading = true
@ -283,6 +285,9 @@ final class IndexModel {
self.dramaGroupElements = transformUpdateDramaGroups(groups: self.updateDramaGroups)
displayDramaGroups(self.updateDramaGroups, label: "after")
loadNum = groups.reduce(0, { acc, group in acc + group.items.count })
//
callback(true)
} else {
@ -293,6 +298,8 @@ final class IndexModel {
}
self.isMoreLoading = false
}
return loadNum
}
//

View File

@ -8,6 +8,7 @@
import SwiftUI
import SwiftData
import Observation
import BackgroundTasks
@main
struct dimensionhubApp: App {
@ -97,7 +98,14 @@ struct dimensionhubApp: App {
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
let taskId = "com.jihe.dimensionhub.refresh"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: taskId, using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
Task.detached {
await self.registerForPushNotifications()
@ -124,6 +132,42 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
return true
}
private func handleAppRefresh(task: BGAppRefreshTask) {
self.scheduleAppRefresh()
task.expirationHandler = {
//
task.setTaskCompleted(success: false)
}
Task {@MainActor in
if let unreadNum = await self.fetchUserUnreadCount(), unreadNum > 0 {
do {
try await UNUserNotificationCenter.current().setBadgeCount(unreadNum)
task.setTaskCompleted(success: true)
NSLog("Refresh setBadgeCount num: \(unreadNum)")
} catch let err {
NSLog("Refresh setBadgeCount get error: \(err)")
task.setTaskCompleted(success: false)
}
} else {
task.setTaskCompleted(success: false)
}
}
}
private func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: taskId)
// 1-4
request.earliestBeginDate = Date(timeIntervalSinceNow: 900)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
NSLog("无法安排后台任务: \(error.localizedDescription)")
}
}
private func registerForPushNotifications() {
//
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {granted, error in