Run in Background?

I’m working on an iOS app that periodically checks a website URL and updates itself from the information there. I want the app to continue checking at specified intervals when it is in the background but processes specific to a view are suspended when the app is not in the foreground. If I create a module to do this that is independent of the views and call it from the app when it first starts would it continue to run if the app is in the background? It would be a major rewrite to do this and I don’t want to spend time on it if it isn’t going to work.

This is not trivial in an iOS app and Xojo does not have built-in support for it. Here are Apple’s docs on the subject:

Thanks for the link.

There is another forum post about background upload/download. It seems that it can be accomplished with declares, but there is no final solution posted there. You might want to check in on that post and maybe get some answers there.

I did read the information in Paul’s link and it looks like I need to implement background fetch in my iOS app for it to update itself in the background but I haven’t yet sorted out how to do that in Xojo.

Other than using Xcode, Apple’s documentation says to include the UIBackgroundModes key with the fetch value in the app’s info.plist file but it doesn’t seem to be possible to add keys to the info.plist through the IDE. Adding a custom info.plist to the entitlements box in the IDE still results in a default info.plist in the build.

If you need to manipulate the plist, use calls to PlistBuddy in a post-build script.

NOTE: “defaults write” has been deprecated for this use (by Apple) and in recent versions of 10.10.x does not work at all.

I found a script in another thread and modified it to add the entitlement I want:

Dim App As String = CurrentBuildLocation + "/" + CurrentBuildAppName call DoShellCommand("/usr/libexec/PlistBuddy -c ""Add :UIBackgroundModes string fetch"" " + App + "/Info.plist" )
but it doesn’t work when run as an external build script from the IDE. If I run the PlistBuddy command directly from the shell it modifies Info.plist as desired but that breaks the code signature.

Also, I can’t find any documentation on the Entitlements box in the code signing settings in the IDE. How is that used to add entitlements to the Info.plist?

See https://forum.xojo.com/24391-editing-augmenting-info-plist

That’s the thread I copied the script from. The PlistBuddy command works if I run it in the terminal but the script doesn’t work as an external build script in the IDE.

Here is another way :

I prepared a text file containing the key in a minimal info.plist file :

[code]<?xml version="1.0" encoding="UTF-8"?>

UIBackgroundModes fetch [/code]

Actually I grabbed the info.plist from the build bundle and removed all keys in , then placed the new one.

Then I dragged that file into the project.

The key gets added on top of the build info.plist at compile time :

[code]?xml version=“1.0” encoding=“UTF-8”?>

UIBackgroundModes fetch CFBundleExecutable My iOS App CFBundleName My iOS App CFBundleIdentifier

etc…[/code]

Make sure you add that build script you add it after build but before code signing and you should be fine.

Thanks, I’ll give those suggestions a try.

Thanks, Michael B. I created an Info.plist containing only the key I wanted to add, dragged it into the project and it worked as you indicated.

Hi,

I was directed to this thread by Jason on the XOJO team. I have a need to run a background process on IOS that captures and sends out the GPS coordinates of the device once per minute.

Looking at this thread, it seems like that is something that would be possible by “shelling” out to IOS using a modified Plist.

Is that a correct assumption on my part?

Thanks.

Herb

How to modify the plist has been evolved by Xojo since this thread was started and is now much easier. Now you should go to build settings, click on iOS, click on the advanced gear in the inspector, turn on the Background modes switch, then select the fetch checkbox to replicate the behavior presented earlier. I don’t think there is a relevant entitlement, but if there is you need to add that to your app ID as well in Apple member center.

I’d like to fetch data opportunistically when running in the background. So, in the IDE I have to click the Background modes in the build settings and select Fetch.
That’s the easy part I guess, I still need to implement all the necessary declares for, e.g, performFetchWithCompletionHandler, myself, right?

Yes :frowning:

Somone have a working example of background data fetching in xojo?

I create currently an app which should check in intervals automatic for new data over JSON and inform the user if there is new data for him.

Thanks
Marcel

Using ImprovediOSApplication I tried adding application:performFetchWithCompletionHandler: that is necessary for running in the background.

Unfortunately, this code breaks each time the app runs:

if not class_replaceMethod(appDelegateClass, NSSelectorFromString("application:performFetchWithCompletionHandler:"), _ AddressOf impl_appPerformFetch, "v@:@@") then break

impl_appPerformFetch :

[code]Private Shared Sub impl_appPerformFetch(pid as ptr, sel as ptr, appRef as ptr, block as ptr)

ImprovediOSApplication(dispatch.Value(pid)).HandlePerformBackgroundFetch(block)

End Sub
[/code]

Either the selector application:performFetchWithCompletionHandler: isn’t correct or it’s the receiver method.

I double-checked, the plist from built app has

[quote]UIBackgroundModes
fetch[/quote]


EDIT: found the solution. Using class_addMethod.

if not class_addMethod(appDelegateClass, NSSelectorFromString("application:performFetchWithCompletionHandler:"), _ AddressOf impl_appPerformFetch, "v@:@@") then break

impl_appPerformFetch :

[code]Private Shared Sub impl_appPerformFetch(pid as ptr, sel as ptr, appRef as ptr, block as ptr)

ImprovediOSApplication(dispatch.Value(pid)).HandlePerformBackgroundFetch(block)

End Sub
[/code]