I am getting data from and hardware iBeacon , in which i can program to change its UUID.
I know the UUID of the hardware, but i dont understand what is the identifier in :
[[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"com.name.iBeacon"];
Is it my app identifier, or something the iBeacon is transmitting(its name?)
I wonder if this is why its not working .
I have set everything and i can't even discover the iBeacon :
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"74278BDA-B644-4520-8F0C-720EAF059935"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"com.company.iBeacon"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
[self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion];
Than these delegates, which are in the same class(should be in app delegate?) are never fired :
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"ENTER");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"EXIT");
}
I have read that you have to go in and out from the area ??
Another issue is, Apple says every BLE has services,that includes characteristic, but than, in iBeacon, what are the major and minor values? characteristics of the same service ?
Got it ,
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
Must be done first .
Related
Here is a code I use to detect Eddystone using iPhone iOS 9:
- (void)viewDidLoad
{
[super viewDidLoad];
if ([CLLocationManager locationServicesEnabled]) {
_locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager requestAlwaysAuthorization];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"f7826da6-4fa2-4e98-8024-bc5b71e0893e"];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:bundleIdentifier];
self.locationManager.allowsBackgroundLocationUpdates = YES;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];
}
else {
NSLog(#"location service is disabled");
}
}
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(nonnull NSArray<CLBeacon *> *)beacons
inRegion:(nonnull CLBeaconRegion *)region
{
NSLog(#"beacons count: %lu", (unsigned long)[beacons count]); // beacons count always "0"
}
Also I added in plist NSLocationAlwaysUsageDescription field.
The problem is that it can't detect any Eddystone device with code above. But with third party apps it finds well.
What I'm doing wrong?
Your code is using Core Location, which only works with iBeacon. You won't be able to discover Eddystone beacons this way.
You need to use some Eddystone-compatible SDK. Since you seem to be using Kontakt.io's beacons, you might want to use their SDK:
http://developer.kontakt.io/ios-sdk/quickstart/#eddystone-support
Alternatively, you can use iOS's native Core Bluetooth to implement Eddystone scanning yourself. There's even an example on how to do that, available in the official Eddystone GitHub repo:
https://github.com/google/eddystone/tree/master/tools/ios-eddystone-scanner-sample
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.
My app should get the user's current location only one time.
It's doing it successfully using the location manager and a delegate. Once i get the location for the first time my delegate calls the manager to stopUpdatingLocation.
Since I'm using ARC, and I keep an instance of this class during all the time my app runs, my CLLocationManager instance stays in memory.
I know GPS services are quite power consuming, but does it have the same effect while i actually don't consume more events? does it keep on working?
I want to know if i should add some logic to release it.
Try Following...
-(void)updateLoc
{
if (self.locationManager != nil)
{
[self.locationManager stopUpdatingLocation];
self.locationManager.delegate = nil;
self.locationManager = nil;
}
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
self.locationManager.headingFilter = 1;
self.locationManager.distanceFilter=10.0;
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{//Use if you are supporting iOS 5
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
}
I am Ahmet. I have been trying to solve a problem for 3 days, that I have about communicating with Estimote beacon first time. (I am quite new on beacons), I have read a lot of articles and looked for many example codes. Even tried the Estimote example app (provided in the Estimote SDK file). Some how I could not find the beacons through the code that I have written and example code (app) in the SDK file. But estimote application on the app store works fine.
I am using MacBookPro late 2011 version.
If you help me about this, I would appreciated that. My purpose is to communicate first, then the rest will come. I cannot go out from the house, so I have written the code in that way.
Here is the code that I am using.
//MainViewController.h
#interface MainViewController : UIViewController<CLLocationManagerDelegate>
#property(nonatomic, strong)CLBeaconRegion *beaconRegion;
#property(nonatomic, strong)CLLocationManager *locationManager;
#end
#implementation MainViewController
(void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
[self initRegion];
[self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"did start monitoring");
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
-(void)initRegion
{
NSLog(#"Init Region");
NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];
self.beaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:#"identifier"] ;
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"Did enter region"); // never called
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(#"Did exit region"); // never called
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"NO Beacon Found...");
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
NSLog(#"did range Beacons");
CLBeacon *beacon = [[CLBeacon alloc]init];
beacon = [beacons lastObject];
NSLog(#"BEACON FOUND");
NSLog(#"Proximity UUID: %#",beacon.proximityUUID.UUIDString);
NSLog(#"MAJOR ID: %#", beacon.major);
NSLog(#"MINOR ID: %#", beacon.minor);
}
#end
According to MacTracker, your MacBookPro is not compatible.
Apple put a Bluetooth Low-Energy chip in its MacBook Pro starting with the Mid 2012.
Since iBeacon use in reality BLE (which is hidden, at least in the iOS part: CLBeacon vs CoreBluetooth), you won't detect iBeacon with your MBP, except if you may have a special BLE chip (extern, as some USB one we can find in the market).
To verify if you laptop is BLE compatible, I'd suggest you read this on SuperUser.
I'm having an issue where my app will not fire the didEnterRegion event if I start the app within the region. If I start the app outside the region and then enter the region, it fires. If I start the app inside the region, then leave the region, then re-enter the region, it fires.
Any suggestions on how to get it to fire as soon as the app is opened if it's in the region would be much appreciated!
I suggest you to use this code
[locationManager requestStateForRegion:region];
And use the delegate method didDetermineState: to check if the state is CLRegionStateInside or CLRegionStateOutside.
I don't think you can do that.
But, you can get the current location and check if it's inside the region you're specifying yourself. CLCircularRegion has a containsCoordinate: method for this.
The first conclusion is that didEnterRegion is implemented consistently with its name. :)
Implement something like this in your CLLocationManagerDelegate:
- (void) locationManager: (CLLocationManager *) manager
didStartMonitoringForRegion: (CLRegion *) region
{
if ([self insideRegion: region location: manager.location])
[self locationManager: manager
didEnterRegion: region];
}
From apple's documentation:
Monitoring of a geographical region begins immediately after
registration for authorized apps. However, don’t expect to receive an
event right away, because only boundary crossings generate an event.
In particular, if the user’s location is already inside the region
at registration time, the location manager doesn’t automatically
generate an event. Instead, your app must wait for the user to cross
the region boundary before an event is generated and sent to the
delegate. To check whether the user is already inside the boundary
of a region, use the requestStateForRegion: method of the
CLLocationManager class.
So I ended up doing this:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSDictionary *regionDictionary;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// setup regions in case you have multiple regions
self.regionDictionary = #{#"com.test" : #"2FAE2A83-1634-443B-8A0C-56704F81A181"};
// setup location manager
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
//start monitoring for all regions
for (NSString *key in self.regionDictionary.allKeys) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[key]] identifier:key];
[self.locationManager startMonitoringForRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region {
if (region.identifier.length != 0) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region {
if (region.identifier.length != 0) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region {
// Beacon found!
CLBeacon *foundBeacon = [beacons firstObject];
NSLog(#"UUID:%#; major:%#; minor:%#;", foundBeacon.proximityUUID.UUIDString, foundBeacon.major, foundBeacon.minor);
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if ([region isKindOfClass:[CLBeaconRegion class]] && state == CLRegionStateInside) {
[self locationManager:manager didEnterRegion:region];
}
}
- (void)locationManager:(CLLocationManager *) manager didStartMonitoringForRegion:(CLRegion *) region {
[manager requestStateForRegion:region];
}