# MTB11说明文档
本套SDK仅支持Minew公司出品的蓝牙Sensor设备,目前是工业温湿度传感器。通过SDK可以帮助开发者处理手机和Sensor之间的一切工作,包括:扫描设备,连接设备,向设备写入数据,从设备接收数据等。
# 前期工作
整体框架:MTICentralManager为设备管理类,在APP运行时始终是单例。MTIPeripheral是设备实例类,此套件会为每一个设备生成一个MTIPeripheral实例以便于对监听设备和操作设备。
MTICentralManager:设备管理类,可以扫描周围的Sensor设备,并且可以连接它们,校验它们等。
MTIPeripheral:设备实例类,当MTICentralManager发现一个物理设备时,MTICentralManager会生成一个MTIPeripheral实例,这个实例就对应一个物理设备。
MTIFrameRRRHandler:设备广播类,可以获取设备广播时的数据。
# 开始上手
# 开发环境:
- Xcode10+,当前SDK使用Xcode15编译,请使用Xcode10及以上版本进行开发;
- iOS12.0,限制最低系统版本为iOS12;
# 导入到工程:
手动导入
- 将开发套件的文件:MTIndustrialSensorKit.framework文件拷贝到项目工程目录下,然后添加到项目中。
PS:
- !!!在iOS10及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Peripheral Usage Description - "你的使用描述"。
- !!!在iOS13及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Always Usage Description - "你的使用描述"。
# 开始开发
# 扫描设备
首先需要获取到MTICentralManager的单例,然后检查手机当前的蓝牙状态,接着就可以进行设备扫描了。
// 获取Manager单例
MTICentralManager *manager = [MTICentralManager sharedInstance];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 手机端当前的蓝牙开关状态
if(self->manager.status == PowerStatePoweredOn) {
// 开始进行设备扫描
[manager startScan:^(NSArray<MTIPeripheral *> *peripherals) {
//可根据broadcast属性的type筛选所需要的传感器种类
self->deviceAry = peripherals;
}];
}
});
//扫描到的设备也可以使用manager.scannedPeris获得
// 如果你需要对手机的蓝牙状态作出响应。请监听回调。
[manager didChangesBluetoothStatus:^(PowerState status){
switch(status) {
case PowerStatePoweredOn:
NSLog(@"bluetooth status change to poweron");
break;
case PowerStatePoweredOff:
NSLog(@"bluetooth status change to poweroff");
break;
case PowerStateUnknown:
NSLog(@"bluetooth status change to unknown");
}
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PS: 只有手机蓝牙状态处于Poweron时,整个SDK才能够正常工作。
# 使用
sdk只有扫描一个阶段。
# 扫描部分
# 开始扫描
[[MTICentralManager sharedInstance] startScan:^(NSArray<MTIPeripheral *> *peripherals) {
if (peripherals.count != 0) {
NSMutableSet *uniqueMacs = [NSMutableSet set]; // 用于跟踪唯一的mac值
NSMutableArray *filteredPeripherals = [NSMutableArray array]; // 用于存储筛选后的MTIPeripheral对象
for (MTIPeripheral *per in peripherals) {
if (!isEmptyString(per.frameRRRHandler.mac) && per.frameRRRHandler.modelType == MTIFrameFlexibilityTwoC) {
NSString *mac = per.frameRRRHandler.mac;
if (![uniqueMacs containsObject:mac]) {
[uniqueMacs addObject:mac];
[filteredPeripherals addObject:per];
} else {
// 如果已经包含相同的mac地址,更新现有对象的信息
NSUInteger index = [filteredPeripherals indexOfObjectPassingTest:^BOOL(MTIPeripheral *existingPer, NSUInteger idx, BOOL *stop) {
if ([existingPer.frameRRRHandler.mac isEqualToString:mac]){
per.frameRRRHandler.noneCounter = existingPer.frameRRRHandler.counter;
per.frameRRRHandler.updateLTime = [[NSDate new] timeIntervalSince1970]*1000;
}
return [existingPer.frameRRRHandler.mac isEqualToString:mac];
}];
if (index != NSNotFound) {
[filteredPeripherals replaceObjectAtIndex:index withObject:per];
}
}
}
}
// 创建一个排序描述符,以便按照 rssi 属性进行倒序排序
NSSortDescriptor *rssiSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"frameRRRHandler.rssi" ascending:NO];
// 使用排序描述符对数组进行排序
NSArray *filteredSortPeripherals = [filteredPeripherals sortedArrayUsingDescriptors:@[rssiSortDescriptor]];
NSMutableArray *filteredortedPeripherals = [NSMutableArray array]; // 用于存储筛选后的MTIPeripheral对象
filteredortedPeripherals = [filteredSortPeripherals mutableCopy];
NSLog([NSString stringWithFormat:@"设备数:\t(%ld)",filteredortedPeripherals.count]);
self.mainTableView.peripherals = filteredortedPeripherals;
[self.mainTableView reloadData];
}
}];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 注意事项
柔性资产设备只有1种广播帧类型。
设备资产标签帧
MTIFrameRRRHandler
名称 类型 说明 encryptoFlag int 0未加密 1加密 cteFlag int 0 未配置,1配置 cteLength int cte长度 encryptoRange int 0 全段加密 全段加密范围为 Encrypto Range与Measured Power之间的数据measuredPower int Power noneSalt int NoneSalt encryptoDataByte byte[] 加密数据byte noneCounter int NoneCounter none byte[] none值等于4个字节的noneCounter+2个字节的noneSalt rawDataHex String 广播数据hex字符串 updateTime long 记录广播帧数据更新时间, calculateAdvInterval long 记录广播数据间隔,可能会有丢包,该数值不精确仅供参考。
# 文档版本记录
- 2026.03.19 v1.0 初版;