iOS SDK

本文介绍了如何使用阿里云智能语音服务提供的iOS SDK,包括SDK下载安装、关键接口及代码示例。

前提条件

下载安装

  1. 下载SDK和示例代码

    重要

    请下载后在样例初始化代码中替换您的阿里云账号信息、Appkey和Token才可运行。为方便集成,2.5.14版本后iOS接口使用纯Object-C接口,不再使用C++混合接口。

  2. 解压ZIP包,将zip包中的nuisdk.framework添加到您的工程中,并在工程Build Phases的Link Binary With Libraries中添加nuisdk.framework。请确保在编译配置的General > Frameworks, Libraries, and Embedded Content中配置nuisdk.framework为Embed & Sign。

  3. 使用Xcode打开此工程,工程中提供了参考代码以及一些直接可使用的工具类,例如音频播放录制和文件操作,您可以直接复制源码到您的实际工程进行使用。其中录音文件识别极速版示例代码在FileTranscriberViewController类中。

SDK关键接口

  • nui_initialize:初始化SDK。

      /**
       * 初始化SDK,SDK为单例,请先释放后再次进行初始化。请勿在UI线程调用,可能引起阻塞。
       * @param parameters: 初始化参数,参见接口说明文档
       * @param level: log打印级别,值越小打印越多
       * @param save_log: 是否保存log为文件,存储目录为parameter中的debug_path字段值
       * @return 参见错误码
       */
    -(NuiResultCode) nui_initialize:(const char *)parameters
                           logLevel:(NuiSdkLogLevel)level
                            saveLog:(BOOL)save_log;
  • nui_set_params:以JSON格式设置SDK参数。

    /**
     * 以JSON格式设置参数
     * @param params: 参数信息请参见接口说明文档
     * @return 参见错误码
     */
    -(NuiResultCode) nui_set_params:(const char *)params;
  • nui_file_trans_start:发起文件识别请求。

    /**
     * 开始识别
     * @param params:设置识别参数,参考接口说明。
     * @param task_id:开始转写的任务ID,SDK生成随机字符串。
     * @return:参见错误码。
     */
    NuiResultCode nui_file_trans_start(const char *params, char *task_id);
  • nui_file_trans_cancel:取消正在工作的识别任务。

    /**
     * 结束识别
     * @param task_id:需要结束的转写任务ID。
     * @return:参见错误码
     */                    
    NuiResultCode nui_file_trans_cancel(const char *task_id);
  • nui_release:释放SDK。

    /**
     * 释放SDK资源
     * @return 参见错误码
     */
    -(NuiResultCode) nui_release;
  • NeoNuiSdkDelegate事件代理

    onFileTransEventCallback:SDK转写事件回调。

    /**
     * SDK主要事件回调
     * @param nuiEvent: 回调事件,参见如下事件列表
     * @param asrResult: 语音识别结果
     * @param taskId: 一个任务对应的唯一id
     * @param ifFinish: 本轮识别是否结束标志
     * @param retCode: 参见错误码,在出现EVENT_ASR_ERROR事件时有效
     */
    -(void) onFileTransEventCallback:(NuiCallbackEvent)nuiEvent
                           asrResult:(const char *)asr_result
                              taskId:(const char *)task_id
                            ifFinish:(BOOL)finish
                             retCode:(int)code;

    NuiCallbackEvent事件列表:

    名称

    说明

    EVENT_FILE_TRANS_CONNECTED

    连接文件转写服务成功

    EVENT_FILE_TRANS_UPLOADED

    上传文件成功

    EVENT_FILE_TRANS_RESULT

    识别最终结果

    EVENT_ASR_ERROR

    根据错误码信息判断出错原因

调用步骤

  1. 初始化SDK。

  2. 根据业务需求设置参数。

  3. 调用nui_file_trans_start开始识别。

  4. 在EVENT_FILE_TRANS_RESULT事件中获取最终识别结果。

  5. 结束调用,使用release接口释放SDK资源。

代码示例

说明

接口默认采用get_instance方式获得单例,您如果有多例需求,也可以直接alloc对象进行使用。

