美文网首页
聊聊Apple的iBeacon技术

聊聊Apple的iBeacon技术

作者: SuperMan_Wang | 来源:发表于2017-03-24 12:58 被阅读471次
    首先,iBeacon 的标志是下面这张图片
    iBeacon

    网上查资料说苹果在13年的WWDC上发布iOS7上配备的新功能。
    最近,利用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信息就可以利用定位算法来进行定位了。
    一篇关于用iBeacon定位的文章

    最后,上代码

    关于开始定位的部分
    
        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];
       
    }
    

    相关文章

      网友评论

          本文标题:聊聊Apple的iBeacon技术

          本文链接:https://www.haomeiwen.com/subject/lzoznttx.html