diff --git a/dimensionhub/Info.plist b/dimensionhub/Info.plist
index fde08b1..6129aec 100644
--- a/dimensionhub/Info.plist
+++ b/dimensionhub/Info.plist
@@ -10,6 +10,11 @@
UIBackgroundModes
remote-notification
+ fetch
+ BGTaskSchedulerPermittedIdentifiers
+
+ com.jihe.dimensionhub.refresh
+
diff --git a/dimensionhub/Modifers/AutoDismissModifier.swift b/dimensionhub/Modifers/AutoDismissModifier.swift
index 9b6259e..933f7c2 100644
--- a/dimensionhub/Modifers/AutoDismissModifier.swift
+++ b/dimensionhub/Modifers/AutoDismissModifier.swift
@@ -8,28 +8,31 @@ import SwiftUI
// 自定义修饰符
extension View {
- func autoDismiss(after seconds: Double) -> some View {
- modifier(AutoDismissModifier(seconds: seconds))
+ func autoDismiss(isHidden: Binding, 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)")
+ }
}
+
}
diff --git a/dimensionhub/Views/Index/IndexMainView.swift b/dimensionhub/Views/Index/IndexMainView.swift
index 91a1573..b124c7a 100644
--- a/dimensionhub/Views/Index/IndexMainView.swift
+++ b/dimensionhub/Views/Index/IndexMainView.swift
@@ -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
diff --git a/dimensionhub/Views/Index/IndexModel.swift b/dimensionhub/Views/Index/IndexModel.swift
index 29459be..2dc2084 100644
--- a/dimensionhub/Views/Index/IndexModel.swift
+++ b/dimensionhub/Views/Index/IndexModel.swift
@@ -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
}
// 转换成显示的元素信息
diff --git a/dimensionhub/dimensionhubApp.swift b/dimensionhub/dimensionhubApp.swift
index 0c03712..6991fcc 100644
--- a/dimensionhub/dimensionhubApp.swift
+++ b/dimensionhub/dimensionhubApp.swift
@@ -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