游戏陪玩平台源码开发,关于本地通知推送实现的详细解析
游戏陪玩平台源码开发,关于本地通知推送实现的详细解析
游戏陪玩平台源码开发也是需要实现推送功能的,这样用户就能在第一时间了解平台消息以及好友发送的消息。这虽然只是一个小的方面,但却有着不容忽视的作用。今天我们主要了解一下利用系统的原生推送类结合工程实践如何实现游戏陪玩平台源码系统推送的集成,希望我的讲解能让大家很清楚的理解它。
源码
1. Swift
首先看下工程组织结构
下面就是源码啦
1. TaskManager.swift
import Foundationclass TaskManager: ObservableObject { static let shared = TaskManager() let taskPersistenceManager = TaskPersistenceManager() @Published var tasks: [Task] = [] init() { loadTasks() } func save(task: Task) { tasks.append(task) DispatchQueue.global().async { self.taskPersistenceManager.save(tasks: self.tasks) } if task.reminderEnabled { NotificationManager.shared.scheduleNotification(task: task) } } func loadTasks() { self.tasks = taskPersistenceManager.loadTasks() } func addNewTask(_ taskName: String, _ reminder: Reminder?) { if let reminder = reminder { save(task: Task(name: taskName, reminderEnabled: true, reminder: reminder)) } else { save(task: Task(name: taskName, reminderEnabled: false, reminder: Reminder())) } } func remove(task: Task) { tasks.removeAll { $0.id == task.id } DispatchQueue.global().async { self.taskPersistenceManager.save(tasks: self.tasks) } if task.reminderEnabled { NotificationManager.shared.removeScheduledNotification(task: task) } } func markTaskComplete(task: Task) { if let row = tasks.firstIndex(where: { $0.id == task.id }) { var updatedTask = task updatedTask.completed = true tasks[row] = updatedTask } } }
2. NotificationManager.swift
import Foundationimport UserNotificationsimport CoreLocationenum NotificationManagerConstants { static let timeBasedNotificationThreadId = "TimeBasedNotificationThreadId" static let calendarBasedNotificationThreadId = "CalendarBasedNotificationThreadId" static let locationBasedNotificationThreadId = "LocationBasedNotificationThreadId"}class NotificationManager: ObservableObject { static let shared = NotificationManager() @Published var settings: UNNotificationSettings? func requestAuthorization(completion: @escaping (Bool) -> Void) { UNUserNotificationCenter.current() .requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in self.fetchNotificationSettings() completion(granted) } } func fetchNotificationSettings() { // 1 UNUserNotificationCenter.current().getNotificationSettings { settings in // 2 DispatchQueue.main.async { self.settings = settings } } } func removeScheduledNotification(task: Task) { UNUserNotificationCenter.current() .removePendingNotificationRequests(withIdentifiers: [task.id]) } // 1 func scheduleNotification(task: Task) { // 2 let content = UNMutableNotificationContent() content.title = task.name content.body = "Gentle reminder for your task!" content.categoryIdentifier = "OrganizerPlusCategory" let taskData = try? JSONEncoder().encode(task) if let taskData = taskData { content.userInfo = ["Task": taskData] } // 3 var trigger: UNNotificationTrigger? switch task.reminder.reminderType { case .time: if let timeInterval = task.reminder.timeInterval { trigger = UNTimeIntervalNotificationTrigger( timeInterval: timeInterval, repeats: task.reminder.repeats) } content.threadIdentifier = NotificationManagerConstants.timeBasedNotificationThreadId case .calendar: if let date = task.reminder.date { trigger = UNCalendarNotificationTrigger( dateMatching: Calendar.current.dateComponents( [.day, .month, .year, .hour, .minute], from: date), repeats: task.reminder.repeats) } content.threadIdentifier = NotificationManagerConstants.calendarBasedNotificationThreadId case .location: // 1 guard CLLocationManager().authorizationStatus == .authorizedWhenInUse else { return } // 2 if let location = task.reminder.location { // 3 let center = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude) let region = CLCircularRegion(center: center, radius: location.radius, identifier: task.id) trigger = UNLocationNotificationTrigger(region: region, repeats: task.reminder.repeats) } content.threadIdentifier = NotificationManagerConstants.locationBasedNotificationThreadId } // 4 if let trigger = trigger { let request = UNNotificationRequest( identifier: task.id, content: content, trigger: trigger) // 5 UNUserNotificationCenter.current().add(request) { error in if let error = error { print(error) } } } } }
3. TaskPersistenceManager.swift
import Foundationclass TaskPersistenceManager { enum FileConstants { static let tasksFileName = "tasks.json" } func save(tasks: [Task]) { do { let documentsDirectory = getDocumentsDirectory() let storageURL = documentsDirectory.appendingPathComponent(FileConstants.tasksFileName) let tasksData = try JSONEncoder().encode(tasks) do { try tasksData.write(to: storageURL) } catch { print("Couldn't write to File Storage") } } catch { print("Couldn't encode tasks data") } } func loadTasks() -> [Task] { let documentsDirectory = getDocumentsDirectory() let storageURL = documentsDirectory.appendingPathComponent(FileConstants.tasksFileName) guard let taskData = try? Data(contentsOf: storageURL), let tasks = try? JSONDecoder().decode([Task].self, from: taskData) else { return [] } return tasks } func getDocumentsDirectory() -> URL { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return paths[0] } }
4. LocationManager.swift
import CoreLocationclass LocationManager: NSObject, ObservableObject { var locationManager = CLLocationManager() @Published var authorized = false override init() { super.init() locationManager.delegate = self if locationManager.authorizationStatus == .authorizedWhenInUse { authorized = true locationManager.startMonitoringSignificantLocationChanges() } } func requestAuthorization() { locationManager.requestWhenInUseAuthorization() } }// MARK: - CLLocationManagerDelegateextension LocationManager: CLLocationManagerDelegate { func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { if locationManager.authorizationStatus == .authorizedWhenInUse || locationManager.authorizationStatus == .authorizedAlways { authorized = true } else { authorized = false } } }`
5. TaskListView.swift
import SwiftUIstruct TaskListView: View { @ObservedObject var taskManager = TaskManager.shared @State var showNotificationSettingsUI = false var body: some View { ZStack { VStack { HStack { Spacer() Text("Organizer Plus") .font(.title) .foregroundColor(.pink) Spacer() Button( action: { // 1 NotificationManager.shared.requestAuthorization { granted in // 2 if granted { showNotificationSettingsUI = true } } }, label: { Image(systemName: "bell") .font(.title) .accentColor(.pink) }) .padding(.trailing) .sheet(isPresented: $showNotificationSettingsUI) { NotificationSettingsView() } } .padding() if taskManager.tasks.isEmpty { Spacer() Text("No Tasks!") .foregroundColor(.pink) .font(.title3) Spacer() } else { List(taskManager.tasks) { task in TaskCell(task: task) } .padding() } } AddTaskView() } } }struct ContentView_Previews: PreviewProvider { static var previews: some View { TaskListView() } }struct TaskCell: View { var task: Task var body: some View { HStack { Button( action: { TaskManager.shared.markTaskComplete(task: task) DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { TaskManager.shared.remove(task: task) } }, label: { Image(systemName: task.completed ? "checkmark.circle.fill" : "circle") .resizable() .frame(width: 20, height: 20) .accentColor(.pink) }) if task.completed { Text(task.name) .strikethrough() .foregroundColor(.pink) } else { Text(task.name) .foregroundColor(.pink) } } } }struct AddTaskView: View { @State var showCreateTaskView = false var body: some View { VStack { Spacer() HStack { Spacer() Button( action: { showCreateTaskView = true }, label: { Text("+") .font(.largeTitle) .multilineTextAlignment(.center) .frame(width: 30, height: 30) .foregroundColor(Color.white) .padding() }) .background(Color.pink) .cornerRadius(40) .padding() .sheet(isPresented: $showCreateTaskView) { CreateTaskView() } } .padding(.bottom) } } }
6. CreateTaskView.swift
import SwiftUIimport MapKit struct CreateTaskView: View { @State var taskName: String = "" @State var reminderEnabled = false @State var selectedTrigger = ReminderType.time @State var timeDurationIndex: Int = 0 @State private var dateTrigger = Date() @State private var shouldRepeat = false @State private var latitude: String = "" @State private var longitude: String = "" @State private var radius: String = "" @Environment(\.presentationMode) var presentationMode let triggers = ["Time", "Calendar", "Location"] let timeDurations: [Int] = Array(1...59) var body: some View { NavigationView { Form { Section { HStack { Spacer() Text("Add Task") .font(.title) .padding() Spacer() Button("Save") { TaskManager.shared.addNewTask(taskName, makeReminder()) presentationMode.wrappedValue.dismiss() } .disabled(taskName.isEmpty ? true : false) .padding() } VStack { TextField("Enter name for the task", text: $taskName) .padding(.vertical) Toggle(isOn: $reminderEnabled) { Text("Add Reminder") } .padding(.vertical) if reminderEnabled { ReminderView( selectedTrigger: $selectedTrigger, timeDurationIndex: $timeDurationIndex, triggerDate: $dateTrigger, shouldRepeat: $shouldRepeat, latitude: $latitude, longitude: $longitude, radius: $radius) .navigationBarHidden(true) .navigationTitle("") } Spacer() } .padding() } } .navigationBarTitle("") .navigationBarHidden(true) } } func makeReminder() -> Reminder? { guard reminderEnabled else { return nil } var reminder = Reminder() reminder.reminderType = selectedTrigger switch selectedTrigger { case .time: reminder.timeInterval = TimeInterval(timeDurations[timeDurationIndex] * 60) case .calendar: reminder.date = dateTrigger case .location: if let latitude = Double(latitude), let longitude = Double(longitude), let radius = Double(radius) { reminder.location = LocationReminder( latitude: latitude, longitude: longitude, radius: radius) } } reminder.repeats = shouldRepeat return reminder } } struct CreateTaskView_Previews: PreviewProvider { static var previews: some View { CreateTaskView() } } struct ReminderView: View { @Binding var selectedTrigger: ReminderType @Binding var timeDurationIndex: Int @Binding var triggerDate: Date @Binding var shouldRepeat: Bool @Binding var latitude: String @Binding var longitude: String @Binding var radius: String @StateObject var locationManager = LocationManager() var body: some View { VStack { Picker("Notification Trigger", selection: $selectedTrigger) { Text("Time").tag(ReminderType.time) Text("Date").tag(ReminderType.calendar) Text("Location").tag(ReminderType.location) } .pickerStyle(SegmentedPickerStyle()) .padding(.vertical) if selectedTrigger == ReminderType.time { Picker("Time Interval", selection: $timeDurationIndex) { ForEach(1 ..< 59) { i in if i == 1 { Text("\(i) minute").tag(i) } else { Text("\(i) minutes").tag(i) } } .navigationBarHidden(true) .padding(.vertical) } } else if selectedTrigger == ReminderType.calendar { DatePicker("Please enter a date", selection: $triggerDate) .labelsHidden() .padding(.vertical) } else { VStack { if !locationManager.authorized { Button( action: { locationManager.requestAuthorization() }, label: { Text("Request Location Authorization") }) } else { TextField("Enter Latitude", text: $latitude) TextField("Enter Longitude", text: $longitude) TextField("Enter Radius", text: $radius) } } .padding(.vertical) } Toggle(isOn: $shouldRepeat) { Text("Repeat Notification") } } } }
7. NotificationSettingsView.swift
import SwiftUIstruct NotificationSettingsView: View { @ObservedObject var notificationManager = NotificationManager.shared var body: some View { VStack { Form { Section { HStack { Spacer() Text("Notification Settings") .font(.title2) Spacer() } } Section { SettingRowView( setting: "Authorization Status", enabled: notificationManager.settings?.authorizationStatus == UNAuthorizationStatus.authorized) SettingRowView( setting: "Show in Notification Center", enabled: notificationManager.settings?.notificationCenterSetting == .enabled) SettingRowView( setting: "Sound Enabled?", enabled: notificationManager.settings?.soundSetting == .enabled) SettingRowView( setting: "Badges Enabled?", enabled: notificationManager.settings?.badgeSetting == .enabled) SettingRowView( setting: "Alerts Enabled?", enabled: notificationManager.settings?.alertSetting == .enabled) SettingRowView( setting: "Show on lock screen?", enabled: notificationManager.settings?.lockScreenSetting == .enabled) SettingRowView( setting: "Alert banners?", enabled: notificationManager.settings?.alertStyle == .banner) SettingRowView( setting: "Critical Alerts?", enabled: notificationManager.settings?.criticalAlertSetting == .enabled) SettingRowView( setting: "Siri Announcement?", enabled: notificationManager.settings?.announcementSetting == .enabled) } } } } }struct NotificationSettingsView_Previews: PreviewProvider { static var previews: some View { NotificationSettingsView() } }struct SettingRowView: View { var setting: String var enabled: Bool var body: some View { HStack { Text(setting) Spacer() if enabled { Image(systemName: "checkmark") .foregroundColor(.green) } else { Image(systemName: "xmark") .foregroundColor(.red) } } .padding() } }
8. Task.swift
import Foundationstruct Task: Identifiable, Codable { var id = UUID().uuidString var name: String var completed = false var reminderEnabled = false var reminder: Reminder}enum ReminderType: Int, CaseIterable, Identifiable, Codable { case time case calendar case location var id: Int { self.rawValue } }struct Reminder: Codable { var timeInterval: TimeInterval? var date: Date? var location: LocationReminder? var reminderType: ReminderType = .time var repeats = false}struct LocationReminder: Codable { var latitude: Double var longitude: Double var radius: Double}
9. AppMain.swift
import SwiftUI @mainstruct AppMain: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { TaskListView() } } }`
10. AppDelegate.swift
import UIKitclass AppDelegate: NSObject, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil ) -> Bool { configureUserNotifications() return true } }// MARK: - UNUserNotificationCenterDelegateextension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void ) { completionHandler(.banner) } private func configureUserNotifications() { UNUserNotificationCenter.current().delegate = self // 1 let dismissAction = UNNotificationAction( identifier: "dismiss", title: "Dismiss", options: [] ) let markAsDone = UNNotificationAction( identifier: "markAsDone", title: "Mark As Done", options: [] ) // 2 let category = UNNotificationCategory( identifier: "OrganizerPlusCategory", actions: [dismissAction, markAsDone], intentIdentifiers: [], options: [] ) // 3 UNUserNotificationCenter.current().setNotificationCategories([category]) } // 1 func userNotificationCenter( _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void ) { // 2 if response.actionIdentifier == "markAsDone" { let userInfo = response.notification.request.content.userInfo if let taskData = userInfo["Task"] as? Data { if let task = try? JSONDecoder().decode(Task.self, from: taskData) { // 3 TaskManager.shared.remove(task: task) } } } completionHandler() } }
其中涉及到的内容比较多所以实现游戏陪玩平台源码本地通知推送的源代码很多,不过希望上述的代码能让大家在开发游戏陪玩平台源码时有所帮助。
本文转载自网络,转载仅为分享干货知识,如有侵权欢迎联系云豹科技进行删除处理
原文链接:https://www.jianshu.com/p/5bb4c782a945
来源https://www.cnblogs.com/yunbao/p/15076059.html