物联网开发平台 iOS(集成与登录)

如何在 iOS 平台集成腾讯云物联网(IoT)应用端 SDK 并完成登录:涵盖工程配置、SDK 引入、登录签名计算与登录调用,并通过拉取家庭列表验证接入是否成功。设备绑定、设备分享、远程控制等能力在登录完成后按需接入。

相关产品
物联网开发平台 产品页,含版本规格、价格与购买入口。

二、开通服务

请先按照 开通服务 文档,完成服务开通和应用创建,并获取以下信息:

·AppKey:登录必需。

·AppSecret:登录必需,用于计算登录签名。

·ProductId:接入设备绑定、物模型等能力时使用,这篇不涉及。

·DeviceName:接入设备绑定、物模型等能力时使用,这篇不涉及。

三、环境准备

·Xcode 11.0 及以上版本。

·确保项目已设置有效的开发者签名。

·一台 iOS 12.0 及以上真机(与 Podfile 的 platform :ios, '12.0' 配置保持一致)。

四、创建项目

参考以下步骤创建一个新的 iOS 项目。如果已有项目,可跳过本节。

1. 打开 Xcode,选择 New Project(新建项目)。

2. 在平台标签中选择 iOS,然后选择 App 模板,单击 Next。

3. 在 Choose options for your new project 页面设置 Product Name、Team、Organization Identifier 等项目基本信息,单击 Next 并选择保存路径,最后单击 Create 完成创建。

五、集成 SDK

1. 在项目根目录的 Podfile 中添加 IoT SDK 依赖:

注意:说明:

注意:Podfile 是 iOS 项目的 CocoaPods 依赖配置文件,位于项目根目录(与 .xcodeproj 同级),用文本编辑器编辑即可。如果目录下没有 Podfile,先在终端进入项目目录执行 pod init 生成。

# 将下方的 'YourApp' 替换为你 Xcode 项目中实际的 Target 名称platform :ios, '12.0'target 'YourApp' do # 物联网应用端 SDK pod 'TXLiteAVSDK_IOT', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_IOT.podspec'end

Xcode 16 兼容性问题:若使用 Xcode 16 及以上版本,pod install 后可能报部署目标版本错误。请在 Podfile 末尾添加以下配置解决:

post_install do |installer| installer.pods_project.build_configurations.each do |config| config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' end installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' end endend

2. 完成配置后,在终端执行 pod install,SDK 将自动下载并集成到工程中。

3. pod install 完成后,在 Finder 中找到项目目录下的 .xcworkspace 文件并双击打开(请打开 .xcworkspace 而非 .xcodeproj)。

4. 在 Xcode 的 Build Settings 中搜索 User Script Sandboxing,将其值设置为 No。

5. 在 Signing & Capabilities 中确认已配置有效的开发者签名。

七、步骤 1:获取 SDK 实例

调用 TXIoTEngine.getInstance 获取 SDK 实例,并注册 TXIoTEngineDelegate 监听登录、签名过期和设备状态推送。

// 获取单例实例TXIoTEngine *iotEngine = [TXIoTEngine getInstance];// 注册监听(self 需遵循 TXIoTEngineDelegate 协议)[iotEngine addDelegate:self];

在监听对象中实现 TXIoTEngineDelegate 协议方法:

#pragma mark – TXIoTEngineDelegate- (void)onLoginSuccess { // 登录成功}- (void)onLoginFailure:(TXIoTErrorCode)errCode errMsg:(NSString *)errMsg { // 登录失败}- (void)onUserSignatureExpired { // 登录签名过期,请重新计算签名后再次调用 login}- (void)onReceivePushMessage:(TXIoTPushMessage *)pushMessage { // 接收设备在线、离线等状态变更}

八、步骤 2:计算登录签名

注意:说明:

注意:快速接入阶段可直接在客户端计算签名进行调试。正式上线时请将签名计算逻辑放在业务后台,不要将 AppSecret 保存在客户端。

九、签名参数

参与签名的参数:

