能否让Siri建议将识别的事件添加到自定义App而非默认日历?
我观看了WWDC2019的243号视频,了解到自定义App可向Siri创建并捐赠交互,使Siri在日历、地图等场景中给出相关建议。但我希望实现「反向捐赠」:当Siri从邮件中识别到事件时,建议将其添加至我的App而非默认日历应用。

我猜测Siri识别的事件存储在名为「Found in Natural Language」的内部日历中,因此尝试了以下代码:
let eventStore = EKEventStore() var fetchedEvents = [EKEvent]() let startDate = Date() let endDate = Calendar.current.date(byAdding: .day, value: 30, to: Date())! let predicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: ["Found in Natural Language"] ) fetchedEvents = eventStore.events(matching: predicate)
但显然此处不能仅传入字符串,我需要提供实际的EKCalendar对象,但该如何操作?「Found in Natural Language」日历是否可被访问?
解答
首先明确:「Found in Natural Language」是系统内部私有日历,苹果并未开放通过EventKit访问它的权限,所以你无法直接获取该日历中的事件,这种思路走不通。
要实现Siri识别事件后建议添加到你的自定义App,正确的方式是利用Siri Intents框架,通过处理INCreateEventIntent并将你的App注册为该Intent的候选应用,具体步骤如下:
添加Intents Extension
在Xcode中给你的App添加「Intents Extension」目标,勾选支持INCreateEventIntent(创建时可在配置界面选择,或后续在Extension的Info.plist中添加对应Intent类型)。实现Intent处理逻辑
在Intents Extension的IntentHandler类中,实现INCreateEventIntentHandling协议,处理Siri传递的事件数据,并将其保存到你的App中:import Intents class IntentHandler: INExtension, INCreateEventIntentHandling { // 处理创建事件的请求 func handle(intent: INCreateEventIntent, completion: @escaping (INCreateEventIntentResponse) -> Void) { // 从intent中提取事件核心信息 guard let eventTitle = intent.title, let startDateComp = intent.startDateComponents, let endDateComp = intent.endDateComponents else { completion(INCreateEventIntentResponse(code: .failure, userActivity: nil)) return } // 将事件保存到你的自定义App中(替换为你的实际存储逻辑) saveEventToCustomApp(title: eventTitle, start: startDateComp, end: endDateComp) // 返回处理成功的响应 completion(INCreateEventIntentResponse(code: .success, userActivity: nil)) } // 可选:提供确认界面(让用户确认事件信息) func confirm(intent: INCreateEventIntent, completion: @escaping (INCreateEventIntentResponse) -> Void) { completion(INCreateEventIntentResponse(code: .ready, userActivity: nil)) } // 自定义的事件存储方法 private func saveEventToCustomApp(title: String, start: DateComponents, end: DateComponents) { // 这里写入你的App保存事件的业务逻辑 } }注册为Intent候选应用
在主App中,先请求Siri权限,然后将你的App设置为INCreateEventIntent的默认候选应用之一:import Intents func setupSiriIntentPreferences() { INPreferences.requestSiriAuthorization { authStatus in guard authStatus == .authorized else { return } // 将当前App注册为INCreateEventIntent的处理应用 INPreferences.setDefaultHandler(for: INCreateEventIntent.self, appBundleIdentifier: Bundle.main.bundleIdentifier!) } }配置权限描述
在主App的Info.plist中添加NSSiriUsageDescription键,填写向用户说明使用Siri权限的原因(比如"允许Siri将识别到的事件添加到我的App中")。
补充说明
- 无需直接访问系统私有日历,Siri会自动将识别到的事件数据通过
INCreateEventIntent传递给你的App。 - 用户首次使用时需要授权Siri权限,后续也可以在系统设置的「Siri与搜索」中调整默认的事件创建应用。
内容的提问来源于stack exchange,提问作者grep

