iOS SDK

本文介绍如何使用无影云手机iOS SDK。

1. 版本发布记录

版本号

发布日期

修改内容

已知主要问题

3.1.2022071802

20220718

  • 云手机基础功能

  • 手势缩放功能

  • 文本/图片双向拷贝

  • 支持Touch、鼠标和键盘

  • 音视频上下行

  • 分辨率设置

  • 日志和埋点

  • 不支持自动重连

  • 不支持区域流

  • 不支持替换媒体引擎

3.1.2022083010

20220930

  • 支持自动重连

  • 支持多会话

  • 支持蓝牙耳机

  • 支持分辨率切换

3.2.11

20220516

  • 支持区域流

  • 支持超分

  • 支持云端Touch

  • 支持云应用

  • 支持网络重定向

2. ASP iOS SDK 使用方法

2.1 集成环境要求

最低支持iOS版本:10.0

由于iOS系统相关接口的开放,外设鼠标和键盘功能,要求iOS最低版本:13.4

2.2 主要文件

ASPEngineSDK公开的头文件

功能描述

ASPStreamView.h

该类封装了ASPEngineSDK,在此基础上定义了高度集成ASP能力的增强型UI组件,通过这些组件,开发人员能够更快速地搭建整合了ASP能力的应用程序。

  • 具备云手机视图

  • 支持响应用户的手势、鼠标和键盘能力

  • 支持响应前后台暂停和恢复云手机

  • 支持响应音频打断和恢复能力

ASPEngineSDK.h

定义了操作ASP的核心API,通过该类,应用程序可实现对ASP关键流程的控制,如启动/停止流,暂停/恢复流,注入输入事件,接收事件消息等。

2.3 集成与使用SDK

2.3.1 SDK集成

