1

Is there any way to run NSTimer for more than 3 mins in background? I have to create simple app that uses

 `locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion)`

for scan my beacons. I have run into problem when I needed to check if user is exactly 10 seconds near closest beacon. I created

    var timer: NSTimer?
    var lastClosestBeacon: CLBeacon? {
        didSet {
            timer?.invalidate()
            timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "showLocalNotification", userInfo: nil, repeats: false)
//            NSRunLoop.mainRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
        }
    }

When closest beacon changes lastClosestBeacon is set and timer is scheduled. It is working in App and for 3 mins when user enters background(locks phone etc.) with help from Scheduled NSTimer when app is in background? Is there any possibility to check that for more than 3 mins ?

PS. I have already added Background Modes with location updates.

Community
  • 1
  • 1
Mateusz Tylman
  • 271
  • 1
  • 2
  • 17
  • Have you read about [*Background Execution*](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html)? – trojanfoe Feb 10 '16 at 11:10
  • 1
    Please please please keep in mind that unless your app provides some serious location-related value to the user (e.g., turn-by-turn navigation, notification to get off at the next bus stop, etc.), Apple will rejected your app for an unjustified use of the "location" background mode. – heypiotr Feb 19 '16 at 14:30

2 Answers2

4

You can do it by following way:

1) First include required background mode keys into your Info.plist

2) Check and add following line of code for adding background working of location manager in iOS 9 (update: also works in iOS 10):

if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
    [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    [self.locationManager pausesLocationUpdatesAutomatically:NO];
}

3)Then create a new timer with repeated continuously with every 1 sec.

4)In that timer method add these two line of code.

[self.locationManager stopUpdatingLocation];
[self.locationManager startUpdatingLocation];

This make your app run in background more than 3 mins. To be aware, the battery usage may be costly.

Akshay Sunderwani
  • 12,428
  • 8
  • 29
  • 52
3

As of iOS 9, apps are allowed a maximum of 180 seconds (3 minutes) of background execution time upon request. This can be extended indefinitely if you put location updates in the “Required background modes” in your Info.plist. I have verified that doing so lets the background execution run forever. Having this in your Info.plist, however, will require you to get approval from Apple for this background mode before putting your app in the App Store.

If you don't want to request location background mode, there are some other tricks you can do to get around Apple's restrictions, which you can read about here: https://gooddevbaddev.wordpress.com/2013/10/22/ios-7-running-location-based-apps-in-the-background/

A word of caution about using those tricks, though -- they are subject to change in any iOS upgrade, and using them might get your app rejected by reviewers.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • I already have in Info.plist Required background modes with location updates. App can run forever with scanner but timer option only works for 3 mins after phone is locked/app entered background.As I wrote my task is to measure in background if user is near 1 beacon for 10 seconds(closest beacon) and it is working only for 3 mins after app enters background mode. – Mateusz Tylman Feb 10 '16 at 12:00
  • "I already have in Info.plist Required background modes with location updates" but you are not _doing_ background location updates. Thus you are suspended. It is not enough to request the right to run in the background. You must in fact run in the background. Otherwise you and your timer are suspended. The scanner does not cause the app to run in the background at all. The system is doing that work for you. – matt Feb 10 '16 at 12:10
  • Hi i'm trying post local notification when app is in background but this is working 30 secs only. I have added required background mode in my info.plist. what should i do?? – Abhishek Thapliyal Jan 31 '17 at 18:41
  • You still need a background task as described in the tutorial. If that doesn't work, you should open a new question and show your code. – davidgyoung Jan 31 '17 at 23:40
  • @davidgyoung : i m trying in app delegate so i'm getting 180 secs window but same i'm tring to my class it's getting only max 36 secs what should i do : : http://stackoverflow.com/questions/42266258/ios-9-beginbackgroundtaskwithexpirationhandler-is-getting-called-before-timout/42338898?noredirect=1#comment71831187_42338898 – Abhishek Thapliyal Feb 21 '17 at 06:10