处理系统的未读消息数逻辑
This commit is contained in:
parent
fbd362f84e
commit
34a48116d2
@ -120,6 +120,31 @@ struct API {
|
|||||||
return await doRequest(request: request, as: T.self)
|
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请求
|
// 执行http请求
|
||||||
private static func doRequest<T: Codable>(request: URLRequest, as: T.Type) async -> APIResponse<T> {
|
private static func doRequest<T: Codable>(request: URLRequest, as: T.Type) async -> APIResponse<T> {
|
||||||
do {
|
do {
|
||||||
|
|||||||
@ -150,6 +150,8 @@ struct IndexMainView: View {
|
|||||||
}
|
}
|
||||||
.task {
|
.task {
|
||||||
await self.indexModel.loadData(userId: self.userId)
|
await self.indexModel.loadData(userId: self.userId)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@ struct dimensionhubApp: App {
|
|||||||
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||||
@StateObject var appNav = AppNavigation.shared
|
@StateObject var appNav = AppNavigation.shared
|
||||||
|
|
||||||
|
private var userId: String
|
||||||
|
|
||||||
var sharedModelContainer: ModelContainer = {
|
var sharedModelContainer: ModelContainer = {
|
||||||
let schema = Schema([
|
let schema = Schema([
|
||||||
Item.self,
|
Item.self,
|
||||||
@ -33,11 +35,11 @@ struct dimensionhubApp: App {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
self.userId = KeychainHelper.getPersistentUserId()
|
||||||
|
|
||||||
// 尽可能早设置代理对象
|
// 尽可能早设置代理对象
|
||||||
UNUserNotificationCenter.current().delegate = appDelegate
|
UNUserNotificationCenter.current().delegate = appDelegate
|
||||||
|
print("user_id is: \(self.userId)")
|
||||||
let userId = KeychainHelper.getPersistentUserId()
|
|
||||||
print("user_id is: \(userId)")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
@ -60,6 +62,11 @@ struct dimensionhubApp: App {
|
|||||||
withAnimation {
|
withAnimation {
|
||||||
appNav.append(dest: .detail(id: dramaId))
|
appNav.append(dest: .detail(id: dramaId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task {
|
||||||
|
await self.updateUserUnreadNum(userId: self.userId, dramaId: dramaId)
|
||||||
|
}
|
||||||
|
|
||||||
appNav.targetDetailId = 0
|
appNav.targetDetailId = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,13 +74,25 @@ struct dimensionhubApp: App {
|
|||||||
}
|
}
|
||||||
.navigationViewStyle(.stack)
|
.navigationViewStyle(.stack)
|
||||||
.tint(.black)
|
.tint(.black)
|
||||||
.environment(\.userId, KeychainHelper.getPersistentUserId())
|
.environment(\.userId, self.userId)
|
||||||
.environmentObject(appNav)
|
.environmentObject(appNav)
|
||||||
.preferredColorScheme(.light)
|
.preferredColorScheme(.light)
|
||||||
}
|
}
|
||||||
.modelContainer(sharedModelContainer)
|
.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 {
|
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 {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
Task.detached {
|
Task.detached {
|
||||||
await self.registerForPushNotifications()
|
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
|
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
|
// 成功注册远程通知,获取到 deviceToken
|
||||||
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
@ -136,7 +203,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||||||
|
|
||||||
// 收到远程通知(App 在前台)
|
// 收到远程通知(App 在前台)
|
||||||
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||||
|
|
||||||
completionHandler(.newData)
|
completionHandler(.newData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user