Search code examples
iosxamarinibeaconestimote

Xamarin Estimote not finding beacons for iOS


Im just trying to get a really simple POC of my multiplatform app finding ibeacons in a crossplatform xamarin solution. I've got the android side of things going but just hitting issues with the iOS side of things.

I've got the following hacked up code in the AppDelegate class (this is just to first muck around with it, i realize this isnt where it should reside):

[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
    UIWindow window;

    static readonly string uuid = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
    static readonly string monkeyId = "Monkey";

    CBPeripheralManager peripheralMgr;
    BTPeripheralDelegate peripheralDelegate;
    CLLocationManager locationMgr;

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        window = new UIWindow(UIScreen.MainScreen.Bounds);

        myAppManagerApp.Init(typeof(myAppManagerApp).Assembly);
        Forms.Init();
       // FormsMaps.Init();            

        UINavigationBar.Appearance.BackgroundColor = UIColor.FromRGBA(0, 0, 0, 0);
        UINavigationBar.Appearance.TintColor = UIColor.Blue;          
        UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
        {
            TextColor = UIColor.White
        });

        window.RootViewController = BuildView();
        window.MakeKeyAndVisible();

        var monkeyUUID = new NSUuid(uuid);
        var beaconRegion = new CLBeaconRegion(monkeyUUID, monkeyId);
        //power - the received signal strength indicator (RSSI) value (measured in decibels) of the beacon from one meter away
        var power = new NSNumber(-59);
        NSMutableDictionary peripheralData = beaconRegion.GetPeripheralData(power);
        peripheralDelegate = new BTPeripheralDelegate();
        peripheralMgr = new CBPeripheralManager(peripheralDelegate, DispatchQueue.DefaultGlobalQueue);
        peripheralMgr.StartAdvertising(peripheralData);

        locationMgr = new CLLocationManager();
        locationMgr.RegionEntered += (object sender, CLRegionEventArgs e) =>
        {
            if (e.Region.Identifier == monkeyId)
            {
                var notification = new UILocalNotification() { AlertBody = "There's a monkey hiding nearby!" };
                UIApplication.SharedApplication.PresentLocationNotificationNow(notification);
            }
        };

        locationMgr.DidStartMonitoringForRegion += locationMgr_DidStartMonitoringForRegion;
        locationMgr.MonitoringFailed += locationMgr_MonitoringFailed;

        locationMgr.StartMonitoring(beaconRegion);
        locationMgr.StartRangingBeacons(beaconRegion);

        locationMgr.DidRangeBeacons +=locationMgr_DidRangeBeacons;

        return true;
    }

    private void locationMgr_DidRangeBeacons(object sender, CLRegionBeaconsRangedEventArgs e)
    {
            throw new NotImplementedException();
    }

    private void locationMgr_MonitoringFailed(object sender, CLRegionErrorEventArgs e)
    {
        throw new NotImplementedException();
    }

    private void locationMgr_DidStartMonitoringForRegion(object sender, CLRegionEventArgs e)
    {
        int i = 0;
        //throw new NotImplementedException();
    }

    static UIViewController BuildView()
    {
        var root = new pgeRoot();
        var controller = root.CreateViewController();
        return controller;
    }

Ive chopped most of the code out of the Find the monkey sample. Either way the DidRangeBeacons or RegionEntered events never fire. I'm using estimote iBeacons so i dont know whether that makes a difference?

Any ideas on what im missing here? Is there a permission or setting i need to put into the plist?

Thanks


Solution

  • In iOS 8 you need to explicitly ask for permission to use Location Services - it's the CLLocationManager's RequestAlwaysAuthorization (for monitoring) and RequestWhenInUseAuthorization (for ranging) methods. You also need an appropriate (NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription) entry in the Info.plist file of your iOS app, though I'm not entirely surely how to do this in Xamarin.