// // PushHandler.swift // AIGrammar // // Created by oscar on 2024/8/31. // import UIKit import SwiftUI import UserNotifications enum PromotionDisplayType { case halfScreen case fullScreen case urlLink(String) // URL 链接,可以传递 URL 字符串 } class NofifyState: ObservableObject { @Published var selectedTab: Int = 0 @Published var showPromotion: Bool = false @Published var promotionMode: PromotionDisplayType = .halfScreen } class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate { // 保存 AIGrammarApp 的实例 var app: AIGrammarApp? var window: UIWindow? var rootView: ContentView? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 设置 UNUserNotificationCenter 的 delegate UNUserNotificationCenter.current().delegate = self // 注册推送通知 registerForPushNotifications() return true } func registerForPushNotifications() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in logger.info("Permission granted: \(granted)") guard granted else { return } self.getNotificationSettings() } } func getNotificationSettings() { UNUserNotificationCenter.current().getNotificationSettings { settings in logger.info("Notification settings: \(settings)") guard settings.authorizationStatus == .authorized else { return } DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() logger.info("Device Token: \(token)") // 你可以在此处将 token 发送到你的服务器 } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { logger.error("Failed to register: \(error)") } /* // 处理前台接收推送通知 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { logger.info("get push msg in willPresent") globalEnvironment.pushSettings.appAtFront = true //completionHandler([.sound, .banner]) } */ // 处理用户响应推送通知 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { logger.info("get push msg in didReceive") let userInfo = response.notification.request.content.userInfo // 解析相关的参数,保存到全局变量中。等用户唤起主界面后执行 globalEnvironment.pushSettings.gotoTab = extractValue(from: userInfo, key: "gotoTab", defaultValue: 0, logMessage: "gotoTab not found or invalid in userInfo") globalEnvironment.pushSettings.showPage = extractValue(from: userInfo, key: "showPage", defaultValue: 0, logMessage: "showPage not found or invalid in userInfo") != 0 globalEnvironment.pushSettings.page = extractValue(from: userInfo, key: "page", defaultValue: "", logMessage: "page not found or invalid in userInfo") globalEnvironment.pushSettings.showMode = extractValue(from: userInfo, key: "showMode", defaultValue: "", logMessage: "showMode not found or invalid in userInfo") globalEnvironment.pushSettings.openURL = extractValue(from: userInfo, key: "url", defaultValue: "", logMessage: "url not found or invalid in userInfo") // 如果推送过来的时候,已经在前台了,需要触发一下 if globalEnvironment.pushSettings.appAtFront { DispatchQueue.main.async { self.app?.handlePushNotification() } globalEnvironment.pushSettings.appAtFront = false } completionHandler() } // 解析 userInfo 的通用函数 func extractValue(from userInfo: [AnyHashable: Any], key: String, defaultValue: T, logMessage: String) -> T { if let value = userInfo[key] as? T { return value } else { logger.info(logMessage) return defaultValue } } } struct PromotionView: View { var body: some View { Text("This is the Promotion View") } }