如何在 Objective-C 中使用 startMonitoringForRegion 扫描多个区域

Posted

技术标签:

【中文标题】如何在 Objective-C 中使用 startMonitoringForRegion 扫描多个区域【英文标题】:How to scan multiple regions using startMonitoringForRegion in Objective-C 【发布时间】:2014-01-15 05:56:39 【问题描述】:

我已经完成了两个教程,并且正在阅读基本的 C。通过实践来学习最好,并在过去一周左右编写了一些轻量级应用程序。我正在加快速度编写一些将使用 ibeacon 的应用程序。当我浏览一些示例并阅读参考指南时,我发现可以通过为每个 UUID 运行 startMonitoringForRegion 来扫描多个区域。好的,所以我想我可以为每个 UUID 运行它,但这不起作用。我确定我在做一些基本完全错误的事情......下面的代码完全是一个黑客 - 一旦我得到语义,我将通过 API 调用从数据库中提取 UUID,然后循环通过它们来激活监控。下面的代码导致最后一个循环仅显示四个 UUID 中的两个。

在标题中:

@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion2;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion3;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion4;

主要:

NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"86E4BDEA-C6FF-442C-95CB-E6E557A23CF2"];
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.appcoda.testregion"];

NSUUID *uuid2 = [[NSUUID alloc] initWithUUIDString:@"C9AFF296-A722-4F2D-8669-47B7CCC79A14"];
self.myBeaconRegion2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid2 identifier:@"com.appcoda.testregion"];

NSUUID *uuid3 = [[NSUUID alloc] initWithUUIDString:@"1DBDDC7C-49BB-48BF-A2F6-A4825BD514EA"];
self.myBeaconRegion3 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid3 identifier:@"com.appcoda.testregion"];

NSUUID *uuid4 = [[NSUUID alloc] initWithUUIDString:@"8D942B9E-0197-4C81-8722-92144599E9F7"];
self.myBeaconRegion4 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid4 identifier:@"com.appcoda.testregion"];

[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion2];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion3];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion4];

NSSet *setOfRegions = [self.locationManager monitoredRegions];
    for (CLRegion *region in setOfRegions) 
        NSLog (@"region info: %@", region);
    

【问题讨论】:

【参考方案1】:

我认为问题在于您的区域标识符。每个信标区域identifier 必须唯一,否则CLLocationManager 将它们视为同一区域。

尝试为每个区域设置唯一标识符:

NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"86E4BDEA-C6FF-442C-95CB-E6E557A23CF2"];
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.appcoda.testregion"];

NSUUID *uuid2 = [[NSUUID alloc] initWithUUIDString:@"C9AFF296-A722-4F2D-8669-47B7CCC79A14"];
self.myBeaconRegion2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid2 identifier:@"com.appcoda.testregion2"];

NSUUID *uuid3 = [[NSUUID alloc] initWithUUIDString:@"1DBDDC7C-49BB-48BF-A2F6-A4825BD514EA"];
self.myBeaconRegion3 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid3 identifier:@"com.appcoda.testregion3"];

NSUUID *uuid4 = [[NSUUID alloc] initWithUUIDString:@"8D942B9E-0197-4C81-8722-92144599E9F7"];
self.myBeaconRegion4 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid4 identifier:@"com.appcoda.testregion4"];

您应该会看到NSLog 语句中列出的每个区域。也不需要dispatch_async

【讨论】:

我无法在我的 iphone5s 上使用 os 7.1.1。但它曾经适用于一个信标区域。任何人都可以通过这种方式工作吗? 太棒了!原因是因为相同的地区名称。非常感谢!! :)【参考方案2】:

startMonitoringForRegion 的头文件指出“这是异步完成的,可能不会立即反映在受监控的区域中”。

您可以通过在 for 循环中添加时间延迟来验证这一点:

double delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
    NSSet *setOfRegions = [self.locationManager monitoredRegions];
    for (CLRegion *region in setOfRegions) 
        NSLog (@"region info: %@", region);
    
);

【讨论】:

不走运。所以我添加了那段代码,它确实延迟了。我还增加了延迟并且得到了几乎相同的结果。不过有几件奇怪的事情。有一次 UUID 不是我在代码中的一个……我开始从下到上注释掉 UUID,看到它只是显示的最后一个……这就是它的样子。我是否会错误地添加到 startMonitoringForRegion? 很确定您已正确添加到 startMonitoringForRegion,但确实存在时间延迟。您可以添加一个 UIButton 循环通过受监控的Regions 并在点击时打印出 UUID - 您会注意到每次打印不同的 UUID。最终,您应该会在那里看到所有添加的 UUID。【参考方案3】:

如果您需要使用多个信标进行监控,那么您可以使用信标的主要和次要值来区分。阅读教程here 以更好地了解 ibeacon。

-(void)setBeaconTranmitter:(NSInteger)major minorValue:(NSInteger)minor 
    // We need to set beacon regions here.
    NSUUID * uid = [[NSUUID alloc] initWithUUIDString:uuid]; //uuid value is static common string for all beacons.
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uid major:major minor:minor identifier:beaconsId];//beaconsId is a common identifier for all beacons.
    
// Call your Transmitter function here
    [self configureTransmitter];

以上方式我配置了三个具有主要和次要值差异的信标区域。我放置了三个按钮并调用 IBAction 以使用标签和调用函数发送不同的主要和次要值。我在三部不同的 iphone 中安装了相同的应用程序,并在每部手机中启用了每个不同的按钮,并在另一部手机中安装了接收器以进行演示。像魅力一样工作!但是从一个区域移动到另一个区域时检测区域需要时间。

【讨论】:

这是一个仅限链接的边界答案。您应该在此处扩展您的答案以包含尽可能多的信息,并使用该链接仅供参考。 当然,我会在以后的回复中包含这个。谢谢

以上是关于如何在 Objective-C 中使用 startMonitoringForRegion 扫描多个区域的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中使用 Objective-C #define

如何在objective-c中使用didSelectRowAtIndexPath

如何在 Objective-C 中使用 Swift 文件?

如何在 Objective-C 中使用正则表达式验证 IP 地址?

如何在 Objective-C 中使用符号断点获取参数

SideMenu:如何包含在 Objective-C 项目中?