二方:通过Pod集成SDK
  1. Podfile文件里添加库依赖,例如:

    pod 'ASPEngineSDK' '3.1.2022071802'
  2. 安装tpod环境(只需要安装一次)。

    sh <(curl http://tpm.taobao.net/taobaoSetup.sh) # 比较耗时,需要等待执行完成
  3. 在根目录下执行Pod工程。

    tpod install --verbose # 比较耗时,需要等待执行完成 (失败的话,可以删除Pods目录重试)
    tpod update --fast-mode --build-target=Debug,Release # 更新本地Pods
三方:通过集成framework接入SDK
  1. 真机包

    asp-sdk-publish/sdk/asp-engine/ios/ASPEngineSDK/3.1.2022071802/ASPEngineSDK.framework.zip
  2. 模拟器包

    asp-sdk-publish/sdk/asp-engine/ios/ASPEngineSDK_Simulator/3.1.2022071803/ASPEngineSDK.framework.zip
  3. 目录3.1.20220718023.1.2022071803是生成SDK库对应的版本号信息。

  4. 将真机包或模拟器包对应的framework拷贝到自己的工程中。

  5. Link SDK库。

    target --> Build Phases --> Link Binary With Libraries --> + --> Add Other -- Add Files -->选择对应的framework
  6. 设置Embed。

    target --> General --> Frameworks, Libraries, and Embeddded Content --> 找到ASPEngineSDK.framework --> Embed Without Signing

2.3.2 SDK权限

工程info.plist配置ASPEngineSDK需要的权限。

1. 录音权限
Privacy - Microphone Usage Description
2. 相机权限
Privacy - Camera Usage Description

2.3.3 SDK签名

SDK库是动态库,真机调试或发布App Store时,需要签名。

1. KEY文件签名

参考demo工程目录下的KEY配置进行签名,默认KEY文件是空的,可在KEY文件里配置一个签名ID,修改方法:

1.1 命令修改

在命令窗口,cd工程目录,然后执行下面命令进行修改:

echo "8AEF20DC6E0CBFF4FA852118BCDD6D507F5764ED" > KEY

1.2 手动修改

在工程里,找到KEY文件,以文本编辑器打开并修改。

2. 如何获取签名ID

通过以下命令,查找自己本机安装证书的签名ID:

security find-identity -v -p codesigning

若没有本机安装证书,可以登录Apple开发者账号,下载对应证书的授权文件Profiles,下载后,选中文件右键,右键菜单选择显示简介,在预览处会显示此授权文件关联的所有证书信息,找到对应证书的信息,里面SHA-1对应的值就是我们需要签名ID。

3. Signing & Capabilities签名

需清空KEY文件配置的签名ID,然后在工程target里正确配置Signing & Capabilities里的证书即可。

4. 添加签名shell(模拟器不需要,真机需要)
target --> Build Phases --> + --> New Run Script Phase --> 填写sh内容,参考签名示例 --> 添加KEY文件,在Input Files处,点击+,填写$(SRCROOT)/KEY
注意:此Run Script必现在Embed Frameworks下面。
5. 签名示例
set -e
SHELL_PATH="${PROJECT_DIR}/ASPDemo/Lib/ASPEngineSDK/3.1.2022063002-SNAPSHOT/ASPEngineSDK.framework/link_and_sign.sh"
while read -r line; do
exit 0
done < ${SCRIPT_INPUT_FILE_0}
echo "===> Signing using $line"
/bin/bash -c "${SHELL_PATH}"\ "${TARGET_BUILD_DIR}"\ "${FRAMEWORKS_FOLDER_PATH}"\ "${line}"

2.3.4 工程配置注意事项

关闭Bitcode

target --> Build Settings --> Build Options --> Enable Bitcode -->设置No

2.3.5 SDK核心API使用示例

说明

以下示例代码中的desktopId请传入应用实例ID(格式:ai-0cc7s3n1iagyq****)。应用实例ID可通过调用云手机的DescribeAndroidInstances - 查询实例详细信息接口或云应用的GetConnectionTicket - 获取应用连接凭证接口获取。

- (void)viewDidLoad {
    [super viewDidLoad];

    #设置log回调,SDK日志通过此回调输出
    [ASPStreamView setASPEngineLogDelegate:[ASPDemoLog sharedInstance]];
    #创建对象并开始连接云手机
    ASPStreamView* streamView = [ASPStreamView buildStreamView];
    [streamView setASPEngineDelegate:self];
    if (self.connParam.connTicket) {
        ASPConnTicket* ticketParam = [[ASPConnTicket alloc] init];
        ticketParam.connTicket = self.connParam.connTicket;
        ticketParam.useVpc = false;
        ticketParam.enableStatistics = true;
        ticketParam.desktopId = self.connParam.desktopId;
        [streamView startWithTicket:ticketParam];
    } else {
        ASPConnParam* connParam = [[ASPConnParam alloc] init];
        connParam.connIp = self.connParam.connIp;
        connParam.connPort = self.connParam.connPort;
        connParam.connUdpPort = self.connParam.connUdpPort;
        connParam.connToken = self.connParam.connToken;
        connParam.enableTls = self.connParam.enableTls;
        connParam.desktopId = self.connParam.desktopId; 
        connParam.enableStatistics = true;
        [streamView start:connParam];
    }
    self.streamView = streamView;
    [self.view addSubview:streamView];
    //埋点回调
    [self.streamView setASPEngineStatisticsDelegate:self];
}

- (void)onConnectionSuccess {
    NSLog(@"云手机连接成功回调");
}

- (void)onDisconnected:(int)reason {
    //reason 2000-断开成功 2001~2009-云上主动断开的状态码 2001~2005-含义请查看下面错误说明 2006~2009-预留定义,暂时没有含义
    NSLog(@"云手机已断开连接回调");
}

- (void)onReconnect {
    NSLog(@"云手机在自动重连回调");
}

- (void)onConnectionFailureWithErrCode:(int)errCode errMsg:(NSString *)errMsg {
    NSLog(@"云手机报错回调");
}

- (void)onEngineErrorWithErrCode:(int)errCode errMsg:(NSString *)errMsg {
    NSLog(@"ASPEngineSDK内部逻辑出现错误");
}

- (void)onStatisticsInfoUpdate:(StatisticsInfo)info {
    NSLog(@"埋点回调");
}

3. 接口定义及说明

3.1 ASPEngineSDK

3.1.1 ASPStreamView.h

3.1.1.1 init

初始化接口。

+ (instancetype)buildStreamView;
3.1.1.2 start

通过指定的server连接参数,连接云手机。

1)通过从PaaS获取的server session启动串流服务。

- (void)startWithTicket:(ASPConnTicket*) ticketParam;

ASPConnTicket参数说明:

connTicket

应用通过PaaS API从管控获取的serverSession

caFilePath