参数 说明
RequestId 唯一请求 ID,建议使用 UUID。
Timestamp 当前 UNIX 秒级时间戳。
Nonce 随机正整数,用于和时间戳一起防重放。
AppKey 从 开通服务 文档获取的 AppKey。
OpenID 用户标识,需与后续登录的 userId 保持一致。支持数字、字母、下划线,长度不超过 32 字节。

注意:OpenID 与 UserID 的关系:签名参数名为 OpenID,SDK 登录接口参数名为 userId,两者是同一个东西,值必须保持一致。

十、签名计算规则

1. 去掉值为空的参数。

2. 将参数按参数名的字典序升序排列。

3. 将排序后的参数按 Key=Value 格式拼接。

4. 使用 & 连接所有参数,得到签名原文。

5. 使用从 开通服务 文档获取的 AppSecret 对签名原文进行 HMAC-SHA1 签名。

6. 对签名结果进行 Base64 编码,得到最终 Signature。

十一、签名计算示例

例如,参与签名的参数如下:

RequestId=8b8d499bbba1ac28b6da21b4Timestamp=1546315200Nonce=71087795AppKey=your_app_keyOpenID=user_001

排序后的签名原文:

AppKey=your_app_key&Nonce=71087795&OpenID=user_001&RequestId=8b8d499bbba1ac28b6da21b4&Timestamp=1546315200

使用 your_app_secret 作为 AppSecret 对上述原文计算,期望得到的签名为 aSLzd4Ett7RsiLhrYht6Yk9+0qY=,可用于自验签名实现是否正确。

参考以下示例计算签名。客户端示例基于系统自带的 CommonCrypto 框架;正式上线时签名在业务后台计算,参考服务端示例:

客户端(Objective-C)

#import <CommonCrypto/CommonHMAC.h>+ (NSString *)generateSignatureWithAppSecret:(NSString *)appSecret requestId:(NSString *)requestId timestamp:(int64_t)timestamp nonce:(NSInteger)nonce appKey:(NSString *)appKey openId:(NSString *)openId { NSDictionary<NSString *, NSString *> *params = @{ @"RequestId": requestId, @"Timestamp": @(timestamp).stringValue, @"Nonce": @(nonce).stringValue, @"AppKey": appKey, @"OpenID": openId, }; // 去掉值为空的参数,按参数名的字典序升序排列 NSArray<NSString *> *sortedKeys = [params.allKeys sortedArrayUsingSelector:@selector(compare:)]; NSMutableArray<NSString *> *pairs = [NSMutableArray array]; for (NSString *key in sortedKeys) { NSString *value = params[key]; if (value.length == 0) { continue; } [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, value]]; } // 按 Key=Value 格式拼接,使用 & 连接 NSString *source = [pairs componentsJoinedByString:@"&"]; // 使用 AppSecret 对签名原文进行 HMAC-SHA1 签名 NSData *keyData = [appSecret dataUsingEncoding:NSUTF8StringEncoding]; NSData *sourceData = [source dataUsingEncoding:NSUTF8StringEncoding]; unsigned char digest[CC_SHA1_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA1, keyData.bytes, keyData.length, sourceData.bytes, sourceData.length, digest); // 对签名结果进行 Base64 编码 NSData *digestData = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; return [digestData base64EncodedStringWithOptions:0];}

import base64import hashlibimport hmacdef generate_signature(app_secret, request_id, timestamp, nonce, app_key, user_id): params = { "RequestId": request_id, "Timestamp": str(timestamp), "Nonce": str(nonce), "AppKey": app_key, "OpenID": user_id, } # 去掉值为空的参数 params = { key: value for key, value in params.items() if value is not None and value != "" } # 按参数名的字典序升序排列 sorted_items = sorted(params.items(), key=lambda item: item[0]) # 按 Key=Value 格式拼接,使用 & 连接 source = "&".join([f"{key}={value}" for key, value in sorted_items]) # 使用 AppSecret 对签名原文进行 HMAC-SHA1 签名 digest = hmac.new( app_secret.encode("utf-8"), source.encode("utf-8"), hashlib.sha1, ).digest() # 对签名结果进行 Base64 编码 signature = base64.b64encode(digest).decode("utf-8") return signaturesignature = generate_signature( app_secret="your_app_secret", request_id="8b8d499bbba1ac28b6da21b4", timestamp=1546315200, nonce=71087795, app_key="your_app_key", user_id="user_001",)print(signature)

