ios – How would I associate a notification with a reminder?

I have a reminders app and need to associate the correct notification with each reminder that way if a reminder is added a new notification request will be sent assuming the reminder has a date or time set. The parameters for the reminder can be seen in the Reminder Model. If the reminder is deleted the notification should also be deleted. I have my reminder model, home view with how I set up my notification so far, and my LocalNotificationManager below. Also should the localNotificationManager be put in a view model folder or should it go somewhere else. Any help would be greatly appreciated.

Reminder Model

””

struct Reminder: Identifiable, Equatable {
var title: String
var notes: String?
var date: Date?
var time: Date?
var theme: Theme
var iscomplete: Bool
var priority: RemindPriority
let id: UUID
//let filter: FilterType

init(title: String, notes: String? = nil, date: Date? = nil, time: Date? = nil, theme: Theme, iscomplete: Bool = false, priority: RemindPriority = .None, id: UUID = UUID()) {
    self.title = title
    self.notes = notes
    self.date = date
    self.time = time
    self.theme = theme
    self.iscomplete = iscomplete
    self.priority = priority
    self.id = id
}

/*var filteredReminders: [Reminder] {
    switch filter {
    case .all:
        return HomeViewModel().reminds
    case .today:
        return HomeViewModel().reminds.filter($0.date.)
    }
}*/

func formatDate(date: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateStyle = .full
    formatter.timeStyle = .none
    
    return formatter.string(from: date)
}

func formatTime(time: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateStyle = .none
    formatter.timeStyle = .short
    
    return formatter.string(from: time)
}   
}

””

HomeView

””

import SwiftUI