CA文件的绝对路径,用于TLS通信加密

desktopId

请传入应用实例ID(格式:ai-0cc7s3n1iagyq****)。应用实例ID可通过调用云手机的DescribeAndroidInstances - 查询实例详细信息接口或云应用的GetConnectionTicket - 获取应用连接凭证接口获取。

useVpc

是否通过企业专网进入

enableTls

是否进行加密传输(建议设为YES)

enableStatistics

是否开启埋点(建议设为YES)

3.1.1.3 stop

断开云手机接口。

- (int)stop;
3.1.1.4 dispose

销毁云手机对象。

- (void)dispose;
3.1.1.5 delegate
//云手机连接相关回调
@property (nonatomic, weak) id<ASPEngineDelegate> engineDelegate;
//分辨率发生变化回调
@property (nonatomic, weak) id<ASPEngineResolutionUpdateDelegate> resolutionUpdateDelegate;
//鼠标光标相关回调
@property (nonatomic, weak) id<ASPEngineCursorDelegate> cursorDelegate;
//云手机方向发生变化回调
@property (nonatomic, weak) id<ASPEngineOrientationUpdateDelegate> orientationUpdateDelegate;
//埋点相关回调
@property (nonatomic, weak) id<ASPEngineStatisticsDelegate> statisticsDelegate;
//输入法相关回调
@property (nonatomic, weak) id<ASPEngineIMEDelegate> imeDelegate;
//LOG相关回调,delegate建议使用单例
+ (void)setASPEngineLogDelegate:(id<ASPEngineLogDelegate>)delegate;
+ (void)unsetASPEngineLogDelegate;
3.1.1.6 enableStatistics

是否开启埋点。

- (BOOL)enableStatistics:(BOOL) enabled;
3.1.1.7 enableMouseMode

是否开启鼠标模式。

- (BOOL)enableMouseMode:(BOOL)enabled;
3.1.1.8 enableDump

是否开启dump,此功能会消耗性能,只用于开发调试,禁止上线。

@property (nonatomic, assign) BOOL enableDump;
3.1.1.9 sendKeyboardEvent

发送键盘按键事件。

- (BOOL)sendKeyboardEvent: (ASPKeyEvent) event;
3.1.1.10 simulateMouseClick

模拟鼠标点击。

// leftButton是鼠标左键还是右键 鼠标点击位置 x:0 y:0
- (BOOL)simulateMouseClick:(BOOL)leftButton;
- (BOOL)simulateMouseClick:(BOOL)leftButton x:(float)x y:(float)y;
3.1.1.11 setVideoProfileWithWidth

设置分辨率。

- (void)setVideoProfileWithWidth:(int)width height:(int)height fps:(int)fps;
3.1.1.12 setMute

设置是否静音。

@property (nonatomic, assign) BOOL mute;

3.1.2 ASPEngineSDK.h

3.1.2.1 start

通过指定的server连接参数,连接云手机

1)通过从PaaS获取的server session启动串流服务

- (void)startWithTicket:(ASPConnTicket*) ticketParam;

ASPConnTicket参数说明:

connTicket

应用通过PaaS API从管控获取的serverSession

caFilePath

CA文件的绝对路径,用于TLS通信加密

desktopId

请传入应用实例ID(格式:ai-0cc7s3n1iagyq****)。应用实例ID可通过调用云手机的DescribeAndroidInstances - 查询实例详细信息接口或云应用的GetConnectionTicket - 获取应用连接凭证接口获取。

useVpc

是否通过企业专网进入

enableTls

是否进行加密传输(建议设为YES)

enableStatistics

是否开启埋点(建议设为YES)

2)通过指定的server连接参数启动云端的串流服务

该方法通常用于日常调试,适用于不经过网关(或已知网关地址并得到可访问的token),能够直联ASP Server的情形

- (void)start:(AspConnParam*) connParam;

AspConnParam参数说明:

connIp

网关域名或IP

connPort

网关端口

connUdpPort

UDP端口号,用于RTC数据传输,通常与connPort一致

connToken

用于访问网关的token,通常是由参与联调负责网关的人员提供

connTicket

应用通过PaaS API从管控获取的serverSession

caFilePath

CA文件的绝对路径,用于TLS通信加密

desktopId

