You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SiriKit中INSendMessageIntent未触发handleSendMessage代理及日期获取咨询

Siri意图处理问题排查与解决方案

我来帮你逐一解决这两个问题:


一、handleSendMessage代理方法未触发的排查步骤

从你的代码来看,基本的方法实现是有的,但没触发大概率是配置或resolve阶段的逻辑问题,按下面的步骤检查:

1. 确认Siri扩展的Info.plist配置

这是最容易忽略的点!你必须在扩展的Info.plist里声明支持INSendMessageIntent

  • 打开扩展的Info.plist,找到NSExtensionNSExtensionAttributesIntentsSupported数组
  • 确保数组中包含INSendMessageIntent这个字符串
  • 如果需要在锁屏下使用,还要在IntentsRestrictedWhileLocked数组中添加同样的内容

2. 修正Resolve方法的逻辑

你的resolveRecipientsForSendMessage直接返回了notRequired,这可能导致Siri无法确认意图是否完成,进而跳过handle阶段。建议改成更严谨的解析逻辑:

- (void)resolveRecipientsForSendMessage:(INSendMessageIntent *)intent withCompletion:(void (^)(NSArray<INPersonResolutionResult *> *resolutionResults))completion {
    NSMutableArray<INPersonResolutionResult *> *resolutionResults = [NSMutableArray array];
    NSArray<INPerson *> *recipients = intent.recipients;
    
    if (recipients.count == 0) {
        // 没有提供收件人,提示用户输入
        [resolutionResults addObject:[INPersonResolutionResult needsValue]];
    } else {
        // 验证收件人(比如检查是否在你的应用联系人列表中)
        for (INPerson *person in recipients) {
            [resolutionResults addObject:[INPersonResolutionResult successWithResolvedPerson:person]];
        }
    }
    completion(resolutionResults);
}

只有当所有resolve方法都返回successnotRequired且意图足够明确时,Siri才会调用handleSendMessage

3. 验证测试指令的正确性

确保你使用的语音指令能被Siri正确识别为发送消息意图,比如:

  • "使用<你的App名称>给John发消息说你好"
  • "<你的App名称> 给张三发消息提醒明天开会"
    模糊的指令(比如只说"发消息")可能会被Siri引导到系统消息应用,而不是你的扩展。

4. 检查Siri权限与扩展部署

  • 在设备设置中,找到Siri与搜索 → 你的App,开启"用Siri打开"和"允许Siri建议"
  • 确保在Xcode中运行的是Siri扩展目标,并且设备上已经正确安装了扩展(可以在设置→通用→VPN与设备管理中确认)

二、从语音中获取日期/时间的方案

INSendMessageDomain本身只是标识意图的领域,不能直接获取日期/时间,但有两种场景的解决方案:

1. 延迟发送场景:直接读取sendDate属性

如果用户的指令包含延迟发送的时间(比如"明天早上8点给李四发消息提醒起床"),Siri会自动将日期/时间解析到INSendMessageIntentsendDate属性中,你可以直接读取:

- (void)handleSendMessage:(INSendMessageIntent *)intent completion:(void (^)(INSendMessageIntentResponse *response))completion {
    NSDateComponents *sendDate = intent.sendDate;
    if (sendDate) {
        NSLog(@"延迟发送时间:%@", sendDate);
        // 这里可以处理延迟发送的逻辑
    }
    
    // 其他原有逻辑
    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INSendMessageIntent class])];
    INSendMessageIntentResponse *response = [[INSendMessageIntentResponse alloc] initWithCode:INSendMessageIntentResponseCodeSuccess userActivity:userActivity];
    completion(response);
}

2. 消息内容中包含日期/时间:用Natural Language框架解析

如果日期/时间是消息内容的一部分(比如"给王五发消息说后天下午三点见面"),你需要自己解析intent.content文本,推荐使用Apple的NaturalLanguage框架来识别实体:

#import <NaturalLanguage/NaturalLanguage.h>

- (void)handleSendMessage:(INSendMessageIntent *)intent completion:(void (^)(INSendMessageIntentResponse *response))completion {
    NSString *content = intent.content;
    if (content.length > 0) {
        NLTagger *tagger = [[NLTagger alloc] initWithTagSchemes:@[NLTagSchemeDateTime]];
        tagger.string = content;
        [tagger enumerateTagsInRange:NSMakeRange(0, content.length)
                               unit:NLTokenUnitWord
                             scheme:NLTagSchemeDateTime
                            options:NLTaggerOmitWhitespace
                         usingBlock:^(NLTag *tag, NSRange tokenRange, BOOL *stop) {
                             if (tag) {
                                 NSString *dateTimeStr = [content substringWithRange:tokenRange];
                                 NSLog(@"识别到的日期/时间:%@", dateTimeStr);
                                 // 可以进一步将字符串转换为NSDate或NSDateComponents
                             }
                         }];
    }
    
    // 其他原有逻辑
    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([INSendMessageIntent class])];
    INSendMessageIntentResponse *response = [[INSendMessageIntentResponse alloc] initWithCode:INSendMessageIntentResponseCodeSuccess userActivity:userActivity];
    completion(response);
}

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

火山引擎 最新活动