处理系统的未读消息数逻辑

This commit is contained in:
anlicheng 2025-07-11 15:29:28 +08:00
parent fbd362f84e
commit 34a48116d2
3 changed files with 98 additions and 5 deletions

View File

@ -120,6 +120,31 @@ struct API {
return await doRequest(request: request, as: T.self)
}
//
static func getUserUnreadNum<T: Codable>(userId: String, as: T.Type) async -> APIResponse<T> {
let request = URLRequest(url: URL(string: baseUrl + "/api/get_unread_num?user_id=\(userId)")!)
return await doRequest(request: request, as: T.self)
}
static func updateUserUnreadNum<T: Codable>(userId: String, dramaId: Int, as: T.Type) async -> APIResponse<T> {
let request = URLRequest(url: URL(string: baseUrl + "/api/update_unread_num?user_id=\(userId)&drama_id=\(dramaId)")!)
return await doRequest(request: request, as: T.self)
}
static func resetUserUnreadNum<T: Codable>(userId: String, dramaIds: [Int], as: T.Type) async -> APIResponse<T> {
let jsonData = try! JSONSerialization.data(withJSONObject: ["drama_ids": dramaIds], options: [])
let url = URL(string: baseUrl + "/api/reset_unread_num?user_id=\(userId)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
return await doRequest(request: request, as: T.self)
}
// http
private static func doRequest<T: Codable>(request: URLRequest, as: T.Type) async -> APIResponse<T> {
do {

View File

@ -150,6 +150,8 @@ struct IndexMainView: View {
}
.task {
await self.indexModel.loadData(userId: self.userId)
}
}

View File

@ -14,6 +14,8 @@ struct dimensionhubApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject var appNav = AppNavigation.shared
private var userId: String
var sharedModelContainer: ModelContainer = {
let schema = Schema([
Item.self,
@ -33,11 +35,11 @@ struct dimensionhubApp: App {
}()
init() {
self.userId = KeychainHelper.getPersistentUserId()
//
UNUserNotificationCenter.current().delegate = appDelegate
let userId = KeychainHelper.getPersistentUserId()
print("user_id is: \(userId)")
print("user_id is: \(self.userId)")
}
var body: some Scene {
@ -60,6 +62,11 @@ struct dimensionhubApp: App {
withAnimation {
appNav.append(dest: .detail(id: dramaId))
}
Task {
await self.updateUserUnreadNum(userId: self.userId, dramaId: dramaId)
}
appNav.targetDetailId = 0
}
}
@ -67,13 +74,25 @@ struct dimensionhubApp: App {
}
.navigationViewStyle(.stack)
.tint(.black)
.environment(\.userId, KeychainHelper.getPersistentUserId())
.environment(\.userId, self.userId)
.environmentObject(appNav)
.preferredColorScheme(.light)
}
.modelContainer(sharedModelContainer)
}
private func updateUserUnreadNum(userId: String, dramaId: Int) async {
let response = await API.updateUserUnreadNum(userId: userId, dramaId: dramaId, as: Int.self)
switch response {
case .result(let newUnreadNum):
NSLog("updateUserUnreadNum success, new unread_num:\(newUnreadNum)")
Task {@MainActor in
try? await UNUserNotificationCenter.current().setBadgeCount(newUnreadNum)
}
case .error(let errorCode, let error):
NSLog("updateUserUnreadNum error: \(error), error_code: \(errorCode)")
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
@ -81,6 +100,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
Task.detached {
await self.registerForPushNotifications()
//
let unreadDramaIds = await self.getSystemUnreadDramaIds()
let userId = KeychainHelper.getPersistentUserId()
let response = await API.resetUserUnreadNum(userId: userId, dramaIds: unreadDramaIds, as: String.self)
switch response {
case .result(let result):
NSLog("reset user unread num result is: \(result)")
case .error(let errorCode, let message):
NSLog("reset user unread error_code: \(errorCode), message: \(message)")
}
Task {@MainActor in
do {
try await UNUserNotificationCenter.current().setBadgeCount(unreadDramaIds.count)
NSLog("UNUserNotificationCenter setBadgeCount num: \(unreadDramaIds.count)")
} catch let err {
NSLog("UNUserNotificationCenter setBadgeCount get error: \(err)")
}
}
}
return true
}
@ -108,6 +147,34 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
}
}
//
private func fetchUserUnreadCount() async -> Int? {
let userId = KeychainHelper.getPersistentUserId()
let response = await API.getUserUnreadNum(userId: userId, as: Int.self)
switch response {
case .result(let unreadNum):
return unreadNum
case .error(let errorCode, let error):
NSLog("fetchUserUnreadCount get error: \(error), code: \(errorCode)")
return nil
}
}
//
private func getSystemUnreadDramaIds() async -> [Int] {
let notifications = await UNUserNotificationCenter.current().deliveredNotifications()
let unreadDramaIds = notifications.flatMap { n -> [Int] in
let userInfo = n.request.content.userInfo
guard let customData = userInfo["custom_data"] as? [String: AnyObject],
let params = customData["params"] as? [String : AnyObject],
let dramaId = params["drama_id"] as? Int else {
return []
}
return [dramaId]
}
return unreadDramaIds
}
// deviceToken
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
@ -136,7 +203,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// App
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
completionHandler(.newData)
}