How to stop iBeacon scanning - ios

i tried with this Code but this delegates are not calling and not stoping the scanning, at one particular condition i need to call some other function.
-(void)locationManager:(CLLocationManager *)manager stopRangingBeaconsInRegion:(CLBeaconRegion *)region
{
NSLog(#"STOP PLEASEEEEEEEE");
}
- (void)locationManager:(CLLocationManager *)manager stopMonitoringForRegion:(CLRegion *)region {
NSLog(#"didExitRegion");
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
NSLog(#"StopRangingBeacons");
}
am using this code to start the beaconScanning
-(void)loadUIElements
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND , 0), ^{
self.beaconRegionAny = [[AIBBeaconRegionAny alloc] initWithIdentifier:#"Any"];
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.pausesLocationUpdatesAutomatically = YES;
[self.locationManager startRangingBeaconsInRegion:self.beaconRegionAny]; });
}
calling this function when start monitoring the beacons
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{

You have to remove the listener from your monitoredRegions list using stopMonitoring(for:). Here'a a link to the documentation
Have you tried this?
[self.locationManager stopMonitoringForRegion:self.beaconRegionAny];

create a button action and this line of code.
#IBAction func launchButtonClicked(_ sender: Any) {
// Determine action based on button state
switch (launchButton.currentState) {
case .Start:
beaconManager.startRangingBeacons(in: region)
launchButton.currentState = .Stop
case .Stop:
beaconManager.stopRangingBeacons(in: region)
launchButton.currentState = .Start
}
}
Try this way, it works

Related

Code Not going into DidupdateLocation() method, iOS, objective -c, going into didfailwithError()

here is my code :
if (!self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
}
if([CLLocationManager locationServicesEnabled]){
[self findCurrentLocation];
}
-(void)findCurrentLocation {
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager performSelector:#selector(requestAlwaysAuthorization)];
}
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.isLocationEnabled=YES;
self.currentLocation = newLocation;
if (currentLocation!= nil) {
latitudeValue = [NSString stringWithFormat:#"%.8f",currentLocation.coordinate.latitude];
longitudeValue = [NSString stringWithFormat:#"%.8f",currentLocation.coordinate.longitude];
}
[self.locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if([error code] == kCLErrorDenied)
{
[locationManager stopUpdatingLocation];
}
self.isLocationEnabled=NO;
}
i am not getting any errors, but didUpdateToLocation is never called, it is going into didFailWithError ()
I am getting null values for latitude and longtitude. Please let me know what can be done to get values.
from iOS8 and above:
Add a key to your Info.plist and request authorization from the location manager asking it to start.
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
You need to request authorization for the corresponding location method.
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
Please Read this Documentation: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

Can't get Region Monitoring to function

After trying for a while using Apple's documentation, Stackoverflow, Google, I still can't get a simple UIAlertView to show up when I enter or exit a region I am monitoring.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
[locationManager requestAlwaysAuthorization];
for (CLRegion *monitored in [self.locationManager monitoredRegions])
[locationManager stopMonitoringForRegion:monitored];
CLLocationCoordinate2D coord;
coord.latitude = 31.521603;
coord.longitude = 33.01190;
CLCircularRegion *region = [[CLCircularRegion alloc]initWithCenter:coord radius:20 identifier:#"work"];
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
[self showMessage:[NSString stringWithFormat:#"EnterRegion: %#",region.identifier] andMessage:#"Welcome Home" andButton:#"Ok"];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
[self showMessage:[NSString stringWithFormat:#"ExitRegion: %#",region.identifier] andMessage:#"Bye Bye" andButton:#"Ok"];
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Now monitoring for %#", region.identifier);
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error{
[self showMessage:#"msg" andMessage:[NSString stringWithFormat:#"Region Failed:%#",region.identifier] andButton:#"ok"];
}
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
[self showMessage:[NSString stringWithFormat:#"Did Determine State: %#. state:%#",region.identifier, (state == CLRegionStateUnknown) ? #"Unknown" : (state == CLRegionStateInside) ? #"INSIDE" : #"OUTSIDE"] andMessage:#"Determined" andButton:#"Ok"];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ }
showMessage is just a UIAlertView popping to the user.
sometimes I get monitoringDidFailForRegion when I set up the region sometimes I don't.
I was thinking if I should mark my app as using "Background Modes" for Location Updates, but this has not changed a thing. Seems like it should work, but I can never get didEnterRegion nor didExitRegion to be called.
I should point out that I updated the info.plist with the required keys:
<key>NSLocationAlwaysUsageDescription</key>
<string>Location is required for geofence</string>
Background app refresh is set to On, locations enabled. Testing outside, physically, I can't get the functions to be called.
What is it that can be wrong here? is 20 meters too short to define a region?
Could it be that region monitoring is not working for an app that is on the foreground? silencing the callbacks?

Why beacons cause Bluetooth to continuously toggle?

I am experiencing a really weird bug working with iOS and iBeacon. I have a really simple BeaconManager that ranges beacons with particular UUID, major and minor values and performs some actions once it found them. My app seems to work properly until it continuously toggle the Bluetooth status and stop doing its job. The only visible result is that the Bluetooth icon in the status bar start flickering due to Bluetooth stopping and restarting.
Where to focus attention?
This is my class definition:
#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
Can't say for sure this is the reason why Bluetooth keeps toggling, but this part is definitely suspicious:
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
This is essentially an infinite loop. Once monitoring starts, iOS invokes the didStartMonitoring method … which starts monitoring for the very same region, which makes the iOS invoke the didStartMonitoring method again, which …
I'd start with removing the startMonitoringForRegion line from this part of your code.

Objective C locationManager cannot get current location, always returns 0

Can you please review following code, it did tries locationManager with delegates, and tries to return current location of device.
But always returns 0 (allowed location permission)
.m
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager startUpdatingLocation];
if(IS_OS_8_OR_LATER) {
[self.locationManager requestAlwaysAuthorization];
}
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways) {
// TODO: Handle status authorized always
} else if (status == kCLAuthorizationStatusNotDetermined) {
// TODO: Handle status not determined
} else {
// TODO: Handle other
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//NSLog(#"newLocation: %#", newLocation);
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
//NSLog(#"Error: %#",[error description]);
}
info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string>We would like to use your location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We would like to use your location.</string>
Please try to call startUpdatingLocation after requestAlwaysAuthorization. and use below didUpdateLocations delegate methods.
if(IS_OS_8_OR_LATER) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
_currentLocation = [locations objectAtIndex:0];
//do your stuff with the location
}
For Simulator Testing - Select Simulator and goto Debug ->Location -> Apple or City Run
For Device Testing Please check with map if you are getting current location or not . Sometime device not getting current location due to inside of house.

Monitoring overlapping regions

I use region monitoring in ios 6 and 7. It works fine, if regions are not overlapping. But if some regions are overlapping then the app calls delegate method didEnterRegion only for one region.
My code:
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
for (XPLocationModel* locationModel in models) {
if ([self.locationManager respondsToSelector:#selector(startMonitoringForRegion:)]) {
[self.locationManager startMonitoringForRegion:locationModel.region];
} else if ([self.locationManager respondsToSelector:#selector(startMonitoringForRegion:desiredAccuracy:)]) {
[self.locationManager startMonitoringForRegion:locationModel.region desiredAccuracy:XPGeofenceMaster_DesiredAccuracy];
}
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"%s id == %#", __PRETTY_FUNCTION__, region.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
If you want, you can use the requestStateForRegion: method to get an update about all of your states, something like this. However, you better be prepared for enter and exit to be called multiple times.
- (void)requestStateForAllLocations
{
for (CLRegion *region in self.locationManager.monitoredRegions) {
[self.locationManager requestStateForRegion:region];
}
}

Resources