How to reboot CoreBluetooth manager instance at fi

2019-04-16 03:57发布

问题:

I'm developing a iOS application of using CoreBluetooth and i have one problem in application BackGround.

Generally, iOS application can't run long-term in Background. (e.g. pushing HomeButton. switching other application) But my application is set "Uses Bluetooth LE accessories" as BackGroundMode, so i can monitor region in Background.
And i implemented startRangingBeaconsInRegion in didEnterRegion.
When enter a region, Ranging region will be started and will be stopped after about 10 sec by iOS.

But i want to always use ranging in Background. Because my app use only one UUID for detecting over 20 beacons(20 means limit of startMonitoringForRegion), and i want to know how beacons there are in one region.
(About The reason of using only one UUID, please see this tips.
iBeacon / Bluetooth Low Energy (BLE devices) - maximum number of beacons.)

So I'm thinking the way of rebooting CoreBluetooth manager instance at fixed interval in background. if i can do alternately didEnterRegion -> didRangeBeacons-> reboot -> didEnterRegion -> didRangeBeacons -> reboot -> ..., i can check how beacon there are in the region at fixed interval.
Maybe i need background fetch... i'll try it later.
If you know about this way is available or not, please tell me that.
Or if you have any suggestions, please tell me, i'll try it.

Updated 2014/03/07 17:45

BackGround fetch will fire at UNSTABLE interval. So This way isn't the solution...

回答1:

You do not need to set that requirement for background modes. You can try on applicationDidEnterBackground: call startBackgroundTask

- (void)startBackgroundTask {
    if(bgTask != UIBackgroundTaskInvalid){
        [[UIApplication sharedApplication] endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }
    bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        NSLog(@"your time is over");
        //you can call start once again to get more time
    }];
}

Where the bgTask is UIBackgroundTaskIdentifier bgTask;

My only worry would be that from my observations to get another time for background execution user has to touch the screen to make screen illuminating (screen can be locked). To make sure your code is working in background you can set up a timer and log a message on the console periodically (for example time remaining which system gave you on the background execution [UIApplication sharedApplication].backgroundTimeRemaining or restarting bluetooth). As far as I know it is quite common approach to that kind of problems.



回答2:

one of solution is this.... But sometimes not going well..

- (void) startProcess
{
    [_manager startMonitoringForRegion:beacon];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    // some process...
    [_manager startRangingBeaconsInRegion:beacon];
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    // some process...
    [_manager stopRangingBeaconsInRegion:beacon];
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    // some process...
    [_manager stopRangingBeaconsInRegion:beacon];
    [_manager stopMonitoringForRegion:beacon];
    [_manager startMonitoringForRegion:beacon];
}

i've checked bluetooth scanning run in background always.