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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:45:37