我已经和iBeacons玩了几个星期了,并且想知道是否有可能从同一个视图控制器监视两个信标。
例如,到目前为止,我已经创建了一个具有三个特定视图的应用程序,每个视图都对单独的信标作出反应,根据范围改变内容并触发音乐和视频等动态内容。所有这些视图都是相同的布局,所以我想知道我是否可以更改它,所以我有一个视图控制器根据我附近的信标改变内容,而不是必须更改视图。
这样更有意义,因为你只能监控一个意味着当segue触发并且新信标被监控时,如果你向第一个信标移动,当你进入时,它不会回到那个视图。第一个信标接近。
我确信有一种方法可以做到这一点,因为在美国的苹果商店使用信标触发促销等等,并且他们在没有问题的情况下依靠最近的信标。
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface ExhibitsViewController : UIViewController <CLLocationManagerDelegate,UIScrollViewDelegate>
{
CLBeacon *beacon;
}
@property (strong, nonatomic) CLBeaconRegion *beaconRegion;
@property (strong, nonatomic) CLLocationManager *locationManager
@end
这是我头文件中定义beacon,beaconRegion和locationManager的代码。
#import "MultipleBeaconsViewController.h"
@interface MultipleBeaconsViewController ()
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *rangeLabel;
@property (weak, nonatomic) IBOutlet UILabel *uuidLabel;
@end
@implementation MultipleBeaconsViewController
NSUUID *iBeacon1uuid;
NSUUID *iBeacon2uuid;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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.iBeacon1Region];
[self locationManager:self.locationManager didStartMonitoringForRegion:self.iBeacon2Region];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)initRegion {
iBeacon1uuid = [[NSUUID alloc] initWithUUIDString:@"11111111-2222-3333-4444-555555555555"];
_iBeacon1Region = [[CLBeaconRegion alloc] initWithProximityUUID:iBeacon1uuid identifier:@"com.private.Gallery"];
_iBeacon1Region.notifyOnEntry = YES;
_iBeacon1Region.notifyOnExit = YES;
// launch app when display is turned on and inside region
_iBeacon1Region.notifyEntryStateOnDisplay = YES;
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
[_locationManager startMonitoringForRegion:_iBeacon1Region];
[_locationManager startRangingBeaconsInRegion:_iBeacon1Region];
}
iBeacon2uuid = [[NSUUID alloc] initWithUUIDString:@"55555555-4444-3333-2222-111111111111"];
_iBeacon2Region = [[CLBeaconRegion alloc] initWithProximityUUID:iBeacon2uuid identifier:@"com.private.Gallery"];
_iBeacon2Region.notifyOnEntry = YES;
_iBeacon2Region.notifyOnExit = YES;
// launch app when display is turned on and inside region
_iBeacon2Region.notifyEntryStateOnDisplay = YES;
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
[_locationManager startMonitoringForRegion:_iBeacon2Region];
[_locationManager startRangingBeaconsInRegion:_iBeacon2Region];
}
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
if ([region isKindOfClass:[CLBeaconRegion class]])
{
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
if ([beaconRegion.proximityUUID isEqual: iBeacon1uuid])
{
_titleLabel.text = @"Beacon 1 proximity entered";
}
else if ([beaconRegion.proximityUUID isEqual: iBeacon2uuid])
{
_titleLabel.text = @"Beacon 2 proximity entered";
}
}
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
if ([region isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
if ([beaconRegion.proximityUUID isEqual: iBeacon1uuid])
{
_titleLabel.text = @"Beacon 1 proximity exited";
}
else if ([beaconRegion.proximityUUID isEqual: iBeacon2uuid])
{
_titleLabel.text = @"Beacon 2 proximity exited";
}
}
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
if ([region isKindOfClass:[CLBeaconRegion class]]) {
for (CLBeacon *beacon in beacons)
{
NSString *beaconID = [beacons objectAtIndex:0];
NSLog(@"%@",beaconID);
if ([region.proximityUUID isEqual:iBeacon1uuid])
{
if (beacon.accuracy >=0.000001 && beacon.accuracy <=0.500000)
{
_titleLabel.text = @"Beacon 1";
_rangeLabel.text = [NSString stringWithFormat:@"%f",beacon.accuracy];
_uuidLabel.text = [NSString stringWithFormat:@"%@", beacon.proximityUUID];
}
}
else if ([region.proximityUUID isEqual:iBeacon2uuid])
{
if (beacon.accuracy >=0.000001 && beacon.accuracy <=0.500000) {
_titleLabel.text = @"Beacon 2";
_rangeLabel.text = [NSString stringWithFormat:@"%f",beacon.accuracy];
_uuidLabel.text = [NSString stringWithFormat:@"%@", beacon.proximityUUID];
}
else
{
}
}
}
}
}
这是我在实施文件中的代码,它是信标的范围。
答案 0 :(得分:4)
是的,你可以。要做到这一点,你不必保留属性self.beaconRegion你只需创建任意多个并开始监视并开始测距,例如我就是这样做的:
// Reion 1
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:major minor:minor identifier:identifier];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
// launch app when display is turned on and inside region
region.notifyEntryStateOnDisplay = YES;
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
[_locationManager startMonitoringForRegion:region];
[_locationManager startRangingBeaconsInRegion:region];
}
// Region 2
CLBeaconRegion *region2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid2 major:major2 minor:minor2 identifier:identifier2];
region2.notifyOnEntry = YES;
region2.notifyOnExit = YES;
// launch app when display is turned on and inside region
region2.notifyEntryStateOnDisplay = YES;
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
[_locationManager startMonitoringForRegion:region2];
[_locationManager startRangingBeaconsInRegion:region2];
}
//等等
在每个self.locationManager委托方法之后,确保您拥有哪个信标,例如:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
if ([region isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
// Find out which beacon you have,
// I check just UUID but maybe your beacons have the same uuid but major, minor are difference so you need to check minor/major as well
if ([beaconRegion.proximityUUID isEqual:UUIDFIRST]) {
//Do some stuff
}
}
}
如果您想查看哪个灯塔最近,请使用:
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
枚举信标数组:
if ([region isKindOfClass:[CLBeaconRegion class]]) {
for (CLBeacon *beacon in beacons) { // 1
// do the checking which beacon you have
if ([beaconRegion.proximityUUID isEqual:UUIDFIRST]) { // 2
}
// check beacon.accuracy property this should gives you distance in meters meters
//beacon.accuracy // 3
}
}
}
//扩展
如果您在两个(或更多)信标范围内,信标将以信标数组传递给您。通过调用[beacons lastObject],你只需要一个信标。您需要做的是枚举(遍及数组中的所有对象)在上面的代码中看到没有1(我编辑了一下)并看到你有什么信标(2)之后你比较距离(3)和价值较低的那个是最近的一个。
答案 1 :(得分:3)
UUID可以在许多iBeacons上重复使用。每个信标都有一个主要数字和一个次要数字,以区分每个信标。
所以一家公司会购买一个UUID,但是(以商店为准),
所有专业= 1都在一楼:
少校2 =二楼:
......等等。当应用程序在商店周围走动时,信标可以告诉它们在哪里,并根据数据提供广告/视频。
您在didRangeBeacons
回调中检查这些值。我还相信一个应用程序可以同时监控多达20个区域,因此该回调中的region
属性将包含不同的UUID
答案 2 :(得分:0)
中提供的标识符
[[CLBeaconRegion alloc] initWithProximityUUID:iBeacon1uuid identifier:@"com.private.Gallery"];
对于您正在监控的每个信标,必须不同。
在你的情况下,他们都是@“com.private.Gallery”