Pushing a view and poping back on your promimity demo

i m working on estimote beacon.

I try to present a ViewController when i m in switch Case "immediate". But when i the view is loaded, i have a warning :

2014-03-13 02:44:26.017 ProximityDemo[856:60b] Warning: Attempt to present on whose view is not in the window hierarchy!

Why ? I think the presentView Method is still working while i m on the new view.

Also when i m on the new View , i would like to pop to old view when i m in Case "Near"

I Think i have to implement all the the code in the new ViewController ? (presentProductViewController) Is there a way to have all the proximity/distance controll in only one Controller ?

Here is my code :

ESTViewController :

#import "ESTViewController.h"
#import <ESTBeaconManager.h>
#import "PresentProductViewController.h"

@interface ESTViewController () <ESTBeaconManagerDelegate>

@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;

@end

@implementation ESTViewController

  • (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.

/////////////////////////////////////////////////////////////
// setup Estimote beacon manager

// craete manager instance
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
self.beaconManager.avoidUnknownStateBeacons = YES;

// create sample region object (you can additionaly pass major / minor values)
ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTEIOSBEACONPROXIMITY_UUID
identifier:@"EstimoteSampleRegion"];

// start looking for estimote beacons in region
// when beacon ranged beaconManager:didRangeBeacons:inRegion: invoked
[self.beaconManager startRangingBeaconsInRegion:region];

}

-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
if([beacons count] > 0)
{

if(!self.selectedBeacon)
{
    // initialy pick closest beacon
    self.selectedBeacon = [beacons objectAtIndex:0];
}
else
{
    for (ESTBeacon* cBeacon in beacons)
    {
        // update beacon it same as selected initially
        if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
           [self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
        {
            self.selectedBeacon = cBeacon;
        }
    }
}



// beacon array is sorted based on distance
// closest beacon is the first one

NSString* labelText = [NSString stringWithFormat:
                       @"Major: %i, Minor: %i\nRegion: ",
                       [self.selectedBeacon.major unsignedShortValue],
                       [self.selectedBeacon.minor unsignedShortValue]];

// calculate and set new y position
switch (self.selectedBeacon.proximity)
{
    case CLProximityUnknown:
    {
        labelText = [labelText stringByAppendingString: @"Unknown"];
        break;
    }
    case CLProximityImmediate:
    {
        labelText = [labelText stringByAppendingString: @"Immediate"];

        PresentProductViewController *showViewController = [[PresentProductViewController alloc] initWithNibName:@"PresentProductViewController" bundle:nil];

        [self presentViewController:showViewController animated:YES completion:nil];

        break;
    }
    case CLProximityNear:
    {
        labelText = [labelText stringByAppendingString: @"Near"];
        break;

        //[self.navigationController popToRootViewControllerAnimated:YES];
        //ESTViewController *initViewController = [[ESTViewController alloc]init];
        //[self presentViewController:initViewController animated:YES completion:nil];
    }
    case CLProximityFar:
    {
        labelText = [labelText stringByAppendingString: @"Far"];
        break;
    }

    default:
        break;
}

self.distanceLabel.text = labelText;

}
}

  • (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.

PresentProductViewController :

#import "PresentProductViewController.h"
#import <ESTBeaconManager.h>
#import "ESTViewController.h"

@interface PresentProductViewController () <ESTBeaconManagerDelegate>

@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;

@end

@implementation PresentProductViewController

  • (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization
    }
    return self;
    }

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.activityIndicator startAnimating];

/////////////////////////////////////////////////////////////
// setup Estimote beacon manager

// craete manager instance
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
self.beaconManager.avoidUnknownStateBeacons = YES;

// create sample region object (you can additionaly pass major / minor values)
ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTEIOSBEACONPROXIMITY_UUID
identifier:@"EstimoteSampleRegion"];

// start looking for estimote beacons in region
// when beacon ranged beaconManager:didRangeBeacons:inRegion: invoked
[self.beaconManager startRangingBeaconsInRegion:region];

}

-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
if([beacons count] > 0)
{

if(!self.selectedBeacon)
{
    // initialy pick closest beacon
    self.selectedBeacon = [beacons objectAtIndex:0];
}
else
{
    for (ESTBeacon* cBeacon in beacons)
    {
        // update beacon it same as selected initially
        if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
           [self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
        {
            self.selectedBeacon = cBeacon;
        }
    }
}



// beacon array is sorted based on distance
// closest beacon is the first one

self.labelText.text = [NSString stringWithFormat:
                       @"Major: %i, Minor: %i\nRegion: ",
                       [self.selectedBeacon.major unsignedShortValue],
                       [self.selectedBeacon.minor unsignedShortValue]];

// calculate and set new y position
switch (self.selectedBeacon.proximity)
{
    case CLProximityUnknown:
    {
        self.labelText.text = [self.labelText.text stringByAppendingString: @"Unknown"];
        break;
    }
    case CLProximityImmediate:
    {
        self.labelText.text = [self.labelText.text stringByAppendingString: @"Immediate"];
        break;
    }
    case CLProximityNear:
    {
        self.labelText.text = [self.labelText.text stringByAppendingString: @"Near"];
        break;

        //UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main.storyboard" bundle:nil];
        //UIViewController *initViewController = [storyBoard instantiateInitialViewController];

        //[self.navigationController pushViewController:initViewController animated:YES];

        //ESTViewController *initViewController = [[ESTViewController alloc]init];
        //[self presentViewController:initViewController animated:YES completion:nil];

        //[self.navigationController popToRootViewControllerAnimated:YES];

    }
    case CLProximityFar:
    {
        self.labelText.text = [self.labelText.text stringByAppendingString: @"Far"];
        break;
    }

    default:
        break;
}

}
}

-(void)viewDidDisappear:(BOOL)animated
{
[self.activityIndicator stopAnimating];
}

  • (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }

@end

i added this code to avoid warning message:

  • (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.beaconManager stopRangingBeaconsInRegion:region];
    }

  • (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.beaconManager startRangingBeaconsInRegion:region];
    }

I hope this will help others people who will have same problem as me.
Anyone can help me to pop my view back when i go away the beacon ?
Thx you.

Ok i found it.

Let me know, if you have any other question!