Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS - Background mode doesn´t work #25

Open
marseca opened this issue Feb 29, 2016 · 13 comments
Open

iOS - Background mode doesn´t work #25

marseca opened this issue Feb 29, 2016 · 13 comments

Comments

@marseca
Copy link

marseca commented Feb 29, 2016

Version

0.6.0

Hi!

I am trying that my App run this console.log() when he finds the beacon. It works until I change to Background Mode. Then, the logs stops to show the beacons.

I set the background modes like the tutorial says: Location updates, Use Bluetooth LE accesories and I added Remote notifications ( I want the App send you a Local Notification when it finds a beacon)

My code:

class BeaconManager {
    static f_ids = []; // Beacon identifiers that we have found
    static region = {
        identifier: 'eBeacon',
        uuid: '6269736F-6E74-6500-0000-000000000000'
    };

    static Start() {
        // Request for authorization
        Beacons.requestAlwaysAuthorization();

        Beacons.startMonitoringForRegion(this.region);
        Beacons.startRangingBeaconsInRegion(this.region);

        Beacons.startUpdatingLocation();

        // Listen for beacon changes
        DeviceEventEmitter.addListener(
          'beaconsDidRange',
          (data) => {
           console.log(data); // It works until change to Background mode
          }
        );
    }
}

Steps to reproduce

  1. iOS 9.2.1
  2. iPhone 6
  3. RN 0.18
@frostney
Copy link
Owner

There is an issue with iOS 9 compatibility right now and I'm not sure that this might be a side effect. Let me see if I can reproduce the issue on my end and get back to you in a bit.

@stu60610
Copy link

In iOS 9, there is a newly added property called "allowsBackgroundLocationUpdates" in CLLocationManager class. And it's default vaule is "NO".

So if we want to range beacon in background mode, we have to set this property to "YES",
to achieve this, edit the RNBeacon.m file and add these lines below:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
    [self.locationManager requestAlwaysAuthorization];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
    self.locationManager.allowsBackgroundLocationUpdates = YES;
}
[self.locationManager startUpdatingLocation];

It should be work fine in iOS 9.

@frostney
Copy link
Owner

@stu60610 Thank you for very much. I'll package that up it into a release very soon.

@stu60610
Copy link

@frostney You're welcome. This is a great module and it helps me a lot!

BTW, If you need more information, here's some links I found to handle this problem:

http://stackoverflow.com/questions/30808192/allowsbackgroundlocationupdates-in-cllocationmanager-in-ios9

https://developer.apple.com/videos/play/wwdc2015/714/

@albo1337
Copy link

@stu60610 Thank you very much! This works like a charm

ewindso added a commit to KocomojoLLC/react-native-ibeacon that referenced this issue Jun 21, 2016
@felixaa
Copy link

felixaa commented Dec 7, 2016

Does anyone of you guys have some sample code on how you handle background scans:

if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"]) { NSLog(@"DID RECIEVE REGION"); }

Like local notifications or just opening the app

@marseca Can you confirm that @stu60610 suggestion fixed you'r issue.
I'm kinda confused on how to log/handle scans in background

@stuarttayler
Copy link

I would also like to know how to handles background scans like @felixaa.
In the README.md file there's the following snippet:

 // a region we were scanning for has appeared, ask to open us
  if([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"])
  {
    //pop a notification to ask user to open, or maybe reload your scanner with delegate so that code fires
  }

I'm assuming this goes in the AppDelegate.m file, so just wondering @frostney or anyone has more details on popping a notification and/or reloading the scanner? Does this have to be done in the appdelegate file in Swift or can I use the react-native notification library?

@felixaa
Copy link

felixaa commented Dec 13, 2016

If you want to pop a local notification you can do this.

  if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"]) {
    NSLog(@"DID RECIEVE REGION");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = @"SAH DUDE?!";
    notification.soundName = UILocalNotificationDefaultSoundName;
    
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
  }

Btw is it event possible for the JS and 'beaconDidRange' to run in background?

@stuarttayler
Copy link

Thanks @felixaa, that's really helpful.

I guess at that point there's no way to add details about the location event? I was reading on the apple dev site about how you would need to create a CLLocationManager object to get info about the location data. But by adding in more native code it seems to defeat the point of using this library?

That's why I'm wondering if there's a way to run the JS code from the ([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"]) delegate. Not sure if that's what is implied with the "reload your scanner with delegate so that code fires" comment in the code?

@felixaa
Copy link

felixaa commented Dec 28, 2016

I've kinda solved this issue(I think)

You'r AppDelegate.m needs a CLLocationManagerDelegate:

@interface AppDelegate() <CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *locationManager;

@end

Then in application didFinishLaunchingWithOptions method you need to do this:

  if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"]) {
    NSLog(@"DID RECIEVE REGION");
    
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    
    [self.locationManager requestAlwaysAuthorization];
    
    NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:@"YOUR UUID"];
    
     CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:@"YOUR IDENTIFIER"];
    
    [self.locationManager startMonitoringForRegion:beaconRegion];
  }

Then you can override didEnter/didExit region event-handlers:

-(void)locationManager:(CLLocationManager *)manager
        didEnterRegion:(CLBeaconRegion *)region {
  
  UILocalNotification *notification = [[UILocalNotification alloc] init];
  NSString *alertBody = [@"You've entered region: " stringByAppendingString:region.identifier];
  notification.alertBody = alertBody;
  notification.soundName = UILocalNotificationDefaultSoundName;
  
  [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

-(void)locationManager:(CLLocationManager *)manager
         didExitRegion:(CLBeaconRegion *)region {

  UILocalNotification *notification = [[UILocalNotification alloc] init];
  NSString *alertBody = [@"You've exited region: " stringByAppendingString:region.identifier];
  notification.alertBody = alertBody;
  notification.soundName = UILocalNotificationDefaultSoundName;
  
  [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

@jonathanroze
Copy link

When i add

 // a region we were scanning for has appeared, ask to open us
  if([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"])
  {
    //pop a notification to ask user to open, or maybe reload your scanner with delegate so that code fires
  }

And use NSLOG nothing happen :( ! Do you have an idea?

@relaxedtomato
Copy link

@Clowning - I just tried the same thing, did you make any progress on this?

@felixaa
Copy link

felixaa commented Mar 23, 2017

@Clowning @r-bansal Look at my last comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants