ios – 为什么信标会导致蓝牙不断切换?

我在使用iOS和iBeacon时遇到了一个非常奇怪的错误.我有一个非常简单的BeaconManager,它使用特定的UUID,主要和次要值来定义信标,并在找到它们后执行一些操作.我的应用似乎正常工作,直到它不断切换蓝牙状态并停止工作.唯一可见的结果是状态栏中的蓝牙图标由于蓝牙停止和重新启动而开始闪烁.

在哪里集中注意力?

这是我的班级定义:

#import "BeaconManager.h"

@implementation BeaconManager

- (instancetype)init {
    self = [super init];
    if (self) {
        NSURL *beep = [[NSBundle mainBundle] URLForResource:@"beep" withExtension:@"aiff"];
        soundFileURLRef = (CFURLRef) CFBridgingRetain(beep);
        AudioServicesCreateSystemSoundID(soundFileURLRef,&soundFileObject);

        // Initializes properties
        beacon = [CLBeacon new];
        foundBeacons = [NSMutableArray new];
        _lastBeaconActionTimes = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void)initRegion {
    // Initializes the beacon region by giving it an UUID and an identifier
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACON];
    beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"beacon.region"];
    // Starts looking for beacon within the region
    [self.locationManager startMonitoringForRegion:beaconRegion];
}

- (void)checkBeacon {
    if (!self.locationManager) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;

        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
            [self.locationManager requestWhenInUseAuthorization];
    }
    [self initRegion];
    [self locationManager:self.locationManager didStartMonitoringForRegion:beaconRegion];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
    [self.locationManager startMonitoringForRegion:beaconRegion];
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    [self.locationManager stopRangingBeaconsInRegion:beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
    NSLog(@"Failed monitoring region: %@",error);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"Location manager Failed: %@",error);
}

- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray *)beacons
               inRegion:(CLBeaconRegion *)region {

    if (foundBeacons.count == 0) {
        for (CLBeacon *filterBeacon in beacons) {
            // If a beacon is located near the device and its major value is equal to 1000 (MAJOR constant)
            if (((filterBeacon.proximity == CLProximityImmediate) || (filterBeacon.proximity == CLProximityNear)))
                // Registers the beacon to the list of found beacons
                [foundBeacons addobject:filterBeacon];
        }
    }
    // Did some beacon get found?
    if (foundBeacons.count > 0) {
        // Takes first beacon of the list
        beacon = [foundBeacons firstObject];

        if (([beacon.major isEqualToNumber:[NSNumber numberWithInt:MAJOR]]) && ([beacon.minor isEqualToNumber:[NSNumber numberWithInt:MInor]])) {
            // Takes the actual date and time
            NSDate *Now = [[NSDate alloc] init];
            Nsstring *key = [Nsstring stringWithFormat:@"%@ %@ %@",[beacon.proximityUUID UUIDString],beacon.major,beacon.minor];
            NSDate *lastBeaconActionTime = [_lastBeaconActionTimes objectForKey:key];
            if ((lastBeaconActionTime == nil) || ([Now timeIntervalSinceDate:lastBeaconActionTime] > MINIMUM_ACTION_INTERVAL_SECONDS)) {
                [_lastBeaconActionTimes setobject:Now forKey:key];
                // Plays beep sound
                AudioServicesPlaySystemSound(soundFileObject);

                if (self.delegate) {
                    // Performs actions related to the beacon (i.e. delivers a coupon)
                    [self.delegate didFoundBeacon:self];
                }
                self.locationManager = nil;
            }
            // else [self.locationManager stopMonitoringForRegion:region];
        }
        [foundBeacons removeObjectAtIndex:0];
        beacon = nil;
    }
}
@end

解决方法

不能肯定这是蓝牙不断切换的原因,但这部分肯定是可疑的:
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
    [self.locationManager startMonitoringForRegion:beaconRegion];
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];
}

这基本上是一个无限循环.一旦监控开始,iOS就会调用didStartMonitoring方法……它开始监控同一个区域,这使得iOS再次调用didStartMonitoring方法,其中……

我首先从代码的这一部分中删除startMonitoringForRegion行.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...