ITPub博客

首页 > 移动开发 > IOS > 聊聊Apple的iBeacon技术

聊聊Apple的iBeacon技术

IOS 作者:精神食粮 时间:2021-08-31 16:38:02 0 删除 编辑

前言

网上查资料说苹果在13年的WWDC上发布iOS7上配备的新功能。


之前,利用iBeacon设备做了下定位的算法研究,故此来总结下,也希望能和大家交流下。


什么是iBeacon
首先,iBeacon 的标志是下面这张图片:



下面进入正题,iBeacon这项技术是苹果建立在低功耗蓝牙的技术上做出来的东西。具体来说是利用BLE中名为"通告帧"的广播帧。

通告帧是由配备BLE的设备定期发出,只要是支持BLE的终端,都可以接受到信号。通告帧的有效载荷部分,写入了苹果定义的数据。

一个iBeacon基站的数据大致由四部分信息组成:

1 、UUID(universally unique identifier):一个128位的唯一标识一个或多个Beacon基站为特定类型或特定的组织。

2、 Major:一个16位的无符号整数,可以将具有相同proximity UUID的Beacon基站组织联系起来。(用户可以自定义)

3、 Minor:同上。

4、Measured Power :是iBeacon发送模块与接收器之间距离为1米时的信号强度(RSSI)参照值。

通过蓝牙低功耗技术(BLE)发送特定的识别信息,来确定Beacon基站和设备之间的相对距离。而这个距离并不是精密推算的,而是将其分为三级:

  • 约10厘米(immediate)

  • 1米以内(near)

  • 1米以外(far)

这是因为,发送和接受设备之间的距离在1米之内时,RSSI值基本是按照理论值减少的,而在1米外,收到发射波的影响,RSSI不会明显的随距离增加减少,而是会上下波动。也就是说,1米外的距离无法非常精密推测,可以用far来概括。


接下来,进入重点:
既然,用一个iBeacon我们可以测出Beacon设备和扫描Beacon设备之间的距离(Apple的API中已给出距离值)。

那么,猜想下,有三个Beacon,然后知道他们的坐标信息,那么我们拿着手机去不断的扫描这三个Beacon的RSSI信息就可以利用定位算法来进行定位了。


下面,上代码
关于开始定位的部分
在这,我设置了三个基准点作为坐标点固定,用来探测手持设备的位置。

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];    self.locationManager            = [[CLLocationManager alloc] init];    self.locationManager.delegate   = self;    NSArray *myBeacon = @[UUID_BEACON_O, UUID_BEACON_T, UUID_BEACON_H];    for (NSString *uuid in myBeacon) {        NSString *identifier = @"";        if ([uuid isEqualToString:UUID_BEACON_O]) {            identifier = @"左后";        }else if ([uuid isEqualToString:UUID_BEACON_T]) {            identifier = @"右后";        }else if ([uuid isEqualToString:UUID_BEACON_H]) {            identifier = @"左前";        }        CLBeaconRegion *beacon = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:uuid]                                                                    identifier:identifier];        beacon.notifyOnExit              = YES;        beacon.notifyOnEntry             = YES;        beacon.notifyEntryStateOnDisplay = YES;        [self.locationManager startMonitoringForRegion:beacon];        [self.locationManager startRangingBeaconsInRegion:beacon];    }    [self.locationManager requestAlwaysAuthorization];

滑 动显示更 多



关于位置的Delegate部分

处理收到的系统发给的信号, 在这里主要是做了本地消息的推送 。

