在iOS调用SiriKit识别指令

解读

面试官真正想考察的是:

  1. 你是否把Unity3D当作“宿主”而非“孤岛”,知道iOS原生能力必须走原生桥接;
  2. SiriKit的权限、Intent Domain、语音链路生命周期有没有实战级理解;
  3. 能否给出可落地的Unity→Native→SiriKit→Unity闭环方案,并兼顾国内App Store审核隐私合规
  4. 是否具备性能与体验兜底意识(离线、失败、中文方言、后台唤醒)。
    一句话:不是“能不能调”,而是“怎么调得稳、调得上架、调得可维护”。

知识点

  • SiriKit可用Domain:iOS 15+ 开放App Intents(原Intent Extension)给第三方,游戏场景下常用Custom Intent+App Shortcuts,而非老版VoIP、Messaging等封闭Domain。
  • Unity-iOS桥接
    UnitySendMessage只能Native→Unity,且主线程延迟;
    UnityFramework动态库符号暴露,C#通过[DllImport("__Internal")]调用Objective-C。
  • 权限与描述NSSiriUsageDescription(iOS 16起强制)、NSMicrophoneUsageDescriptionNSSpeechRecognitionUsageDescription,缺一则审核秒拒。
  • 中文指令优化Siri NLTokenizer+自定义词汇表(App Intent Vocabulary),解决“开火”被识别成“开伙”。
  • 热更新合规:App Intents 以Swift 源码形式编进主App,无法热更;若必须热更指令,只能走云端配置+本地映射表,但不得动态注册新Intent,否则4.3条款驳回。
  • 性能注意:SiriKit回调在独立进程(Intent Extension),内存上限~16 MB,不得加载Unity引擎,只能做轻量级解析后回主App。

答案

  1. 工程配置
    a. 在Unity导出Xcode工程后,新建Swift Intent Extension Target(需≥iOS 15)。
    b. Podfileuse_frameworks!,引入AppIntents框架;主App与Extension共享同一App Group,便于缓存指令映射表。
    c. Info.plist 追加
    NSSiriUsageDescription:“需要Siri权限来识别语音指令,提升操作效率。”
    NSMicrophoneUsageDescriptionNSSpeechRecognitionUsageDescription同理,必须中文,否则审核驳回。

  2. 定义Custom Intent
    在Swift侧新建GameCommandIntent: AppIntent,含参数command: String、结果success: Bool
    使用**@Parameter(title: "指令")**标注,支持同义词数组“开火/射击/shoot”。

  3. 桥接Unity→Native
    Unity C#层

    [DllImport("__Internal")]
    private static extern void _siri_registerCommands(string json); // 注册同义词表
    
    public static void RegisterSiriCommands(List<string> cmds){
        #if UNITY_IOS && !UNITY_EDITOR
        _siri_registerCommands(JsonUtility.ToJson(new CmdList{list=cmds}));
        #endif
    }
    

    Objective-C++ (SiriBridge.mm)

    extern "C" void _siri_registerCommands(const char* json){
        NSString* nsJson = [NSString stringWithUTF8String:json];
        [[NSUserDefaults standardUserDefaults] setObject:nsJson forKey:@"SiriVocab"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        // 触发INTENT VOCABULARY SYNC
        [INVoiceShortcutCenter.sharedCenter setShortcutSuggestions:@[]];
    }
    
  4. Native→Unity回传结果
    Intent Extension解析完成后,通过App Group UserDefaults写回结果;主App进入前台时,Unity轮询或监听applicationWillEnterForeground通知,再UnitySendMessage("SiriManager","OnCommand",command),保证回到主线程。

  5. 审核与合规
    – 在App Store Connect元数据里勾选Siri能力,录制演示视频供审核;
    – 隐私清单补充Speech Recognition使用场景,不得声明“收集”语音数据,只能“临时处理”;
    – 若游戏含未成年人账号,需在家长控制界面提供关闭Siri开关,否则被儿童类别拒审

  6. 性能与异常兜底
    – Extension内存超限被系统杀掉时,INIntentResponse返回failureRequiringAppLaunch;主App启动后读取lastIntentUserInfo重放指令,保证不丢指令
    – 中文方言识别失败,本地维护模糊匹配表(Levenshtein距离≤2),兜底弹Toast提示“未识别,请再说一次”。

拓展思考

  • 跨平台一致性:若同时上架Android,可用Google Assistant App Actions实现同源指令,但Custom Intent语法差异大,需在Cloud Script做指令归一化,保持策划配置单一份。
  • 语音驱动战斗的延迟:SiriKit链路平均600 ms,竞技类游戏预加载+本地缓存关键指令,或把语音降为非实时策略指令(如“切换武器”),避免影响帧同步。
  • 隐私新政:iOS 17引入Sensitive Content Analysis,若游戏允许玩家自定义语音词条,需本地敏感词过滤+上报屏蔽列表,否则4.0条款“ objectionable content”直接下架。