You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现App终止状态下的每日提醒通知问题求助附代码

解决iOS App终止状态下无法触发每日提醒的问题

嘿,我来帮你搞定这个App终止后没法触发每日提醒的问题!你的当前代码用了UNTimeIntervalNotificationTrigger,这个触发器是基于相对时间间隔的,而且你设了repeats: false,只能触发一次,更关键的是——如果App被终止,这种短间隔的触发器可能不会可靠工作,完全没法实现每日固定时间的重复提醒。下面是具体的解决方案:

核心问题分析

你现在用的UNTimeIntervalNotificationTrigger适合临时、一次性的短间隔提醒,但要实现每日固定时间的重复提醒,哪怕App终止也能触发,必须用UNCalendarNotificationTrigger——这是系统级的触发器,由iOS系统负责调度,不受App运行状态影响。

步骤1:确保获取完整的通知权限

首先要确保用户给了App通知权限,而且要请求alert、sound、badge这三个选项,代码如下:

func requestNotificationPermissions() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        if granted {
            print("通知权限已获取,可以安排提醒啦")
        } else {
            print("通知权限被拒绝了:\(error?.localizedDescription ?? "未知错误")")
        }
    }
}

记得在App启动时调用这个方法,比如在application(_:didFinishLaunchingWithOptions:)或者首页的viewDidLoad里。

步骤2:替换为日历触发器的提醒代码

下面是修改后的代码,专门用来安排每日重复的祈祷提醒,用UNCalendarNotificationTrigger实现:

func scheduleDailyAzanReminder(prayerName: String, reminderHour: Int, reminderMinute: Int) {
    // 1. 创建通知内容
    let content = UNMutableNotificationContent()
    content.title = "\(prayerName) azan will be after 5 minutes"
    content.badge = 1
    
    // 2. 处理自定义通知声音
    if let customSound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "salah.mp3")) {
        content.sound = customSound
    } else {
        print("找不到salah.mp3,用默认通知声音")
        content.sound = .default
    }
    
    // 3. 设置每日触发的时间点
    var dateComponents = DateComponents()
    dateComponents.hour = reminderHour
    dateComponents.minute = reminderMinute
    
    // 4. 创建日历触发器(重复触发)
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
    
    // 5. 创建通知请求(用祈祷名做唯一ID,方便后续更新/删除)
    let request = UNNotificationRequest(
        identifier: "azanReminder_\(prayerName)",
        content: content,
        trigger: trigger
    )
    
    // 6. 添加到通知中心
    UNUserNotificationCenter.current().add(request) { error in
        if let error = error {
            print("安排\(prayerName)提醒失败:\(error.localizedDescription)")
        } else {
            print("\(prayerName)的每日提醒已经安排好了!")
        }
    }
}

步骤3:调用方法安排提醒

比如你要给fajer安排早上5:30的提醒,就这么调用:

scheduleDailyAzanReminder(prayerName: "fajer", reminderHour: 5, reminderMinute: 30)
// 同理给其他祈祷安排对应的时间
scheduleDailyAzanReminder(prayerName: "dohor", reminderHour: 12, reminderMinute: 0)

关键注意事项

  • 音频文件检查:确保salah.mp3已经添加到Xcode项目中,并且在Target的Build Phases > Copy Bundle Resources里能看到它(如果没加,系统找不到这个文件,会用默认声音)。
  • 动态时间调整:如果祈祷时间是根据地理位置变化的(比如夏令时或不同地区),你需要定期重新计算时间,然后更新对应的通知请求(先删除旧的,再添加新的)。
  • 测试技巧:测试时可以把提醒时间设为当前时间的几分钟后,然后完全终止App,等待系统触发通知——这样能快速验证是否生效。
  • 权限问题:如果用户后来禁用了通知权限,所有提醒都会失效,所以可以在App里加个检查权限的逻辑,引导用户开启。

内容的提问来源于stack exchange,提问作者basim imam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:16:40