为什么它找不到我的信标?
我正在编写需要在设备周围查找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应用程序时所做的。
不是所有这些东西都是必要的,但它会
- 工作
- 保持你的用户快乐
- (也许最重要的)保持苹果快乐
仅适用于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的扫描请求与响应不包含制造商特定字段。
请检查这个苹果的说明
在尝试监视任何区域之前,您的应用程序应检查当前设备是否支持区域监视。 以下是区域监控可能不可用的一些原因:
- 该设备没有必要的硬件来支持区域监控。
-
用户拒绝该应用使用区域监控的授权。
-
用户在“设置”应用中停用了位置信息服务。
-
用户在“设置”应用程序中禁用了“后台应用程序刷新”,无论是设备还是应用程序。
5.设备处于飞行模式,无法启动必要的硬件。
在iOS 7.0和更高版本中,在尝试监视区域之前,始终调用CLLocationManager
的isMonitoringAvailableForClass:
和authorizationStatus
类方法。 (在OS X v10.8及更高版本和以前版本的iOS中,请改用regionMonitoringAvailable
类。) isMonitoringAvailableForClass:
方法告诉您底层硬件是否支持指定类的区域监视。 如果该方法返回NO,则您的应用程序无法在设备上使用区域监视。 如果返回YES,请调用authorizationStatus方法来确定应用程序当前是否有权使用位置服务。 如果授权状态为kCLAuthorizationStatusAuthorized
,则您的应用程序可以为其注册的任何区域接收过境通知。 如果授权状态设置为任何其他值,则应用程序不会收到这些通知。 苹果链接到这里