如何在React Native中集成Siri Intents实现多轮交互Todo功能?
React Native集成iOS Siri多轮交互实现方案(Todo应用示例)
由于react-native-siri-shortcut仅支持单轮快捷指令触发,无法实现多轮对话交互,你需要通过原生SiriKit Intent Extension配合React Native通信来完成需求。以下是具体实现步骤:
1. 原生层:创建SiriKit Intent Extension
1.1 添加Intent Extension Target
在Xcode中打开React Native的iOS项目,通过File > New > Target选择Intent Extension,命名为TodoSiriExtension并完成创建(无需勾选"Include UI Extension")。
1.2 定义自定义Intent
- 在Extension目录中创建或打开
.intentdefinition文件,添加名为CreateTodoIntent的自定义Intent。 - 添加两个参数:
todoContent(字符串类型)、dueDate(日期类型),并将两个参数的Ask When Run设置为Yes——这是触发Siri多轮询问的核心配置。 - 在Intent的
Response部分,添加Success类型的响应,并关联todoContent和dueDate作为反馈变量。
1.3 实现Intent Handler
编写处理Intent的逻辑,完成参数收集、数据传递给RN、返回Siri反馈:
import Intents class CreateTodoIntentHandler: NSObject, CreateTodoIntentHandling { func handle(intent: CreateTodoIntent, completion: @escaping (CreateTodoIntentResponse) -> Void) { guard let content = intent.todoContent, let dueDate = intent.dueDate else { completion(CreateTodoIntentResponse(code: .failure, userActivity: nil)) return } // 通过App Groups共享数据给RN主应用 let sharedDefaults = UserDefaults(suiteName: "group.com.yourapp.todo") sharedDefaults?.set(content, forKey: "siri_todo_content") sharedDefaults?.set(dueDate, forKey: "siri_todo_dueDate") sharedDefaults?.synchronize() // 发送通知告知RN处理数据 NotificationCenter.default.post(name: NSNotification.Name("SiriTodoCreated"), object: nil) // 返回成功响应,Siri会自动播报预设的反馈文本 let response = CreateTodoIntentResponse.success( todoContent: content, dueDate: dueDate ) completion(response) } // 可选:自定义参数询问的提示语逻辑 func resolveTodoContent(for intent: CreateTodoIntent, with completion: @escaping (INStringResolutionResult) -> Void) { if let content = intent.todoContent, !content.isEmpty { completion(.success(with: content)) } else { completion(.needsValue()) } } func resolveDueDate(for intent: CreateTodoIntent, with completion: @escaping (INDateComponentsResolutionResult) -> Void) { if let date = intent.dueDate { completion(.success(with: date)) } else { completion(.needsValue()) } } }
1.4 配置App Groups
- 在Xcode中,分别为主应用和Intent Extension开启
Signing & Capabilities中的App Groups,添加同一个Group ID(如group.com.yourapp.todo),用于跨Target共享数据。
2. React Native层:接收并处理Todo数据
2.1 封装原生通信模块
创建原生模块,让RN可以读取App Groups共享的Todo数据:
import Foundation import React @objc(SiriTodoModule) class SiriTodoModule: NSObject, RCTBridgeModule { static func moduleName() -> String { return "SiriTodoModule" } static func requiresMainQueueSetup() -> Bool { return true } @objc func getSiriTodo(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) { let sharedDefaults = UserDefaults(suiteName: "group.com.yourapp.todo") guard let content = sharedDefaults?.string(forKey: "siri_todo_content"), let date = sharedDefaults?.object(forKey: "siri_todo_dueDate") as? Date else { reject("NO_DATA", "未获取到Siri传递的Todo数据", nil) return } // 格式化日期为RN可处理的字符串 let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" let dateStr = formatter.string(from: date) // 返回数据给RN resolve(["content": content, "dueDate": dateStr]) // 清空共享数据,避免重复处理 sharedDefaults?.removeObject(forKey: "siri_todo_content") sharedDefaults?.removeObject(forKey: "siri_todo_dueDate") sharedDefaults?.synchronize() } }
2.2 RN端调用与处理
在RN代码中监听通知并处理Todo存储:
import { NativeModules, NativeEventEmitter, AsyncStorage } from 'react-native'; const { SiriTodoModule } = NativeModules; const SiriTodoEmitter = new NativeEventEmitter(SiriTodoModule); // 监听原生通知,处理Siri传递的Todo SiriTodoEmitter.addListener('SiriTodoCreated', async () => { try { const todo = await SiriTodoModule.getSiriTodo(); // 存储到RN本地存储(示例用AsyncStorage,可替换为Realm等) const todoKey = `todo_${Date.now()}`; await AsyncStorage.setItem(todoKey, JSON.stringify(todo)); console.log("Siri创建的Todo已存储:", todo); } catch (error) { console.error("处理Siri Todo失败:", error); } });
3. 配置与测试
- 在主应用的
Info.plist中添加Siri权限描述:<key>NSSiriUsageDescription</key> <string>使用Siri快速创建待办事项</string> - 在Intent Extension的
Info.plist中,确保NSExtension > NSExtensionAttributes > IntentsSupported数组包含CreateTodoIntent。 - 测试必须在iOS真机上:开启Siri权限,通过
Hey Siri, create a todo for me唤起,测试多轮对话流程。
内容的提问来源于stack exchange,提问作者Vasanth
相关产品推荐
相关产品推荐