struct HomeView: View {
@StateObject private var homeVM = HomeViewModel()
@State var percent: Int = 1
@State var showDetailEditView = false
@State var showAddView = false
@State var dropDown = false
@State var index: Int?
@ObservedObject var notificationManager = LocalNotificationManager()

//@State var filter = false

var body: some View {
        ZStack {
            List {
                ForEach($homeVM.reminds) { $remind in
                    NavigationLink(destination: ReminderDetailView(remindVM: ReminderViewModel(remind: $remind))) {
                        ReminderView(remind: $remind)
                    }
                        .listRowBackground(remind.theme.mainColor)
                        .buttonStyle(PlainButtonStyle())
                        .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                        .swipeActions(edge: .leading) {
                            Button(action: {
                                self.showDetailEditView.toggle()
                                homeVM.existingRemindData = remind.data
                                index = homeVM.reminds.firstIndex(of: remind)
                            }) {
                                Label("Edit", systemImage: "pencil")
                            }
                        }
                        .sheet(isPresented: $showDetailEditView, onDismiss: {homeVM.existingRemindData = Reminder.Data()}) {
                            NavigationView {
                                ReminderEditView(data: $homeVM.existingRemindData)
                                    .navigationTitle(homeVM.existingRemindData.title)
                                    .toolbar {
                                        ToolbarItem(placement: .cancellationAction) {
                                            Button("Cancel") {
                                                self.showDetailEditView.toggle()
                                                homeVM.existingRemindData = Reminder.Data()
                                            }
                                        }
                                        ToolbarItem(placement: .confirmationAction) {
                                            Button("Done") {
                                                self.showDetailEditView.toggle()
                                                homeVM.reminds[index!].update(from: homeVM.existingRemindData)
                                                homeVM.newRemindData = Reminder.Data()
                                            }
                                        }
                                    }
                                    .background(LinearGradient(gradient: Gradient(colors: [
                                        Color(UIColor(red: 0.376, green: 0.627, blue: 0.420, alpha: 1)),
                                        Color(UIColor(red: 0.722, green: 0.808, blue: 0.725, alpha: 1))
                                    ]), startPoint: .topLeading, endPoint: .bottomTrailing))
                            }
                        }
                        .swipeActions(allowsFullSwipe: true) {
                            Button (role: .destructive, action: {
                                homeVM.deleteReminder(remind: remind)
                            }) {
                                Label("Delete", systemImage: "trash.fill")
                            }
                        }
                }
            }
            .onAppear(
                perform: {
                    UITableView.appearance().backgroundColor = .clear
                    UITableViewCell.appearance().backgroundColor = .clear
                })
            .safeAreaInset(edge: .top) {
                HStack {
                    /*
                    Button(action: {
                        self.filter.toggle()
                    }) {
                        Image(systemName: "line.3.horizontal")
                            .font(.system(size: 25))
                    }
                    
                    Spacer()
                    
                    HStack {
                        Text("Hello")
                        .font(.largeTitle.bold())
                        Image(systemName: "chevron.right")
                            .font(.system(size: 17, weight: .bold, design: .default))
                            .frame(width: 10, height: 10, alignment: .center)
                            .onTapGesture {
                                self.dropDown.toggle()
                            }
                            .rotationEffect(dropDown ? .degrees(90) : .degrees(0))
                            .animation(Animation.easeInOut(duration: 0.2), value: dropDown)
                    }
                    */
                    
                    Text("NextUp")
                        .font(.largeTitle.bold())
                    
                    Spacer()
                    Button(action: {
                        self.showAddView.toggle()
                    }) {
                        Image(systemName: "plus")
                            .font(.system(size: 25))
                    }
                    .sheet(isPresented: $showAddView, onDismiss: {homeVM.newRemindData = Reminder.Data()}) {
                        NavigationView {
                            ReminderEditView(data: $homeVM.newRemindData)
                            .toolbar {
                                ToolbarItem(placement: .cancellationAction) {
                                    Button("Dismiss") {
                                        showAddView = false
                                        homeVM.newRemindData = Reminder.Data()
                                    }
                                }
                                ToolbarItem(placement: .confirmationAction) {
                                    Button("Add") {
                                        homeVM.newReminder()
                                        
                                        if homeVM.reminds.last?.data.date != nil {

                                            notificationManager.sendNotification(date: (homeVM.reminds.last?.data.combineDateWithTime(date: (homeVM.reminds.last?.data.date)!, time: homeVM.reminds.last?.data.time ?? Calendar(identifier: .gregorian).date(bySettingHour: 0, minute: 0, second: 0, of: Date())!))!, type: "date", title: (homeVM.reminds.last?.title)!, body: (homeVM.reminds.last?.notes) ?? "None")
                                            print(Calendar(identifier: .gregorian).date(bySettingHour: 0, minute: 0, second: 0, of: Date())!)
                                                //print(notificationManager.notifications)
                                            
                                            
                                        }
                                        showAddView = false
                                    }
                                }
                            }
                            .background(LinearGradient(gradient: Gradient(colors: [
                                Color(UIColor(red: 0.376, green: 0.627, blue: 0.420, alpha: 1)),
                                Color(UIColor(red: 0.722, green: 0.808, blue: 0.725, alpha: 1))
                            ]), startPoint: .topLeading, endPoint: .bottomTrailing))
                            .navigationTitle("New Reminder")
                        }
                    }
                }
                .padding()
                .background(Color.clear.overlay(.ultraThickMaterial))
            }
            .safeAreaInset(edge: .bottom) {
                ForEach(homeVM.reminds) { remind in
                    if remind.iscomplete {
                        ProgressBarView(progress: Float(homeVM.compReminds.count) / Float(homeVM.reminds.count))
                                .padding(.vertical)
                                .onAppear {
                                    homeVM.appendRemind(complete: remind)
                                }
                                .onDisappear {
                                    homeVM.removeRemind(remind: remind)
                                }
                    }
                    
                }
                .frame(height: 75)
                .background(Color.white.overlay(.ultraThickMaterial))
            }
            .ignoresSafeArea(edges: .bottom)
            .background(LinearGradient(gradient: Gradient(colors: [
                Color(UIColor(red: 0.376, green: 0.627, blue: 0.420, alpha: 1)),
                Color(UIColor(red: 0.722, green: 0.808, blue: 0.725, alpha: 1))
            ]), startPoint: .topLeading, endPoint: .bottomTrailing)
                )
        .navigationBarHidden(true)
        /*
         .onTapGesture {
            if dropDown == true {
                self.dropDown.toggle()
            }
            /*if filter == true {
                self.filter.toggle()
            }*/
        }
         */
            
        /*
        ScrollView {
            ForEach((1...10), id: .self) { folder in
                HStack {
                    Text("Folder (folder)")
                        .font(.title2)
                    Spacer()
                    Image(systemName: "chevron.right")
                }
                .padding(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15))
                Divider()
            }
        }
        .frame(width: 250, height: 260)
        .background(.white)
        .cornerRadius(10)
        .position(x: UIScreen.main.bounds.size.width/1.9, y: 200)
        .scaleEffect(dropDown ? 1.0 : 0, anchor: UnitPoint.init(x: 0.62, y: 0.06))
        .animation(Animation.spring(), value: dropDown)
        */
        
        /*
         FilterView(homeVM: homeVM)
            .position(x: UIScreen.main.bounds.width/2.7, y: 85)
            .scaleEffect(filter ? 1.0 : 0, anchor: UnitPoint.init(x:0.1, y: 0.06))
            .animation(Animation.spring(), value: filter)
        */
            
    }
}
}

””

LocalNotificationManager

””

import Foundation
import SwiftUI

class LocalNotificationManager: ObservableObject {
//@Published var notifications: [UNNotificationRequest] = []

init() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
        if granted == true && error == nil {
            print("Notifications are allowed")
        } else {
            print("Notifications are not allowed")
        }
    }
}

func sendNotification(date: Date, type: String, timeInterval: Double = 10, title: String, body: String) {
    var trigger: UNNotificationTrigger?
    
    if type == "date" {
        let dateComponents = Calendar.current.dateComponents([.day, .month, .year, .hour, .minute], from: date)
        trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
    } else if type == "time" {
        trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval, repeats: false)
    }
    
    let content = UNMutableNotificationContent()
    content.title = title
    content.body = body
    content.sound = UNNotificationSound.default
    //content.badge = (notifications.count) as NSNumber
    
    let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
    
    UNUserNotificationCenter.current().add(request)
    
    //notifications.append(request)
}

}

””

Leave a Comment