添加未读消息的后台更新逻辑
This commit is contained in:
parent
ea022e56d3
commit
b0c89d9998
@ -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>
|
||||
|
||||
@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
// 转换成显示的元素信息
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user