请传入应用实例ID(格式:ai-0cc7s3n1iagyq****)。应用实例ID可通过调用云手机的DescribeAndroidInstances - 查询实例详细信息接口或云应用的GetConnectionTicket - 获取应用连接凭证接口获取。

enableTls

是否进行加密传输(建议设为YES)

enableStatistics

是否开启埋点(建议设为YES)

3.1.2.2 stop

断开云手机接口

- (int)stop;
3.1.2.3 pause

暂停云手机接口

- (void)pause;
3.1.2.4 resume

恢复云手机接口

- (void)resume;
3.1.2.5 setRenderView

设置云手机视图容器接口

- (void)setRenderView:(UIView*) view;
3.1.2.6 dispose

销毁云手机对象

- (void)dispose;
3.1.2.7 enableRTC

是否使用RTC传输

- (void)enableRTC:(bool) enabled;
3.1.2.8 enableVDAagentCheck

是否check VDAagent

- (void)enableVDAagentCheck:(bool) enabled;
3.1.2.9 enableStatistics

是否开启埋点

- (BOOL)enableStatistics:(BOOL) enabled;
3.1.2.10 dump

dump相关接口,dump只用于开发联调,比较耗性能,禁止上线

- (void)setDumpPath:(NSString *)path;

@property (nonatomic, assign) BOOLenableDump;
3.1.2.11 delegate

各类相关回调

//云手机连接相关回调
@property (nonatomic, weak) id<ASPEngineDelegate> engineDelegate;
//分辨率发生变化回调
@property (nonatomic, weak) id<ASPEngineResolutionUpdateDelegate> resolutionUpdateDelegate;
//鼠标光标相关回调
@property (nonatomic, weak) id<ASPEngineCursorDelegate> cursorDelegate;
//云手机方向发生变化回调
@property (nonatomic, weak) id<ASPEngineOrientationUpdateDelegate> orientationUpdateDelegate;
//埋点相关回调
@property (nonatomic, weak) id<ASPEngineStatisticsDelegate> statisticsDelegate;
//输入法相关回调
@property (nonatomic, weak) id<ASPEngineIMEDelegate> imeDelegate;
//剪贴板相关回调
@property (nonatomic, weak) id<ASPEngineClipboardDelegate> clipboardDelegate;
//手势缩放相关回调
@property (nonatomic, weak) id<ASPEngineGestureDelegate> gestureDelegate;
//日志相关回调
@property (class, nonatomic, weak) id<ASPEngineLogDelegate> logDelegate;
3.1.2.12 setVideoProfileWithWidth

设置云手机分辨率

- (void)setVideoProfileWithWidth:(int)width height:(int)height fps:(int)fps; //视频流目标fps,目前不生效
3.1.2.13 touch

发送Touch事件

- (void)sendTouchEvent:(ASPTouchEvent*)event touchAction:(ASPTouchAction)action;

- (void)sendTouchEvents:(NSArray<ASPTouchEvent*>*) eventArray touchAction:(ASPTouchAction)action index:(int)index;
3.1.2.14 keyboard

发送Keyboard事件

- (BOOL)sendKeyboardEvent: (ASPKeyEvent) event;

// Caps/Num/Scroll Lock
- (void)sendKeyboardLockModifiers: (int) modifers;
3.1.2.15 mouse

是否开启鼠标模式

- (BOOL)enableMouseMode:(BOOL) enabled;

发送Mouse相关事件

- (void)sendMouseButtonEvent: (ASPMouseButtonEvent)event;

- (void)sendMouseMoveEvent: (ASPMouseMoveEvent)event;

- (void)sendMouseWheelEvent:(int)delta buttonState:(ASPMouseButtonMask)buttonState;
3.1.2.16 ime

发送Ime相关事件

- (void)setImePreedit: (NSString*)preeditStr;

- (void)setImeCommit: (NSString*)commitStr;
3.1.2.17 clipboard

发送剪贴板事件

- (void)sendClipboardType:(int)type;

type 参数:

enum ASPEngineClipboardType {
    ASPENGINE_CLIPBOARD_NONE = 0,
    ASPENGINE_CLIPBOARD_UTF8_TEXT,
    ASPENGINE_CLIPBOARD_IMAGE_PNG,  /* All clients with image support should support this one */
    ASPENGINE_CLIPBOARD_IMAGE_BMP,  /* optional */
    ASPENGINE_CLIPBOARD_IMAGE_TIFF, /* optional */
    ASPENGINE_CLIPBOARD_IMAGE_JPG,  /* optional */
};
3.1.2.18 ASPEngineDelegate

