iOS 10 - App is not working in background mode after 3 minutes

I am connecting an external bluetooth peripheral to iPhone 5S(iOS 10.0.1). Peripheral sends data at every 2 seconds.

After 4 minutes(approx), peripheral goes idle & app will not receiving data from peripheral.

When I put app in background when peripheral goes idle, then upto 3 minutes (approx) app can upload/fetch data.

But I want to upload data after 25 minutes, & app is not working with 'NSTimer' or 'performSelector:afterdelay' after 3 minutes.

Can anyone have better suggestion?

Thank you in advance.

I presume this is a Bluetooth LE peripheral, and thus you’re using Core Bluetooth. If so, Core Bluetooth has explicit background mode support. I’ve not played with this myself but here’s a few links to get you started:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hey Eskimo, thank you for reply.


I am not looking about peripheral connectivity in background, cause that I have achieved.


Because peripheral is auto disconnected after some time (~4 minutes), & application goes idle after 3 more minutes.


Now my query is, in this background state,

- "Why I can't upload/download data after such long time? Is there any restriction done by iOS system itself to suspend the application in latest iOS releases?". - If there is a way to achieve, then "How can I upload/download data after 30 minutes of app went backgrond?".


Appericiate the help!

If there is a way to achieve, then "How can I upload/download data after 30 minutes of app went backgrond?".

Two things:

  • iOS provides no general mechanism for an app to schedule itself to be resumed at a specific time.

  • If an app is running, it has full access to the network, regardless of whether it’s in the foreground or background. The only gotcha is that devices with WWAN will typically shut down Wi-Fi when the device is locked.

I’m confused about your upload requirement. If you’re suspended in the background there should be no need to upload data because you can’t possibly have generated new data that warrants uploading.

As far as downloads are concerned, my standard recommendation in this space is to have your app offload the decision about what data needs to be dowloaded to a server. When the server decides that the app needs some data it can send it a silent push notification to the app, in response to which the app can kick off the download.

IMPORTANT You can use silent push notifications as a mechanism to resume your app frequently in the background because silent push notifications are subject to budgetary restrictions.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Let me explain the requirement.

Fitbit is integrated with the app & app should post data at every 30 minutes(i.e. at 12:00pm, 12:30pm & so on), if app has any data comes from external peripheral.


App should calculate sum of workouts for 30 minutes let say 12:00pm to 12:30pm & should post this sum to Fitbit dashboard at 12:30pm only (not before).


In my case,

- I have workouts from 12:00pm to 12:10pm (~10 minutes) sent by external peripheral. [my app is in background]

- Bluetooth perpheral goes idle at 12:15pm (approximate after 4 minutes of last data sent time ~12:10pm by peripheral).

- Now in background mode, I want to upload the sum of workouts to Fitbit at 12:30pm(~ approximate after 14minutes of peripheral idle time).

- BUT, my application does not work with 'NSTimer' or 'performSelector:afterDelay'.

BUT, my application does not work with 'NSTimer' or 'performSelector:afterDelay'.

Right. That’s because your app is suspended in the background at this time. iOS has no mechanism whereby you can request a resume in the background at a specific time. You’ll have to do one of two things:

  • Post the update when you do get background execution time, either before or after your deadline

  • Figure out a way to get the Bluetooth LE peripheral to resume you at the right time

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for reply, eskimo.

Hi minhaz - we're experiencing a similar issue though we're basically using eskimo's first option above ("Post the update when you do get background execution time, either before or after your deadline") by using the background fetch mode. However we still get terminated eventually at some point in time in the background. I've captured this in the thread below.


Curious if you had any luck with being able to reliably maintain the BLE connection and download data from the peripheral.


https://forums.developer.apple.com/thread/79891


Thanks,

Adam

Hi astachelek,


According to eskimo,

iOS has limitation regarding background tasks. It will keep application in suspended state after around 3 minutes when you put the app in background.


I have read your query here.

https://forums.developer.apple.com/thread/79891


Points to be taken care while background tasks,

  1. Do not use 'While' loop in background - It will tend application to low memory state and finally a crash (due to infinite execution of a block or function).
  2. [Major] : It is just a question. You have used first option. Are you performing any UI related function(task on main thread) after completing the background execution? If yes, then please try to avoid performing while in background state.


Let me know if it works.

Sorry eskimo to go a little bit of topic but basically if we have an app acting like a central, while in background, it can't execute bluetooth related operations on a regular time basis (every minute) right (if the timer is controlled by the app)? From my understanding the only option is the ble peripheral to issue a notification every minute to wake up the app right? I already created a topic about this here: https://forums.developer.apple.com/message/261776. Can you give me some feedback please?

if we have an app acting like a central, while in background, it can't execute bluetooth related operations on a regular time basis (every minute) right (if the timer is controlled by the app)?

Right. iOS has no mechanism whereby you can request a resume in the background at a specific time.

From my understanding the only option is the ble peripheral to issue a notification every minute to wake up the app right?

That’s one option. There may be others, depending on your specific situation. For example, if your app were a navigation app, you could use the

location
background mode to prevent being suspended in the background and that would allow you to use a timer in this way.

I have to say that resuming in the background every minute is unlikely to end well if the device is running off the battery. The reason why iOS’s multitasking is so limited is to allow for all day battery life.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

My app isn't a navigation app but it requires knowing the user location to send the right parameters to the ble peripheral (because it's different if the user is in different places of the globe), so maybe i can follow that approach.. I will try that, thank you!


Edit:

For documentation:

For location apps:

  • The system receives a location update that meets the app’s configured criteria for delivery.
  • The device entered or exited a registered region. (Regions can be geographic regions or iBeacon regions.)


So only when the user change his location the app receives the update and can do something about it. This doesn't match my requirements because the user can be ate the same place for several hours and i need to update the peripheral based on time too. Or can i fetch the user location coordinates on a regular basis and send it to the peripheral even if the user didn't change his location?


Justa a note: this operation needs to be silent so local notifications strategy is a no go for me. Silent push notifications either because it's only about the app and the peripheral. I will try to dig a little bit more. Thank you!

Hi eskimo.

Thanks for helping out with the concepts. But I have a few doubts. I dont know how this is going to work. Lets say the device is issuing events. The app is in backgroung or the app is terminated. Which part of the code will get exectued at that point. How do i get control over my code.

But I have a few doubts. I dont know how this is going to work.

I’m going to recommend that you open a new thread so we can discuss the specifics of your situation.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
iOS 10 - App is not working in background mode after 3 minutes
 
 
Q