为什么它找不到我的信标?

我正在编写需要在设备周围查找BLE信标的Android和iOS应用程序。

当我从Android运行我的代码时,它在我所在的房间里find了几个信标。

我有8个灯塔。

当我从iPhone运行信标代码时,它将返回一个正好为0的信标列表。

这是我的代码:

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; [self initRegion]; [self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion]; } - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; } - (void)initRegion { NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACONUUID]; self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:BEACONIDENTIFIER]; [self.locationManager startMonitoringForRegion:self.beaconRegion]; } - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { NSLog(@"Beacon Found"); [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; } -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { NSLog(@"Left Region"); [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion]; self.beaconFoundLabel.text = @"No"; } -(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { CLBeacon *beacon = [beacons lastObject];//<== is always 0 self.beaconFoundLabel.text = @"Yes"; self.proximityUUIDLabel.text = beacon.proximityUUID.UUIDString; self.majorLabel.text = [NSString stringWithFormat:@"%@", beacon.major]; self.minorLabel.text = [NSString stringWithFormat:@"%@", beacon.minor]; self.accuracyLabel.text = [NSString stringWithFormat:@"%f", beacon.accuracy]; if (beacon.proximity == CLProximityUnknown) { self.distanceLabel.text = @"Unknown Proximity"; } else if (beacon.proximity == CLProximityImmediate) { self.distanceLabel.text = @"Immediate"; } else if (beacon.proximity == CLProximityNear) { self.distanceLabel.text = @"Near"; } else if (beacon.proximity == CLProximityFar) { self.distanceLabel.text = @"Far"; } self.rssiLabel.text = [NSString stringWithFormat:@"%ld", (long)beacon.rssi]; } 

在我的didRangeBeaconsInRegion ,信标NSArray总是有0个对象。 虽然我有8个对象。 我已经下载了几个不是我的应用程序,他们都看到了我的几个信标。

为什么我的代码看不到我的信标?

这是我每当设置一个iBeacon应用程序时所做的。

不是所有这些东西都是必要的,但它会

  1. 工作
  2. 保持你的用户快乐
  3. (也许最重要的)保持苹果快乐

仅适用于iOS 8+

首先要做的是:如果你使用的是iOS 8,那么在使用CLLocationManager之前,你需要确保你真的有权访问它。

 CLLocationManager *locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; // You can either use requestAlwaysAuthorization, or requestWhenInUseAuthorization [self.locationManager requestAlwaysAuthorization]; 

您还需要在plist中使用NSLocationAlwaysUsageDescription条目(仅限iOS 8)

iOS 7+

你的应用程序的pList

无论你使用的是iOS 8还是7,你都应该在你的plist文件中join以下内容(你需要决定是否使用背景)。

注意:下面的forms是KEY:KEY TYPE:VALUE for string,KEY:KEY TYPE:[Value1,Value2 …] for Arrays:

 NSLocationUsageDescription : String : "Gimmie access to your location or else..." NSBluetoothPeripheralUsageDescription : String : "Gimmie access to your blue tooth or else" // Optionally supply if you need background modes. I don't believe you need this either if you plan to turn these options on using the Capabilities section of your App's Settings (see below section) UIBackgroundModes : Array : [ location, bluetooth-central ] UIApplicationExitsOnSuspend : Boolean : NO 

你的应用程序的项目设置(function)

此部分已被删除,因为这可能会导致您的应用程序被拒绝(正如注释中的@heypiotr所指出的那样)

最后的想法

最后的build议是尝试将[self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion]到您的viewDidAppear

这是我通常做的一个例子(对我来说工作得很好)。

 -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self initLocationManager]; [self initBeaconRegion]; [self startMonitoring]; } -(void)initLocationManager { self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; // Not necessary, but I like to do it. if( ![CLLocationManager locationServicesEnabled] ) { [self.locationManager startUpdatingLocation]; } // Only necessary if you're in iOS 8. Checking for existence though to support iOS 7 if( ![CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) { if ([CLLocationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager performSelector:@selector( requestAlwaysAuthorization )]; } } } -(void)initBeaconRegion { NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kYOUR_UUID_HERE]; self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:kYOUR_IDENTIFIER_HERE]; // Change this to whatever you want.... self.beaconRegion.notifyEntryStateOnDisplay = YES; self.beaconRegion.notifyOnEntry = NO; self.beaconRegion.notifyOnExit = YES; } # pragma mark - # pragma mark Monitoring Beacons # pragma mark - -(void)startMonitoring { // Monitor Beacon signals around me and report them back to me [self.locationManager startMonitoringForRegion:self.beaconRegion]; } 

最后一部分(放置在viewDidAppear )可能会帮助或不帮助 – 这一切都取决于我想在太多的因素考虑在一个计算器的回应。

希望有所帮助,祝你好运!

最终编辑

忘了一件事可能会有所帮助。 有一些有用的方法可以帮助您进一步debugging问题。 这是其中几个例子:

 #pragma mark Authorization Status Changed -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if( ![CLLocationManager locationServicesEnabled] ) { NSLog(@"Couldn't turn on ranging: Location services are not enabled."); } else { NSLog(@"Location services ARE enabled."); } if( [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) { NSLog(@"Couldn't turn on monitoring: Location services not authorized."); } else { NSLog(@"Location services ARE authorized."); } } #pragma mark - #pragma mark CLLocationManager Errors #pragma mark - -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog( @"FAIL ERROR: %@", [error description] ); } -(void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion (CLBeaconRegion *)region withError:(NSError *)error { NSLog( @"RANGE BEACONS ERROR: %@", [error description] ); } 

首先检查与其他应用程序。 find应用程序添加您的UDID,并检查这个应用程序显示您的iBeacon。 如果不是那么苹果IOS有时候会有问题。 然后删除应用程序。 重新启动应用程序。 它会为你工作。

我们之前有类似的问题,确保您的iBeacon设备响应来自iOS的扫描请求与响应不包含制造商特定字段。

请检查这个苹果的说明

在尝试监视任何区域之前,您的应用程序应检查当前设备是否支持区域监视。 以下是区域监控可能不可用的一些原因:

  1. 该设备没有必要的硬件来支持区域监控。
  2. 用户拒绝该应用使用区域监控的授权。

  3. 用户在“设置”应用中停用了位置信息服务。

  4. 用户在“设置”应用程序中禁用了“后台应用程序刷新”,无论是设备还是应用程序。

5.设备处于飞行模式,无法启动必要的硬件。

在iOS 7.0和更高版本中,在尝试监视区域之前,始终调用CLLocationManagerisMonitoringAvailableForClass:authorizationStatus类方法。 (在OS X v10.8及更高版本和以前版本的iOS中,请改用regionMonitoringAvailable类。) isMonitoringAvailableForClass:方法告诉您底层硬件是否支持指定类的区域监视。 如果该方法返回NO,则您的应用程序无法在设备上使用区域监视。 如果返回YES,请调用authorizationStatus方法来确定应用程序当前是否有权使用位置服务。 如果授权状态为kCLAuthorizationStatusAuthorized ,则您的应用程序可以为其注册的任何区域接收过境通知。 如果授权状态设置为任何其他值,则应用程序不会收到这些通知。 苹果链接到这里