阅读 220

游戏陪玩平台源码开发,关于本地通知推送实现的详细解析

游戏陪玩平台源码开发,关于本地通知推送实现的详细解析

游戏陪玩平台源码开发也是需要实现推送功能的,这样用户就能在第一时间了解平台消息以及好友发送的消息。这虽然只是一个小的方面,但却有着不容忽视的作用。今天我们主要了解一下利用系统的原生推送类结合工程实践如何实现游戏陪玩平台源码系统推送的集成,希望我的讲解能让大家很清楚的理解它。
源码
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

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