NUI SDK初始化

//请注意此处的参数配置,其中账号相关需要按照genInitParams的说明填入后才可访问服务
NSString * initParam = [self genInitParams];

[_nui nui_initialize:[initParam UTF8String] logLevel:LOG_LEVEL_VERBOSE saveLog:save_log];

其中,genInitParams生成为String JSON字符串,包含资源目录和用户信息。主要包含如下字段。

-(NSString*) genInitParams {
    NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
    NSString *bundlePath = [[NSBundle bundleWithPath:strResourcesBundle] resourcePath];
    NSString *id_string = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    NSString *debug_path = [_utils createDir];
    TLog(@"id: %s", [id_string UTF8String]);

    //获取token方式:
    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];

    //账号和项目创建
    //  ak_id ak_secret app_key如何获得,请查看https://help.aliyun.com/document_detail/72138.html
    [dictM setObject:@"<您申请创建的app_key>" forKey:@"app_key"]; // 必填

    //方法1:
    //  首先ak_id ak_secret app_key如何获得,请查看https://help.aliyun.com/document_detail/72138.html
    //  然后请看 https://help.aliyun.com/document_detail/466615.html 使用其中方案一获取临时凭证
    //  此方案简介: 远端服务器使用以下方法获得有效时限的临时凭证, 下发给移动端进行使用, 保证账号信息ak_id和ak_secret不被泄露
    //  获得Token方法(运行在APP服务端): https://help.aliyun.com/document_detail/450255.html?spm=a2c4g.72153.0.0.79176297EyBj4k
    [dictM setObject:@"<服务器生成的具有时效性的临时凭证>" forKey:@"token"]; // 必填

    //方法2:
    //  STS获取临时凭证方法暂不支持

    //方法3:(强烈不推荐,存在阿里云账号泄露风险)
    //  参考NuiSdkUtils类的实现在端上访问阿里云Token服务获取SDK进行获取。请勿将ak/sk存在本地或端侧环境。
    //  此方法优点: 端侧获得Token, 无需搭建APP服务器。
    //  此方法缺点: 端侧获得ak/sk账号信息, 极易泄露。
    //    [_utils getTicket:dictM];

    //工作目录路径,SDK从该路径读取配置文件
    [dictM setObject:bundlePath forKey:@"workspace"]; // 必填
    //debug目录。当初始化SDK时的save_log参数取值为true时,该目录用于保存中间音频文件
    [dictM setObject:debug_path forKey:@"debug_path"];
    [dictM setObject:id_string forKey:@"device_id"]; // 必填, 推荐填入具有唯一性的id, 方便定位问题
    [dictM setObject:@"https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer" forKey:@"url"]; // 必填

    //FullMix = 0   // 选用此模式开启本地功能并需要进行鉴权注册
    //FullCloud = 1 // 在线实时语音识别可以选这个
    //FullLocal = 2 // 选用此模式开启本地功能并需要进行鉴权注册
    //AsrMix = 3    // 选用此模式开启本地功能并需要进行鉴权注册
    //AsrCloud = 4  // 在线一句话识别可以选这个
    //AsrLocal = 5  // 选用此模式开启本地功能并需要进行鉴权注册
    [dictM setObject:@"1" forKey:@"service_mode"]; // 必填

    NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

开始识别

调用nui_file_trans_start接口开启识别。

char task_id[33] = {0};
[_nui nui_file_trans_start:param:[param_string UTF8String] taskId:task_id];

回调处理

onFileTransEventCallback:文件识别事件回调,请勿在事件回调中调用SDK的接口,可能引起死锁。

