全部产品
弹性计算 会员服务 网络 安全 移动云 数加·大数据分析及展现 数加·大数据应用 管理与监控 云通信 阿里云办公 培训与认证 智能硬件
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 更多
消息队列 MQ

MQTT iOS 接入示例

更新时间:2018-01-23 21:00:41

本文主要介绍如何使用 iOS 客户端收发 MQTT 消息,并给出示例代码供前期开发测试参考,包括资源创建、环境准备、示例代码、注意事项等。

注意:

本文给出的实例均基于第三方框架 MQTT-Client-Framework 实现,SDK 下载请参见 MQTT 接入准备。如使用其他第三方的客户端,请自行修改。

资源创建

使用 MQ 提供的 MQTT 服务,首先需要核实应用中使用的 Topic 资源是否已经创建。如果没有,请先去控制台创建 Topic,Group ID 等资源。

创建资源时需要根据需求选择对应的 Region,例如 MQTT 需要使用华北2的接入点,那么 Topic 等资源就在华北2 创建,资源创建具体请参见创建资源

注意: MQTT 使用的多级子 Topic 不需要创建,代码里直接使用即可,没有限制。

环境准备

iOS 环境下开发 MQTT 客户端程序,一般依赖稳定的第三方 FrameWork,由于涉及网络数据传输,建议选择 Object-c 原生的框架,比如 MQTT-Client-Framework 。

第三方 FrameWork 一般可以用 CocoaPods 来管理资源包依赖。具体配置流程如下:

  1. CocoaPods 安装配置

    CocoaPods 依赖 Ruby 等基础环境。请确保安装过 Ruby,然后将国内的镜像源更新为淘宝源,提高资源包下载速度。

    //查看软件源
    gem sources -l
    //清理掉默认的软件源
    gem sources --remove https://rubygems.org/
    //加入淘宝的源
    gem sources -a https://ruby.taobao.org/
    

    更新完地址后,运行以下命令,等待一段时间后即可运行 pod 工具:

    sudo gem install cocoapods

  2. 更新项目依赖

    MQTT-Client-FrameWork 第三方框架支持 pod 管理方式,因此添加依赖只需要在项目根目录的 Podfile 中加入依赖即可,内容如下:

    pod 'MQTTClient'
    target '${yourprojectname}' do
    end
    

    其中 target 填入项目的名称,然后在 Podfile 目录下运行以下命令,更新依赖即可。

    pod install

主要代码示例

初始化客户端

MQTT-Client-FrameWork 包提供的客户端类有 MQTTSession 和 MQTTSessionManager,建议使用后者维持静态资源,而且已经封装好自动重连等逻辑。初始化时需要传入相关的网络参数。具体如下:

        self.manager = [[MQTTSessionManager alloc] init];
        self.manager.delegate = self;
        self.manager.subscriptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:self.qos]
                                                                 forKey:[NSString stringWithFormat:@"%@/#", self.rootTopic]];
        //password的计算方式是,使用secretkey对groupId做hmac签名算法,具体实现参考macSignWithText方法
        NSString *passWord = [[self class] macSignWithText:self.groupId secretKey:self.secretKey];
        [self.manager connectTo:self.mqttSettings[@"host"]
                                  port:[self.mqttSettings[@"port"] intValue]
                                   tls:[self.mqttSettings[@"tls"] boolValue]
                             keepalive:60  //心跳间隔不得大于120s
                                 clean:true
                                  auth:true
                                  user:self.accessKey
                                  pass:passWord
                                  will:false
                             willTopic:nil
                               willMsg:nil
                               willQos:0
                        willRetainFlag:FALSE
                          withClientId:self.clientId];

添加回调接口

针对连接当前状态,添加对应的回调接口,可以进行相关的业务逻辑处理。

[self.manager addObserver:self
                   forKeyPath:@"state"
                      options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                      context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    switch (self.manager.state) {
        case MQTTSessionManagerStateClosed:
            break;
        case MQTTSessionManagerStateClosing:
            break;
        case MQTTSessionManagerStateConnected:
            break;
        case MQTTSessionManagerStateConnecting:
            break;
        case MQTTSessionManagerStateError:
            break;
        case MQTTSessionManagerStateStarting:
        default:
            break;
    }
}

userName 和 passWord 的设置

由于服务端需要对客户端进行鉴权,因此需要传入合法的 userName 和 passWord。userName 设置为当前用户的 AccessKey,password 则设置为 MQTT 客户端 GroupID 的签名字符串,签名计算方式是使用 SecretKey 对 GroupID 做 HmacSHA1 散列加密。具体方法请参考 Demo 中的 macSignWithText 函数。

+ (NSString *)macSignWithText:(NSString *)text secretKey:(NSString *)secretKey
{
    NSData *saltData = [secretKey dataUsingEncoding:NSUTF8StringEncoding];
    NSData *paramData = [text dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH ];
    CCHmac(kCCHmacAlgSHA1, saltData.bytes, saltData.length, paramData.bytes, paramData.length, hash.mutableBytes);
    NSString *base64Hash = [hash base64EncodedStringWithOptions:0];

    return base64Hash;
}

Demo 工程下载

上文描述的客户端代码具体实现请参考Demo 工程。请根据业务需求适当修改后再用于生产环境。

本文导读目录