iOS 8: Region Monitoring, how to make it work - ios

Here's the code snippet. Below.
// Initialize the region with the Estimote iBeacon manually generated UUID of 16 bytes size.
NSUUID *estimoteUUID = [[NSUUID alloc] initWithUUIDString:[Repository getiBeaconRegionUUID]];
_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:estimoteUUID
identifier:#"A"];
// Launch app when display is turned on and inside region.
_beaconRegion.notifyEntryStateOnDisplay = YES;
// Create a location manager
_locationManager = [[CLLocationManager alloc] init];
// Set delegate
_locationManager.delegate = self;
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
[_locationManager requestAlwaysAuthorization];
[_locationManager startMonitoringForRegion:_beaconRegion];
// Get status update right away for UI
[_locationManager requestStateForRegion:_beaconRegion];
}
else
NSLog(#"This device does not support monitoring beacon regions");
There is the NSLocationAlwaysUsageDescription added to the app. plist.
There was never the dialog with the text from the key above.
In Settings => Privacy => Location Services for the app. was turned off after the first app. run.
The delegate method
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state
forRegion:(CLRegion *)region
is never called.
In iOS 7 the same app. worked without the authorization request.
Share your experience.

i have face same problem when i migrate to ios8 from ios7.and i have done following way with the apple doc with explanation of mine.
Check What apple says Here :
APPLE DOC
from iOS 8, NSLocationWhenInUseUsageDescription or a NSLocationAlwaysUsageDescription key value in Info.plist file is required.but also you need to request permission from the user before you registering for location updates, either by calling [_locationManager requestWhenInUseAuthorization] or [_locationManager requestAlwaysAuthorization] choose any of above as per you requirement.
please note this info it will gonna help through out ios 8.

After I added NSLocationAlwaysUsageDescription key-value pair into InfoPlist.strings it showed the dialog and started to work.

Related

iBeacon and iOS 9

I'm currently working on app that requires iBeacon monitoring.
I wrote the app one year ago, using iOS 8.x SDK.
It was working as it was supposed to, but now, one year from then, the same code doesn't work anymore (I'm testing it with the same beacons!).
Beacon regions detection has become much more unpredictable.
It has a will of its own.
Some beacons get detected, some are just ignored.
I couldn't find anything relevant on OpenRadar.
A few people complained about something similar on Apple Dev Forums, but Apple never came back to them.
Thoughts?
This is how I initialize the location manager.
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
// Worst accuracy is set in order to preserve battery life.
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
self.locationManager.allowsBackgroundLocationUpdates = YES;
// Required to keep the app living in the background.
// Background mode "Location Updates" is enabled.
[self.locationManager startUpdatingLocation];
I think before you were using geofences or CLCircular regions. Core location doesn't need any of that code to detect iBeacons. Try setting it up like this:
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
[self.locationManager startMonitoringForRegion:beaconRegion]; // Where "beaconRegion" is a CLBeaconRegion with a UUID that matches the beacon you want to detect (major & minor optional)
beaconRegion.notifyEntryStateOnDisplay = YES;
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
You also need to add NSLocationAlwaysUsageDescription to your info.plist. Once all that is done, you should begin getting enter and exit events for your beacons through these two methods:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region;

Is there anyway to monitor CLBeaconRegion without using CLLocationManager

