如果从 Core Data SwiftUI 中删除,则删除本地通知

Posted

技术标签:

【中文标题】如果从 Core Data SwiftUI 中删除,则删除本地通知【英文标题】:Delete Local Notification if removed from Core Data SwiftUI 【发布时间】:2020-07-24 19:45:59 【问题描述】:

我编写了这个简单的代码来尝试本地通知如何与 Core Data 一起工作,主要问题是,在添加 Data Core 项目后,我可以在 60 秒后收到通知,但如果我删除它,我仍然会收到它。当我调用 deleteItem 函数时,是否可以调用一个函数来删除该特定通知?

我的另一个问题是如何设置一周中的某一天和触发该通知的时间,而不是在几秒钟后重复?

内容视图:

import UserNotifications
import SwiftUI
import CoreData

struct ContentView: View 
    //Core Data
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(entity: Notifications.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Notifications.date, ascending: false)]) var notifications: FetchedResults<Notifications>
    
    var titles = ["Hello", "Weekend", "Streaming", "ScoobyDoo"]
    var subtitles = ["Hello2", "Weekend2", "Streaming2", "ScoobyDoo2"]
    
    var body: some View 
        NavigationView 
            VStack 
                NavigationLink(destination: FavoriteView()) 
                    Text("Favorite View")
                
                List 
                    ForEach(0 ..< titles.count) title in
                        HStack 
                            Text(self.titles[title])
                            Image(systemName: "heart")
                                .onTapGesture 
                                    if self.checkItem(title: self.titles[title]) 
                                        do 
                                            try self.deleteItem(title: self.titles[title])
                                            print("title deleted")
                                         catch 
                                            print(error)
                                        
                                     else 
                                        self.addItem(item: self.titles[title])
                                        print("item added")
                                        
                                        // Notification content
                                        let content = UNMutableNotificationContent()
                                        content.title = self.titles[title]
                                        content.subtitle = self.subtitles[title]
                                        content.sound = UNNotificationSound.default
                                        
                                        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
                                        
                                        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
                                        
                                        UNUserNotificationCenter.current().add(request)
                                    
                            
                        
                    
                
                
                Button("Request Authorization") 
                    // Ask for notification when app launches
                    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound])  success, error in
                        if success 
                            print("All set")
                         else if let error = error 
                            print(error.localizedDescription)
                        
                        
                    
                
                
                Button("Remove Notifications") 
                    UNUserNotificationCenter.current().removeAllDeliveredNotifications()
                    print("Removed")
                
            
        
    
    private func checkItem(title: String) -> Bool 
        let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Notifications")
        request.predicate = NSPredicate(format: "title == %@", title)
        request.fetchLimit = 1
        var trueFalse = true
        do 
            let count = try managedObjectContext.count(for: request)
            if count == 0 
                trueFalse = false
             else 
                trueFalse = true
            
         catch 
            print(error)
        
        return trueFalse
    
    
    private func deleteItem(title: String) throws 
        let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Notifications")
        request.predicate = NSPredicate(format: "title == %@", title)
        try managedObjectContext.execute(NSBatchDeleteRequest(fetchRequest: request))
        
        saveFavorites()
    
    func addItem(item: String) 
        let newItem = Notifications(context: managedObjectContext)
        newItem.title = item
        saveFavorites()
    
    func saveFavorites() 
        do 
            try managedObjectContext.save()
         catch 
            print(error)
        
    

收藏视图:

import SwiftUI
import CoreData

struct FavoriteView: View 
    //Core Data
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(entity: Notifications.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Notifications.date, ascending: false)]) var notifications: FetchedResults<Notifications>
    
    var body: some View 
        List 
            ForEach(notifications, id: \.self)  item in
                Text(item.title)
            
        
    

【问题讨论】:

【参考方案1】:

修改核心数据模型以包含您在添加请求时提供的通知标识符。然后在从核心数据中删除通知时,您可以使用此标识符来删除本地通知,如下所示:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifier])

【讨论】:

按预期工作!非常感谢你。我只是不明白为什么 UNUserNotificationCenter.current().removeAllDeliveredNotifications() 和 UNUserNotificationCenter.current().removeAllPendingNotificationsRequests() 根本不起作用 这很棒。对于那些想知道的人,标识符确实需要作为数组传递。只需替换“标识符”即可。

以上是关于如果从 Core Data SwiftUI 中删除,则删除本地通知的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI从Core Data实体中获取总项目(SQL术语中的行)计数[重复]

如何从存储在 Core Data SwiftUI 中的数据计算平均值

从 Core Data 非标量属性更新 SwiftUI 视图

SwiftUI Core Data 在 DetailView 中绑定 TextFields

SwiftUI 和 Core Data:基于用户输入获取

SwiftUI - Core-Data - 在这种特殊情况下访问包装的值