云手机连接相关回调

@protocol ASPEngineDelegate <NSObject>
// engine内部错误
- (void)onEngineErrorWithErrCode:(int)errCode errMsg:(NSString*)errMsg;
// 云手机连接成功
- (void)onConnectionSuccess;
// 云手机连接失败
- (void)onConnectionFailureWithErrCode:(int)errCode errMsg:(NSString*)errMsg;
// 云手机已断开连接
- (void)onDisconnected:(int)reason;
// 云手机第一帧回调
- (void)onFirstFrameRendered:(long)timeCostMS;
// 云手机正在重连
- (void)onReconnect;

@end
3.1.2.19 ASPEngineResolutionUpdateDelegate

云手机分辨率发生变化回调

@protocol ASPEngineResolutionUpdateDelegate <NSObject>

- (void)onResolutionUpdateWithOldWidth:(int)oldWidth oldHeight:(int)oldHeight
width:(int)width height:(int)height;

@end
3.1.2.20 ASPEngineCursorDelegate

云手机光标形态发生变化回调

@protocol ASPEngineCursorDelegate <NSObject>
//当云上光标形态变化时
- (void)onCursorBitmapUpdateWithHotX:(int)hotX hotY:(int)hotY width:(int)width
height:(int)height rgba:(char*)rgba;
//当云上光标状态被重置时
- (void)onCursorReset;
//当云上光标被隐藏时
- (void)onCursorHide;
//当云上光标位置发生变化时
- (void)onCursorMoveWithX:(int)x y:(int)y;
@end
3.1.2.21 ASPEngineOrientationUpdateDelegate

监听云上屏幕旋转事件

@protocol ASPEngineOrientationUpdateDelegate <NSObject>

- (void)onOrientationUpdateWithOldOrientation:(int)oldOrientation newOrientation:(int)newOrientation;

@end
3.1.2.22 ASPEngineStatisticsDelegate

用于监听性能及关键运行状态数据报告

@protocol ASPEngineStatisticsDelegate <NSObject>

- (void)onStatisticsInfoUpdate:(ASPStatisticsInfo *)info;

@end

ASPStatisticsInfo 参数说明:

@interface ASPStatisticsInfo : NSObject

@property (nonatomic, assign) int mReceiveFps; // 端侧每秒接收到的视频祯数量
@property (nonatomic, assign) int mRenderFps; // 端侧渲染FPS
@property (nonatomic, assign) double mDownstreamBandwithMBPerSecond; // 下行带宽,MB/s
@property (nonatomic, assign) double mUpstreamBandwithMBPerSecond; // 上行带宽,MB/s
@property (nonatomic, assign) long mP2pFullLinkageLatencyMS; // 端到端全链路时延,毫秒
                                           // 目前该值需要在guest os中使用特定应用才可准确表示
@property (nonatomic, assign) long mNetworkLatencyMS; // 网络rtt时延,毫秒
@property (nonatomic, assign) long mPingGatewayRtt;   // Ping rtt时延,毫秒
@property (nonatomic, assign) double mLostRate; // 丢包率
@property (nonatomic, assign) long mServerRenderLatencyMS; // 服务端渲染时延,毫秒
@property (nonatomic, assign) long mServerEncoderLatencyMS; // 服务端编码时延,毫秒
@property (nonatomic, assign) long mServerTotalLatencyMS; // 服务端总时延,毫秒
@property (nonatomic, assign) long accumulateBandwidth; //总带宽
@property (nonatomic, copy  ) NSString *protocolType; //流协议类型

@property (nonatomic, copy  ) NSDictionary *infoDic;

@end
3.1.2.23 ASPEngineIMEDelegate

用于监听云上输入框焦点变化及输入法UI位置状态

@protocol ASPEngineIMEDelegate <NSObject>

//当云上输入框获取/失去焦点时
- (void)onIMEFocusUpdate:(bool)hasFocus;
//当云上输入法UI的位置发生变化时时
- (void)onIMELocationUpdateWithX:(int)x y:(int)y;

@end
3.1.2.24 ASPEngineClipboardDelegate

用于监听云上剪贴板读取端侧数据或写入数据到端侧