-(void)onFileTransEventCallback:(NuiCallbackEvent)nuiEvent
                      asrResult:(const char *)asr_result
                         taskId:(const char *)task_id
                       ifFinish:(bool)finish
                        retCode:(int)code {
    TLog(@"onNuiEventCallback event %d finish %d", nuiEvent, finish);
    if (nuiEvent == EVENT_FILE_TRANS_CONNECTED) {
        [myself showAsrResult:@"连接成功,正在上传..."];
    } else if (nuiEvent == EVENT_FILE_TRANS_UPLOADED) {
        [myself showAsrResult:@"完成上传,正在转写..."];
    } else if (nuiEvent == EVENT_FILE_TRANS_RESULT) {
        NSString *result = [NSString stringWithUTF8String:asr_result];
        [myself showAsrResult:result];
    } else if (nuiEvent == EVENT_ASR_ERROR) {
        TLog(@"EVENT_ASR_ERROR error[%d]", code);
        NSString *result = [NSString stringWithUTF8String:asr_result];
        [myself showAsrResult:result];
    }

    if (finish) {
        // 任务完成
        [myself showStart];
    }
    return;
}      

取消识别

[_nui nui_file_trans_cancel:[task_id UTF8String]];

常见问题

iOS是否支持后台处理?

SDK本身不限制前后台,iOS SDK的样例工程默认仅支持前台处理,如果您需要支持后台处理,可以做如下修改:

  1. 在工程Info.list中添加Required background modes配置,并在该配置下添加Item,Value设置为App plays audio or streams audio/video using AirPlayios导入头部文件失败

  2. 在录音模块中进入后台时,不停止录音。亦即NLSVoiceRecorder.m中_appResignActive接口中不做停止录音调用。iOS是否支持后台处理

下载语音交互iOS SDK至本地静态库,运行Demo程序测试代码时,模拟器可以正常运行,真机无法运行,报错“Reason: no suitable image found. Did find:xxx”如何解决?

建议您删除手机上对应的APP后,执行xcode clean,并重新尝试运行。除此以外,还需检查签名的正确性,如果签名不正确,需撤销原来的inHouse证书,重新制作新的证书和provisioning profile,并将代码重新签名,再次打包。

iOS端集成nuisdk运行报mic错误如何处理?

请检查当前录音设备是否被占用。

使用智能语音服务集成iOS SDK,接入nuisdk.framework后,导入头文件#import "nuisdk.framework/Headers/NeoNui.h"后项目报错如何解决?

一般情况下是SDK导入有问题导致,请您确认下图参数是否已勾选,如果已勾选,建议您将头文件导入方式换为#import <nuisdk/NeoNui.h>ios导入头部文件失败

按照文档使用SDK接入后报错“/Users/admin/FlashTranscription_iOS/Fc_ASR.xcodeproj Building for iOS, but the linked and embedded framework 'nuisdk.framework' was built for iOS + iOS Simulator."”如何解决?

可能因为版本过高导致,建议您修改项目配置Validate WorkspaceYes后,重新编译。按照文档使用SDK接入后报错

使用集成语音服务iOS SDK,集成flutter_plugin时报错“Undefined symbols for architecture arm64: "std::__1::mutex::~mutex()", referenced from: ___cxx_global_var_init in libflutter_tts.a(ringBuf.o)”如何解决?

您可以打开iOS工程下的Podfile文件,修改post_install do |installer|部分的代码,再次执行构建即可成功。集成语音服务报错

TRTC实时音视频和语音识别结合,当同时调用麦克风时可能会发生冲突,导致有一方没有声音如何解决?

建议尝试TRTC的音视频流,然后使用localStream.getAudioTrack获取MediaStreamTrack对象,并转换为符合ASR标准的音频流,然后通过语音识别SDK发起请求。

使用App集成iOS SDK,提交到App store失败,提示“Unsupported Architectures. The executable for AliYunSmart.app/Frameworks/nuisdk.framework contains unsupported architectures '[x86_ _64, i386]'. With error code”如何解决?

可能是模拟器架构影响,您可以参考如下方法查看framework版本并移除framework模拟器架构。

  1. 进入到framework目录。

  2. 输入命令lipo -info xxxFramework,查看framework的架构版本,如果含有模拟器打包需要把模拟器架构移除。

使用集成语音服务iOS SDK,接入nuisdk.framework后报错,要修改Legacy Build system才可以运行,如何解决?

建议您修改项目配置Validate WorkspaceYes后,重新编译。按照文档使用SDK接入后报错