In my current app i am using
self.locationManager = [[CLLocationManager alloc] init];
if ([_locationManager respondsToSelector:#selector(requestAlwaysAuthorization)])/
[_locationManager requestAlwaysAuthorization];
//self.locationManager.allowsBackgroundLocationUpdates = YES;
self.locationManager.delegate = self;
[self.locationManager startMonitoringForRegion:tempRegio
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
in this case nowhere i need to know user's location still my app asks that it will use you current location even when you're not using this app
Which is annoying for end user plus it constantly display purple arrow on the statubar indicating that the app uses GPS (Which it does not )
My question is
Can we have mechanism where we can scan the beacon without use of CLLocationManager
1 possible solution is to use CBCentralManager but i do not find a proper way where i can use it to detect beacons/ibeacons
Thanks

Is it possible to allow iBeacon app work properly without GPS?

I've been working on iOS app which interacts with iBeacon devices. Workflow is next:
if user near iBeacon then app receiving push notification from internet.
So for recognizing if user near some iBeacon needs to be turned on next modules:
gps
bluetooth
wifi/3G
push notification
The issue is that without turned on GPS module app can't find any iBeacons. It's weird since iBeacon technology works using bluetooth only.
How to solve the following problem?
I use Xcode 6.1.1, iOS 8, CoreLocation and CoreBluetooth frameworks.
Here is a code how I implemented:
if ([CLLocationManager locationServicesEnabled]) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
if([_locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"12345678-1234-1234-1234-123456789012"];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:bundleIdentifier];
[_locationManager startMonitoringForRegion:beaconRegion];
[_locationManager startRangingBeaconsInRegion:beaconRegion];
}
else {
NSLog(#"location service is disabled");
}
You don't need GPS for iBeacon to work, but you do need Location Services.
This why I asked how you were "turning off the GPS", as I am not aware of any way in iOS that you can turn off the GPS receiver specifically.
When the user disables Location Services in the Settings app they aren't just turning off GPS - as the name says, they are turning off Location Services. Location Services in iOS refers to anything that can locate the user, which includes GPS, WiFi location and iBeacon.
No, without GPS, iBeacon will not work properly. CLLocation Manager is a class in the core location framework. The delegates of CLocation Manager will not get triggered without GPS. Here iBeacon works with the help of CLocation Manager.
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;
This is the delegate that is getting triggered while an iBeacon is identified in a region. This delegate will not work without GPS.

Get User location alert does not stay on screen in iOS 8

I am trying to get authorization from user before fetching his location. I am using this code for that:
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// iOS8+
// Sending a message to avoid compile time error
[self.locationManager requestAlwaysAuthorization];
}
[self showIndicatorView];
self.getCityService = [[GetCitiesService alloc] initServiceWithDelegate:self isLocalCall:NO];
[self.getCityService fetchCities];
I see the alert on screen but before I allow it or not, it disappear form screen and app is not authorized.
I want my code to stop until user gives permission.
Apparently in iOS 8 SDK, requestAlwaysAuthorization (for background location) or requestWhenInUseAuthorization (location only when foreground) call on CLLocationManager is needed before starting location updates.
There also needs to be NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist with a message to be displayed in the prompt. Adding these solved my problem.
Hope it helps someone else.
EDIT: For more extensive information, have a look at: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
You code looks really weird, since you seem to be calling the requestAlwaysAuthorization twice. Once on self.locationManager and once via the sendAction.
You code should look like:
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// iOS8+
// Sending a message to avoid compile time error
[self.locationManager requestAlwaysAuthorization];
}

iOS App gets invalid user location

when I'm trying to show the user location on my map it shows the location is somewhere in the ocean (lat = 0.000 , lon = 0.000) , I have set the simulated location to be in london and still nothing.
when i try to compile the app on my iphone its doesn't ask for permission to get user current location , just when i enable the app for using location services in the iphone settings , the app shows the user current location.
any idea why it does it?
this is my viewDidLoad :
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager = [[CLLocationManager alloc] init];
if(IS_OS_8_OR_LATER) {
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
}
_locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[_locationManager startUpdatingLocation];
There is no need to adding both they both do different things
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
requestWhenInUseAuthorization
use [_locationManager requestWhenInUseAuthorization]; when you want to get location updates when app is Active of foreground mode and not when in background .
requestAlwaysAuthorization
use [_locationManager requestAlwaysAuthorization]; when you want to get location updates Even when your app is in background mode. So OS would ask for permissions accordingly
Adding Keys to info.Plist
It is now mandetory to add either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription Key to your info.Plist depending upon which permission you are asking for .
The value to this key should be a NSString explaining user why the app wants to use location services something like "We need your location for XYZ reason"
If iOS does not find above key in your Plist file , it will ignore location request.
Hope this helps. By the way I reccomand you to watch WWDC 2014 video "Whats new in Core Location", all iOS8 changes have been nicely explained.
Other Changes in Code
Also one more thing i see in your code , You are creating new instance of _locationManager in 3rd line , Means you are creating new object after assigning delegate to locationManager, should not do that too.

Resources