@protocol ASPEngineClipboardDelegate <NSObject>

//云手机粘贴时,从端侧读取数据
- (void)onClipBoardRead:(int)engineId type:(int *)type data:(uint8_t**)data size:(int *) size selection:(uint8_t)selection;
//云手机复制时,写入数据到端侧
- (void)onClipBoardWrite:(int)engineId type:(int)type data:(uint8_t*)data size:(int)size;

@end
3.1.2.25 ASPEngineGestureDelegate

用于监听手势缩放和移动(双指操作)

@protocol ASPEngineGestureDelegate <NSObject>

- (void)onScale:(float)sx sy:(float)sy;
- (void)onTranslate:(float)tx ty:(float)ty;

@end
3.1.2.26 ASPEngineLogDelegate

日志输出回调

@protocol ASPEngineLogDelegate <NSObject>

- (void)onLogMessage:(NSString*)msg tag:(NSString*)tag level:(AspLogLevel)level;

@end
3.1.2.27 mute

设置是否静音

@property (nonatomic, assign) BOOL mute;

4. 错误码说明

错误码

错误消息(%s表示云手机或云应用)

定义模块

原因

2~26主要是网络相关问题

2

连接%s失败

ASP SDK

无效MAGIC

3

连接%s失败

ASP SDK

数据有误

4

客户端与服务端版本不匹配

ASP SDK

版本不匹配

5

连接需要 TLS

ASP SDK

需要TLS

6

连接不需要 TLS

ASP SDK

不需要TLS而实际使用了TLS

7

您没有权限连接当前%s

ASP SDK

权限问题

8

ASP SDK

迁移过程中client ID无效

9

连接%s失败

ASP SDK

channel不存在

20

连接ASP服务器失败。

ASP SDK

channel 连接错误

21

TLS认证出错了

ASP SDK

TLS 认证错误

22

连接%s失败

ASP SDK

channel link 错误

23

连接%s失败

ASP SDK

连接认证错误

24

连接%s失败

ASP SDK

连接IO错误

25

连接%s失败

ASP SDK

连接网关失败

26

ASP SDK

xquic 握手失败

连接中断开或遇到某些错误的情况

2000

获取%s数据超时,与服务端断开连接

ASP SDK

正常断开

2001

%s已与服务端断开连接。可能是因为%s进程已被强制终止。

ASP SDK

一般是端上应用被终止进程了,如Android应用用户通过按下Home键终止

2002

已有用户从其他终端连接当前%s。请稍后重试。

ASP SDK

其他人抢占了端

2003

%s正在关机或重启,一般由管理员操作,请稍后重试。

ASP SDK

云手机被关机或重启,一般是管理员操作

2005

%s已超时断开连接,因为已达到管理员设置的使用时长限制。

ASP SDK

管理员设置使用时长被关

2010

连接%s失败

ASP SDK

Vdagent连接失败

2011

连接参数传递错误。

ASP SDK

连接server参数传递错误

2100

剪切板权限,禁止从%s到本地

ASP SDK

剪贴板权限,禁止从 VM到本地

2101

剪切板权限,禁止从本地到%s

ASP SDK

剪贴板权限,禁止从本地到 VM

2200

%s正在尝试重连...

ASP SDK

因为网络问题断开了,ASP SDK正在重连

2201

您的设备出现网络异常,导致%s已断开连接。

ASP SDK

因为网络问题断开了,ASP SDK因为镜像原因不支持重连,应用侧开始重连

2202

%s重连超时,请检查设备网络后重试。

ASP SDK

ASP SDK重连超时

端侧逻辑错误

5100

%s连接ASP Server超时,请稍后重试。

应用侧

端侧在一段时间内未接收到connected事件

5102

获取%s数据超时,请稍后重试。

应用侧

端侧在一段时间内接收到了connected但未接收到display事件

5004

客户端出现错误,请重新打开

应用侧

传入端侧启动参数有误,一般出现在开发阶段

5200

客户端重连超时,请稍后重试。

应用侧

5. 附件

5.1 demo

iOSDemo.zip

5.2 sdk

iOSSDK.zip

说明

下载和使用即表示您认可《无影云电脑SDK隐私权政策》

本平台所有文档、SDK、客户端程序仅限于本人或本企业使用,未经阿里云同意不会转发给第三方个人或企业。