十二、Running Environment

Operating System: Ubuntu 24.04.3 LTS / x86_64Runtime Version: Python 3.11.1

十三、步骤 3:登录 SDK

调用 TXIoTEngine.login 登录 SDK,传入上一步计算得到的签名参数。

十四、参数说明

参数 类型 说明
appKey NSString 从 开通服务 文档获取的 AppKey。
userId NSString 用户标识,支持数字、字母、下划线,长度不超过32字节。首次使用会自动注册,已注册则登录原有账号,该账号下的设备绑定关系仍然保留。需与签名参数 OpenID 保持一致。
userSignature.requestId NSString 对应签名参数 RequestId。
userSignature.timestamp int64_t 对应签名参数 Timestamp。
userSignature.nonce NSInteger 对应签名参数 Nonce。
userSignature.signature NSString 签名计算结果。

TXIoTUserSignature *userSignature = [[TXIoTUserSignature alloc] init];userSignature.requestId = requestId;userSignature.timestamp = timestamp;userSignature.nonce = nonce;userSignature.signature = signature;[iotEngine login:appKey userId:userId userSignature:userSignature];

十五、步骤 4:验证登录结果

登录成功后,调用 getFamilyManager 获取家庭管理实例并拉取家庭列表,以此验证登录态与网络链路是否正常。返回的 familyId 是后续绑定设备、查询设备列表的必备参数,请妥善保存。

TXIoTFamilyManager *familyManager = [iotEngine getFamilyManager];if (familyManager == nil) { // SDK 未登录或登录态已失效 return;}TXIoTCallback<NSArray<TXIoTFamilyInfo *> *> *callback = [[TXIoTCallback alloc] init];callback.onSuccess = ^(NSArray<TXIoTFamilyInfo *> * _Nullable familyList) { if (familyList.count == 0) { // 当前账号下没有家庭,调用 createFamily 创建(见下方示例) return; } // 选择一个家庭,记录 familyId NSString *familyId = familyList.firstObject.familyId;};callback.onError = ^(TXIoTErrorCode errorCode, NSString * _Nullable errorMessage) { // 获取家庭列表失败};[familyManager getFamilyList:callback];

如果当前账号下没有家庭,可调用 createFamily 创建:

TXIoTCallback<TXIoTFamilyInfo *> *callback = [[TXIoTCallback alloc] init];callback.onSuccess = ^(TXIoTFamilyInfo * _Nullable familyInfo) { // 创建成功,记录 familyId};callback.onError = ^(TXIoTErrorCode errorCode, NSString * _Nullable errorMessage) { // 创建家庭失败};[familyManager createFamily:@"我的家庭" callback:callback];

十七、为什么 getFamilyManager 或 getDeviceManager 返回 nil?

SDK 尚未登录或登录态已失效。请先调用 TXIoTEngine.login,并在收到 onLoginSuccess 后再获取对应 Manager。

十八、登录签名过期后如何处理?

当收到 onUserSignatureExpired 回调时,请重新计算登录签名,然后再次调用 TXIoTEngine.login。

十九、登录失败或提示签名错误如何排查?

请按以下顺序逐项核对:

1. AppKey 与 AppSecret 是否来自同一个应用且配对正确。

2. 签名参数 OpenID 与登录接口的 userId 是否完全一致。

3. Timestamp 是否为 UNIX 秒级时间戳(非毫秒),且与当前时间偏差在允许范围内。

4. 参与签名的参数是否已去掉空值、并按参数名字典序升序排列后以 & 连接。

5. 签名算法是否为 HMAC-SHA1,且签名结果经过 Base64 编码。

可使用 签名计算示例 中给出的期望输出(aSLzd4Ett7RsiLhrYht6Yk9+0qY=)自验签名实现是否正确。

20、下一步

完成基础接入后,你还可以继续接入以下能力:

·设备绑定

·远程控制

·家庭管理

赞 (0)
上一篇 4天前
下一篇 4天前