首先声明一下,我用的是 MQTTKit ,因为 MQTTClient 有一些问题,后台用的是混合主题,然后一直为空,无奈,换成了MQTTKit ,一次成功,再次表示感谢,对开源的大神们o( ̄︶ ̄)o
直接上代码 :
.h
#import <Foundation/Foundation.h>
#import "MQTTKit.h"
@interface mqttTool : NSObject
@property (nonatomic, strong) MQTTClient *client; // mqtt客户端
@property (nonatomic, strong) NSString *servicesState; // 服务开启状态
@property (nonatomic, strong) NSString *topicStr; // 订阅主题内容
+ (instancetype)mqttManager;
- (void)connectToHost; // 连接mqtt 自动订阅
@end
.m
#import "mqttTool.h"
typedef enum : NSUInteger {
MyMQTTScribeMessageRemoteUnlock,
MyMQTTScribeMessageFingerVeinRegister,
MyMQTTScribeMessageOther,
} MyMQTTScribeMessage;
@implementation mqttTool
+ (instancetype)mqttManager {
static mqttTool *mqttToolInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mqttToolInstance = [[mqttTool alloc] init];
});
return mqttToolInstance;
}
- (MQTTClient *)client {
if (!_client) {
NSString *clientID = [[UIDevice currentDevice] identifierForVendor].UUIDString;
NSUserDefaults *users = [NSUserDefaults standardUserDefaults];
NSString *userName = [users objectForKey:kUserName];
clientID = [NSString stringWithFormat:@"iOS%@",userName];
_client = [[MQTTClient alloc] initWithClientId:clientID];
}
return _client;
}
#pragma mark - MQTT 订阅服务器通知内容
// 连接服务器
- (void)connectToHost {
// 订阅获取消息
[self setupMessageHandler];
__weak typeof(self) weakSelf = self;
// 异步连接服务器
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 设置连接到服务器的端口
weakSelf.client.port = PORT_TG; // 切换成你们自己端口号
// 开始连接 HOST_TG 切换成自己的服务器地址
[weakSelf.client connectToHost:HOST_TG completionHandler:^(MQTTConnectionReturnCode code) {
// 连接成功
if (code == ConnectionAccepted) {
weakSelf.servicesState = @"Service_ON";
// 更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
// 转换为 CustomView 模式
[weakSelf subscribeTopic];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
// [weakSelf connectTimeoutAction];
});
}
}];
});
}
// 连接服务器超时触发动作
- (void)connectTimeoutAction {
[SVProgressHUD dismiss];
[requestTool showFailureMessage:@"远程开锁失败"];
}
#pragma mark - Subscribe / Unsubscribe
// 订阅某个主题
- (void)subscribeTopic {
__weak typeof(self) weakSelf = self;
NSString *uuidStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
_topicStr = [NSString stringWithFormat:@"/app/doorlock/%@/+",uuidStr]; // 这里是+号的话,可以订阅这里是任意字符的主题,但是不包括子路径
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[weakSelf.client subscribe:weakSelf.topicStr withCompletionHandler:^(NSArray *grantedQos){
// 更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
// 返回订阅成功消息
// [requestTool showSuccessMessage:@"订阅成功"];
});
}];
});
}
// 取消订阅某个主题
- (void)unscribeTopic:(NSString *)topic atIndex:(NSIndexPath *)indexPath{
// [requestTool showWaitMessage:@"取消订阅中..."];
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[weakSelf.client unsubscribe:topic withCompletionHandler:^{
// 更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
[requestTool showSuccessMessage:@"取消订阅成功"];
// sleep(1);
});
}];
});
}
// 设置消息处理
- (void)setupMessageHandler {
NSLog(@"%s", __func__);
__weak typeof(self) weakSelf = self;
[self.client setMessageHandler:^(MQTTMessage *message) {
NSString *content = message.payloadString;
NSString *topicSt = message.topic;
NSLog(@"text --->>%@ >>> %@", topicSt, content);
NSString *purpose = [topicSt substringFromIndex:weakSelf.topicStr.length-1];
NSError *error;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:message.payload options:NSJSONReadingMutableContainers error:&error];
NSString *resultStr = [NSString stringWithFormat:@"%@",dic[@"status"]];
NSLog(@">>>%@",dic[@"status"]);
// status 0 success 1 failure
}];
}
@end
如有疑问,可以直接问我,共同进步🙃