如何安排本地通知在应用程序打开时触发一次,而不会在用户重新打开它时重复? (斯威夫特、XCode、IOS)

发布于 2025-01-16 20:34:42 字数 2655 浏览 1 评论 0原文

我是 Swift 和 XCode 编程新手,在调试代码时遇到问题。该应用程序应该每天同一时间向用户发送一次通知。到目前为止,我已经设置了基础知识,但在测试时,如果我清除应用程序并重新打开它,它会安排两个通知,而不是一个通知。是否需要某种魔术来解决这个问题?

目前,在 viewDidLoad 下调用 scheduleNotification 函数,以便它可以在启动时立即安排一切。我尝试调用 UNUserNotificationCenter.current().add(request) 下的函数。我认为在下面调用它是有意义的,因为它只提示用户一次,因此当用户授予通知权限时,它会立即激活通知,而不会冒重复的风险。但这根本没有安排任何通知。

我做了更多研究,也许我在错误的文件中编写了通知?这一切都在视图控制器中。

我和我的父亲交谈过,他非常喜欢软件,他建议用 ID 跟踪通知,如果我不想让它们出现,就删除它们。但这听起来很复杂,我没有心情再头痛,哈哈

有什么想法吗?

(另外,忽略一些与计算器有关的调用。这与我的问题无关)

//
//  ViewController.swift
//

import UIKit

class ViewController: UIViewController {

    // Calculator Outlets
    @IBOutlet weak var calculatorWorkings: UILabel!
    @IBOutlet weak var calculatorResults: UILabel!
    var workings:String = ""
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        clearAll()
        
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {_, _ in
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                
                print("Request authorized")
                
                 // Repeatedly call function so program schedules notifications in advance
                 for i in 1...10 {
                    self.scheduleNotification(day: i)
                }
                
            }
        }
    }
        
    // Phrases
    let phrasesArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
    
    // Handle Notifications
    func scheduleNotification(day: Int) {
        
        var dateComponents = DateComponents()
        dateComponents.hour = 21
        dateComponents.minute = 09
        dateComponents.day = day
        
        let content = UNMutableNotificationContent()
            // App name is not included in notification bar
        content.title = "Jenna's Wisdom:"
        content.body = phrasesArray[(Int.random(in: 0..<9))]
        
        content.sound = .default
        content.interruptionLevel = .timeSensitive
        
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
        
        // Request to send notifications
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        
        UNUserNotificationCenter.current().add(request) { error in
            if let error = error {
                print(error)
            } else {
                print("Success")
                
            }
        }
        
    }
    
}

I'm new to programming in Swift and XCode and I'm having trouble debugging my code. The app is supposed to send notifications to the user once every day at the same time. I have the basics set up so far, but while testing, if I clear the app and reopen it, it schedules two notifications instead of just one. Is there some sort of magic trick I need to fix this?

Currently, the scheduleNotification function is being called under viewDidLoad so that it can schedule everything as soon as it boots up. I've tried calling the function under UNUserNotificationCenter.current().add(request). I figured it would make sense to call it under there because it only prompts the user once, so when the user grants notification permissions, it would activate the notifications immediately without risking repeats. But that didn't schedule any notifications at all.

I did some more research and maybe I'm programming the notifications in the wrong file? This is all in the View Controller.

I talked to my dad who's really into software and he suggested tracking the notifications with an ID and deleting them if I don't want them to appear. But that sounds very complicated and I'm not in the mood for another headache haha

Any ideas?

(Also, ignore some of the calls that have to do with the calculator. That's unrelated to my issue)

//
//  ViewController.swift
//

import UIKit

class ViewController: UIViewController {

    // Calculator Outlets
    @IBOutlet weak var calculatorWorkings: UILabel!
    @IBOutlet weak var calculatorResults: UILabel!
    var workings:String = ""
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        clearAll()
        
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {_, _ in
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                
                print("Request authorized")
                
                 // Repeatedly call function so program schedules notifications in advance
                 for i in 1...10 {
                    self.scheduleNotification(day: i)
                }
                
            }
        }
    }
        
    // Phrases
    let phrasesArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
    
    // Handle Notifications
    func scheduleNotification(day: Int) {
        
        var dateComponents = DateComponents()
        dateComponents.hour = 21
        dateComponents.minute = 09
        dateComponents.day = day
        
        let content = UNMutableNotificationContent()
            // App name is not included in notification bar
        content.title = "Jenna's Wisdom:"
        content.body = phrasesArray[(Int.random(in: 0..<9))]
        
        content.sound = .default
        content.interruptionLevel = .timeSensitive
        
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
        
        // Request to send notifications
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        
        UNUserNotificationCenter.current().add(request) { error in
            if let error = error {
                print(error)
            } else {
                print("Success")
                
            }
        }
        
    }
    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹梦 2025-01-23 20:34:42

假设 ViewController 是第一个且是 rootViewcontroller,您可以在添加新通知之前删除所有本地通知。

UNUserNotificationCenter.current().removeAllPendingNotificationRequests()

Assuming ViewController is the first and rootViewcontroller you can just remove all local notifications before adding new ones.

UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文