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

EventKit如何获取EKReminder子任务对应的父任务层级关系

EventKit获取提醒事项父子层级关系方案

EKReminder官方公开文档未直接标注父子任务关联属性,是因为该层级能力的公开API在较新系统版本才正式对外提供,具体实现方式分两种场景:

系统版本适配说明

  • iOS 17、macOS 14 及以上版本:苹果已正式开放公开属性,可直接调用,无审核风险
  • 低于上述版本的系统:任务层级关系存储在EventKit内部私有字段中,可通过KVC方式读取,但该方式调用非公开API,上架App Store存在审核被拒风险,仅建议自用、内部分发场景使用

具体实现代码

首先给EKReminder写扩展,兼容不同版本的层级读取逻辑:

import EventKit

extension EKReminder {
    /// 获取当前提醒的父任务,顶层任务返回nil
    var parentReminderTask: EKReminder? {
        if #available(iOS 17.0, macOS 14.0, *) {
            return self.parentReminder
        } else {
            return self.value(forKey: "parent") as? EKReminder
        }
    }
    
    /// 获取当前提醒下的所有直接子任务
    var reminderSubtasks: [EKReminder] {
        if #available(iOS 17.0, macOS 14.0, *) {
            return self.subtasks ?? []
        } else {
            return self.value(forKey: "subtasks") as? [EKReminder] ?? []
        }
    }
}

原有拉取提醒的逻辑不需要修改,fetchReminders返回的结果已经包含所有层级的提醒事项,拉取完成后直接遍历读取关联属性即可,示例修改如下:

func fetchAllReminders(for store:EKEventStore) {
    let predicate: NSPredicate? = store.predicateForIncompleteReminders(withDueDateStarting: nil, ending: nil, calendars: nil)
    store.fetchReminders(matching: predicate!, completion: { (reminders: [EKReminder]?) -> Void in
        guard let reminders = reminders else {
            assertionFailure("No reminders found")
            return
        }
        if reminders.isEmpty {
            print("No reminders found")
            return
        }
        // 先筛选所有顶层任务(无父任务的项)
        let topLevelReminders = reminders.filter { $0.parentReminderTask == nil }
        for reminder in topLevelReminders {
            print("=== 顶层任务:\(reminder.title ?? "No title") ===")
            print("所属日历: \(reminder.calendar.title)")
            if reminder.hasNotes {
                print("备注: \(reminder.notes ?? "No Notes")")
            }
            // 遍历当前顶层任务的子任务
            let subtasks = reminder.reminderSubtasks
            if !subtasks.isEmpty {
                print("子任务列表:")
                for (index, subtask) in subtasks.enumerated() {
                    print("\(index+1). \(subtask.title ?? "无标题")")
                }
            }
        }
    })
}

效果参考

提醒任务示例

提示:如果你的应用需要上架App Store,建议在低版本系统中隐藏任务层级展示能力,仅在iOS17+/macOS14+系统中使用公开API读取父子关系,避免因调用私有接口被审核驳回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:45:30