CLBeacon未被检测到

时间:2014-05-29 10:31:47

标签: ios objective-c core-location core-bluetooth ibeacon

我正在努力了解CLBeacons的工作原理。我之前曾与CBPeripherals合作过,这实际上是BLE设备的核心蓝牙框架实现。

我所做的是以下步骤:

  1. 使用CBPeripheralManager检测我周围的信标,(获取每个信标的个人标识符)。
  2. 使用要在UITableView上显示的数据
  3. 在选择Tableview时,我将CBPeripheral对象本身传递给另一个我有CLLocationManager的类。在这里,我使用CBPeripheral对象的邻近UUID和该区域中的startToRangeBeacons定义CLBeaconRegion。
  4. 没有信标出现。

    令人惊讶的是,当我使用[NSUUID alloc] initWithUUIDString:@" E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"]作为uuid(我从AirLocate项目中收集)时,会出现多个信标。 / p>

    根据我读过的文档,邻近UUID是信标的标识符。那么为什么当我使用传递的标识符时它不起作用,为什么它在我使用定义的标识符时有效呢?

    代码---- 1.第一个屏幕

    #import "TiBViewController.h"
    #import "DEASensorTag.h"
    #import "TiBScanTableViewCell.h"
    #import "TiBLocateViewController.h"
    
    @interface TiBViewController ()
    
    @property (nonatomic,strong) NSTimer *timer_check;
    @end
    
    @implementation TiBViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
    }
    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:YES];
    
    }
    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:YES];
    
        [self performSelector:@selector(initialise) withObject:self afterDelay:2.0];
    }
    -(void)initialise
    {
        DEACentralManager *centralManager = [DEACentralManager initSharedServiceWithDelegate:self];
        if (centralManager.isScanning == NO)
        {
            [centralManager startScan];
            centralManager.isScanning=YES;
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
        }
    
        if(self.timer_check==nil)
        {
            self.timer_check = [NSTimer timerWithTimeInterval:20
                                                       target:self
                                                     selector:@selector(timer_function)
                                                     userInfo:nil
                                                      repeats:YES];
    
            NSRunLoop *runner = [NSRunLoop currentRunLoop];
            [runner addTimer:self.timer_check forMode: NSDefaultRunLoopMode];
        }
        [self.timer_check fire];
    }
    
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central
    {
        switch (central.state)
        {
            case CBCentralManagerStatePoweredOn:
                break;
            case CBCentralManagerStatePoweredOff:
                break;
            case CBCentralManagerStateUnsupported:
            {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                message:@"Device is Supported"
                                                               delegate:nil
                                                      cancelButtonTitle:@"Dismiss"
                                                      otherButtonTitles:nil];
    
                [alert show];
                break;
            }
            case CBCentralManagerStateResetting:
            {
    
                break;
            }
            case CBCentralManagerStateUnauthorized:
                break;
    
            case CBCentralManagerStateUnknown:
                break;
    
            default:
                break;
        }
    }
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        YMSCBPeripheral *yp = [centralManager findPeripheral:peripheral];
        yp.delegate = self;
    
        [yp readRSSI];
    
        for (TiBScanTableViewCell *cell in [self.peripheralsTableView visibleCells])
        {
            if (cell.yperipheral == yp)
            {
               [cell updateDisplay];
                break;
            }
        }
    }
    
    
    
    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
    {
        for (TiBScanTableViewCell *cell in [self.peripheralsTableView visibleCells])
        {
            [cell updateDisplay];
        }
    }
    
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
    {
    
        DEACentralManager *centralManager = [DEACentralManager sharedService];
    
        YMSCBPeripheral *yp = [centralManager findPeripheral:peripheral];
        if (yp.isRenderedInViewCell == NO)
        {
            yp.isRenderedInViewCell = YES;
    
            [self.peripheralsTableView reloadData];
        }
    
        if (centralManager.isScanning)
        {
    //        if(advertisementData!=nil)
    //        {
    //            NSLog(@" ad is %@",advertisementData);
    //        }
    
           for (TiBScanTableViewCell *cell in [self.peripheralsTableView visibleCells])
            {
              if (cell.yperipheral.cbPeripheral == peripheral)
                {
                  if (peripheral.state == CBPeripheralStateDisconnected)
                    {
                        cell.rssiLabel.text = [NSString stringWithFormat:@"%ld dB", (long)[RSSI integerValue]];
    
                        cell.distanceLabel.text = [NSString stringWithFormat:@" distance : %0.3fm",[self calculateAccuracyWithRSSI:[RSSI doubleValue]]];
                    }
                    else
                    {
                        continue;
                    }
                }
            }
        }
    }
    
    
    - (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
    
        for (CBPeripheral *peripheral in peripherals)
        {
            YMSCBPeripheral *yp = [centralManager findPeripheral:peripheral];
            if (yp)
            {
                yp.delegate = self;
            }
        }
    
        [self.peripheralsTableView reloadData];
    
    }
    
    - (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals
    {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
    
        for (CBPeripheral *peripheral in peripherals)
        {
            YMSCBPeripheral *yp = [centralManager findPeripheral:peripheral];
            if (yp)
            {
                yp.delegate = self;
            }
        }
    
        [self.peripheralsTableView reloadData];
    }
    
    #pragma mark - CBPeripheralDelegate Methods
    
    - (void)performUpdateRSSI:(NSArray *)args
    {
        CBPeripheral *peripheral = args[0];
    
        [peripheral readRSSI];
    }
    
    - (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error {
    
        if (error)
        {
            NSLog(@"ERROR: readRSSI failed, retrying. %@", error.description);
    
            if (peripheral.state == CBPeripheralStateConnected)
            {
                NSArray *args = @[peripheral];
                [self performSelector:@selector(performUpdateRSSI:) withObject:args afterDelay:2.0];
            }
    
            return;
        }
    
        [self placeRSSI:peripheral];
    
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        YMSCBPeripheral *yp = [centralManager findPeripheral:peripheral];
    
        NSArray *args = @[peripheral];
        [self performSelector:@selector(performUpdateRSSI:) withObject:args afterDelay:yp.rssiPingPeriod];
    }
    
    -(void)placeRSSI:(CBPeripheral *)per
    {
        for (TiBScanTableViewCell *cell in [self.peripheralsTableView visibleCells])
        {
            if (cell.yperipheral)
            {
                if (cell.yperipheral.isConnected)
                {
                    if (cell.yperipheral.cbPeripheral == per)
                    {
                        cell.rssiLabel.text = [NSString stringWithFormat:@"%@", per.RSSI];
                        cell.distanceLabel.text = [NSString stringWithFormat:@" distance : %0.3fm",[self calculateAccuracyWithRSSI:[per.RSSI doubleValue]]];
                        break;
                    }
                }
            }
        }
    }
    
    #pragma mark UITableView
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        return centralManager.count;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"ListCell";
    
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        YMSCBPeripheral *yp = [centralManager peripheralAtIndex:indexPath.row];
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        TiBScanTableViewCell *pcell = (TiBScanTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        [pcell configureWithPeripheral:yp];
    
        yp.isRenderedInViewCell = YES;
        cell = pcell;
    
        return cell;
    }
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        YMSCBPeripheral *yp = [centralManager peripheralAtIndex:indexPath.row];
    
        TiBLocateViewController *locate = [self.storyboard instantiateViewControllerWithIdentifier:@"Locate"];
        locate.cbPeripheral=yp.cbPeripheral;
        [self.navigationController pushViewController:locate animated:YES];
    }
    -(void)timer_function
    {
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        for (TiBScanTableViewCell *cell in [self.peripheralsTableView visibleCells])
        {
            NSIndexPath *indexPath = [self.peripheralsTableView indexPathForCell:cell];
            YMSCBPeripheral *yp = [centralManager peripheralAtIndex:indexPath.row];
            [centralManager removePeripheral:yp];
            [self.peripheralsTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }
    -(void)viewWillDisappear:(BOOL)animated
    {
        [self.timer_check invalidate];
        self.timer_check = nil;
        [self timer_function];
    
        DEACentralManager *centralManager = [DEACentralManager sharedService];
        [centralManager stopScan];
    
        [super viewWillDisappear:YES];
    }
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }
    - (double)calculateAccuracyWithRSSI:(double)rssi
    {
        if (rssi == 0) {
            return -1.0;
        }
    
        double txPower = -70;
        double ratio = rssi*1.0/txPower;
        if (ratio < 1.0) {
            return pow(ratio,10);
        }
        else {
            double accuracy =  (0.89976) * pow(ratio,7.7095) + 0.111;
            return accuracy;
        }
    }
    @end
    
    1. 第二个屏幕

      #import&#34; TiBLocateViewController.h&#34;     @import CoreLocation;

      @interface TiBLocateViewController ()<CLLocationManagerDelegate>
      @property (strong,nonatomic) CLLocationManager *locateManager;
      @end
      
      @implementation TiBLocateViewController
      
      - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
      {
          self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
          if (self) {
              // Custom initialization
          }
          return self;
      }
      
      - (void)viewDidLoad
      {
          [super viewDidLoad];
      
          self.locateManager = [[CLLocationManager alloc]init];
          self.locateManager.delegate=self;
          self.locateManager.desiredAccuracy = kCLLocationAccuracyBest;
      
      }
      
      -(void)viewDidAppear:(BOOL)animated
      {
          [super viewDidAppear:YES];
      
      }
      -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
      {
          if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
          {
      
              NSUUID *per_uuid = self.cbPeripheral.identifier;
              CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]
                                              initWithProximityUUID:per_uuid
                                              identifier:[[NSBundle mainBundle] bundleIdentifier]];
      
              beaconRegion.notifyOnExit=YES;
              beaconRegion.notifyOnEntry=YES;
              beaconRegion.notifyEntryStateOnDisplay=YES;
      
              [manager startMonitoringForRegion:beaconRegion];
              [manager startRangingBeaconsInRegion:beaconRegion];
      
          }
      }
      -(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
      {
          if ([region isKindOfClass:[CLBeaconRegion class]])
          {
              [manager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
          }
      }
      - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
      {
          if ([region isKindOfClass:[CLBeaconRegion class]])
          {
              [manager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
          }
      }
      -(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
      {
         for (CLBeacon *beacon in beacons)
         {
             NSLog(@" beacon %@",beacon);
         }
      }
      -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
      {
          NSLog(@" error is %@",error.localizedDescription);
      }
      - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
      {
          if ([region isKindOfClass:[CLBeaconRegion class]])
          {
              [manager stopRangingBeaconsInRegion:(CLBeaconRegion *)region];
          }
      }
      - (void)didReceiveMemoryWarning
      {
          [super didReceiveMemoryWarning];
      }
      -(void)viewWillDisappear:(BOOL)animated
      {
          [super viewWillDisappear:YES];
          [self.locateManager stopMonitoringSignificantLocationChanges];
      }
      /*
      #pragma mark - Navigation
      
      // In a storyboard-based application, you will often want to do a little preparation before navigation
      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
      {
          // Get the new view controller using [segue destinationViewController].
          // Pass the selected object to the new view controller.
      }
      */
      
      @end
      

1 个答案:

答案 0 :(得分:1)

尽管iBeacons使用Bluetooth Low Energy,但它们并未与iOS中的Core-Bluetooth库一起使用。它们通过Core Location处理。

信标区域是根据三个参数定义的 - UUID,主要和次要。

iBeacon UUID与蓝牙MAC地址不同 - 它更像是&#34;供应商ID&#34;。给定供应商或所有者的所有信标都将具有相同的UUID - 例如Acme Dept商店将为自己分配一个UUID并将其分配给所有信标,而Big Bank Corp将分配一个不同的信标并将其分配给他们。然后,他们可以使用主要和次要来指示不同的位置。例如,百货商店可能有主要=商店编号和次要=部门编号(鞋子= 1,食物= 2等等)。银行专业可能是分支机构,辅修专业可能是分支机构(1 =出纳员,2 = ATM,3 =后台)。

还有一些&#34;众所周知的&#34;正在使用的UUID - 例如,您找到了AirLocate。 Estimote也有一个默认情况下他们的信标附带。

如果要扫描信标区域,则必须至少指定UUID。您还可以选择指定主要和次要。当检测到与您正在扫描的信标区域匹配的信标时,您将收到通知(取决于您已激活的模式,输入/退出区域或didRangeBeacon)。

某些信标可能另外实现BLE外围服务和特性以设置其参数(UUID,主要,次要,传输级别),但这不是iBeacon规范的一部分,因此不同的供应商将有不同的方法来执行此操作。要使用这些设置,您可以使用Core-Bluetooth。

因此,总而言之,如果您只是处理iBeacon方面的事情,那么您不需要对Core-Bluetooth做任何事情。您只需要Core-Location。

相关问题