0

I have an app that needs to perform some actions based on a TTimer.

When the app becomes inactive (in background), the timer stops working.

I could not find any relevant options for UIBackgroundModes.

How can I make a timer keeps running?

DanielH
  • 123
  • 1
  • 10
  • 2
    The app is paused shortly after entering background. You can enable your app to run in the background, but it will still only work if user has allowed apps to run in the background. Just find out how to do it with Xcode/ObjectiveC then you can convert it for use in your Delphi app. – Hans Jan 14 '16 at 07:39

1 Answers1

0

iOS pauses your app automatically shortly after it goes into the background. You need to let iOS know that you are going to continue operating in the background.

In Project > Options > Version Info you can add to the array key UIBackgroundModes the string values for the services that require to continue running in the background. This gets added to the info.plist for your project on iOS.

You can consult Apple's documentation on what these values do . . .

  • Value - Description
  • audio - The app plays audible content in the background.
  • location - The app provides location-based information to the user and requires the use of the standard location services (as opposed to the significant change location service) to implement this feature.
  • voip - The app provides Voice-over-IP services. Apps with this key are automatically launched after system boot so that the app can reestablish VoIP services. Apps with this key are also allowed to play background audio.
  • fetch - The app requires new content from the network on a regular basis. When it is convenient to do so, the system launches or resumes the app in the background and gives it a small amount of time to download any new content. This value is supported in iOS 7.0 and later.
  • remote-notification - The app uses remote notifications as a signal that there is new content available for download. When a remote notification arrives, the system launches or resumes the app in the background and gives it a small amount of time to download the new content. This value is supported in iOS 7.0 and later.
  • newsstand-content - The app processes content that was recently downloaded in the background using the Newsstand Kit framework, so that the content is ready when the user wants it. This value is supported in iOS 5.0 and later.
  • external-accessory - The app communicates with an accessory that delivers data at regular intervals. This value is supported in iOS 5.0 and later.
  • bluetooth-central - The app uses the CoreBluetooth framework to communicate with a Bluetooth accessory while in the background. This value is supported in iOS 5.0 and later.
  • bluetooth-peripheral - The app uses the CoreBluetooth framework to communicate in peripheral mode with a Bluetooth accessory. The system will alert the user to the potential privacy implications of apps with this key set. See Best Practices for Maintaining User Privacy for more information on privacy. This value is supported in iOS 6.0 and later.

Notice you need to actually select the mode that matches what you are doing. You can't just select fetch when really all you are doing is background processing.

Jim McKeeth
  • 38,225
  • 23
  • 120
  • 194
  • Thanks you for your answer but as I mentioned, none of the UIBackgroundModes values seems relevant. I need that timer to keep running. – DanielH Jan 15 '16 at 23:30
  • 1
    @DanielH unfortunately those are the only options provided by Apple. That is a limitation of the platform. I thought you meant you couldn't find any options for setting the UIBackgroundMode, which is why I explained how to set them. – Jim McKeeth Jan 15 '16 at 23:32
  • @Tim - So in other words there is no way to have a timer running in background mode. For the sake of testing, I checked if a location service runs in background using a TLocationSensor and setting the UIBackgroundModes option to "location" and it does not work neither. – DanielH Jan 16 '16 at 00:19
  • @DanielH What is your timer doing? How do you know if it is running? The OS still manages it in the background. For example the fetch mode means your app only gets woken up occasionally to fetch data. – Jim McKeeth Jan 16 '16 at 00:23
  • @Tim The timer is supposed to terminate a connection and what happens is that the OnTimer is fired only when the application become active again. – DanielH Jan 16 '16 at 01:05
  • @DanielH maybe there is a different event you could close the connection on. – Jim McKeeth Jan 18 '16 at 15:53
  • @Tim The connection should close after a certain period of time from the moment the device went to background mode. I tried with a TThread looping with TickService.GetTick but it's also stopped. I'm open to other ideas. – DanielH Jan 18 '16 at 18:52
  • @DanielH iOS is suspending your app. Probably the best way to do this is with the Fetch mode, and then close the connection when it gets resumed. This means it will probably stay open longer than you want, but it is the most inline with Apple's background operation modes. If you need to know when the app went it background, then have the client notify the server that the app went into the background, and then when the app wakes up for "fetch" it can close the connection. – Jim McKeeth Jan 18 '16 at 19:33
  • @Tim I thought going that way but I could not find how to implement an onFetch event. If I can implement such event then I can calculate the time elapsed and react accordingly. – DanielH Jan 18 '16 at 19:44