在持续探测信号强度的时候,可以按照最后的参考文章,实现三角定位原理,来实现设备的定位。

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {    if ([region isKindOfClass:[CLBeaconRegion class]]) {        UILocalNotification *notification = [[UILocalNotification alloc] init];        notification.alertBody = [NSString stringWithFormat:@"你已进入到 %@ 范围内", region.identifier];        notification.soundName = @"Default";        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];        NSLog(@"%@", [NSString stringWithFormat:@"你已进入到 %@ 范围内", region.identifier]);    }}- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {    if ([region isKindOfClass:[CLBeaconRegion class]]) {        UILocalNotification *notification = [[UILocalNotification alloc] init];        notification.alertBody = [NSString stringWithFormat:@"你已离开 %@ 的范围", region.identifier];        notification.soundName = @"Default";        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];        NSLog(@"%@", [NSString stringWithFormat:@"你已离开 %@ 的范围", region.identifier]);    }}- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region {        for (CLBeacon *beacon in beacons) {    //        NSLog(@"beacon Info : rssi is %ld, major is %@, minor is %@, accuracy is %f, proximity is %ld.", beacon.rssi, beacon.major, beacon.minor, beacon.accuracy, beacon.proximity);            if (self.beaconDataSource.count == 3) {                if ([[beacon.proximityUUID UUIDString] isEqualToString:UUID_BEACON_O]) {                    [self.beaconDataSource replaceObjectAtIndex:0 withObject:beacon];                    [self.wait1 addObject:beacon];      //采集数据  左后                }                if ([[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_T]) {                    [self.beaconDataSource replaceObjectAtIndex:1 withObject:beacon];                    [self.wait2 addObject:beacon];      //采集数据  右后                }                if ([[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_H]) {                    [self.beaconDataSource replaceObjectAtIndex:2 withObject:beacon];                    [self.wait3 addObject:beacon];      //采集数据  左前                }                if (!self.testButton.selected) {   //测试按钮没有选中                   //实时刷新位置信息                    if (self.wait1.count == 20 && self.wait2.count == 20 && self.wait3.count == 20) {                        //                    NSArray *result = [DealModel dealWithBaseData:@[@[@"0", @"0"], @[@"220", @"0"], @[@"110", @"110"]] andThreeAuxData:@[self.wait1, self.wait2, self.wait3] andReal:@[self.textX.text, self.textY.text]];                        DataProcessing *data = [[DataProcessing alloc] init];                        NSArray *result2 = [data dealWithBaseData:@[@[@"0", @"0"], @[@"220", @"0"], @[@"110", @"110"]] andThreeAuxData:@[self.wait1, self.wait2, self.wait3] andReal:@[@"",@""]];                        self.result1.text = self.result2.text;                        self.result2.text = [NSString stringWithFormat:@"X : %@\nY : %@", result2[0], result2[1]];                        NSLog(@"%@", data);                        //                self.xyView.center = CGPointMake([result[0] floatValue], [result[1] floatValue]);                        [self.wait1 removeAllObjects];                        [self.wait2 removeAllObjects];                        [self.wait3 removeAllObjects];                        self.sureButton.selected = NO;                        self.sureButton.backgroundColor = [UIColor blackColor];                    }                }else {                    //开始测试单个设备误差                    if (self.wait1.count == 20) {                        if (![self.textX.text isEqualToString:@""])                            [DataProcessing testErrorWithUUID:UUID_BEACON_O andRealValue:self.textX.text andTestArray:self.wait1];                        [self.wait1 removeAllObjects];                        [self.wait2 removeAllObjects];                        [self.wait3 removeAllObjects];                    }else if (self.wait2.count == 20) {                        if (![self.textX.text isEqualToString:@""])                            [DataProcessing testErrorWithUUID:UUID_BEACON_T andRealValue:self.textX.text andTestArray:self.wait2];                        [self.wait1 removeAllObjects];                        [self.wait2 removeAllObjects];                        [self.wait3 removeAllObjects];                    }else if (self.wait3.count == 20) {                        if (![self.textX.text isEqualToString:@""])                            [DataProcessing testErrorWithUUID:UUID_BEACON_H andRealValue:self.textX.text andTestArray:self.wait3];                        [self.wait1 removeAllObjects];                        [self.wait2 removeAllObjects];                        [self.wait3 removeAllObjects];                    }                }                [self.localView refreshWithArray:self.beaconDataSource];            }else {                if ([[beacon.proximityUUID UUIDString] isEqualToString:UUID_BEACON_O] || [[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_T] || [[beacon.proximityUUID UUIDString]isEqualToString:UUID_BEACON_H]) {                    [self.beaconDataSource addObject:beacon];                }            }        }        [self.beaconTableView reloadData];}

滑 动显示更 多



总结

iOS设备不仅可以探测周围iBeacon信号,也可以把自身作为一个iBeacon来向外界发送信号内容(具体实现很简单,大家自行查阅资料)。

最后在实际的使用中,参照最后的那片文章实现了三角定位的算法,但是,信号的波动还是很大的,并不符合理想,就没有在继续研究下去。如果大家有兴趣可以一起在留言区研究讨论。

转载:掘金 作者:阿华12年

链接:https://juejin.cn/post/6995857698747056142



你好,这里是逻辑iOS技术号:一个让知识变得感性,让学习变得轻松!活跃的技术小站,希望给你的生活与技术带来意思不一样!关注公众号,回复“ 面试题”,即可领取更多大厂面试题型哦~ 小逻辑相信我们的生活不止眼前的苟且,还有我们向往的诗和大厂高薪工作~


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70005484/viewspace-2789704/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
更多干货内容尽在“逻辑iOS技术号”

注册时间:2021-08-18

  • 博文量
    20
  • 访问量
    12855