Is there an alternative to JobScheduler in iOS? - ios

In Android there is JobScheduler where you can schedule to execute part of your code (service) when conditions are met. For example, if one wants to synchronise data, he can schedule a task when there is network connection available and the phone is charging. The service will be called even if the app is never opened after phone restart.
Is there a way how to do this in iOS? For example, how dropbox, onedrive, etc. uploads pictures to the cloud even when the app is not opened after a restart?

I am not sure if what you are asking for is possible: launching an scheduler event though the app has not been launch after phone restart.
Anyway, this library could be a solution for background synchronization tasks: https://github.com/linkedin/Selene and here a complete guide: https://engineering.linkedin.com/ios/introducing-selene-open-source-library-scheduling-tasks-ios

Have a look at SwiftQueue to see if it meets your needs.
https://github.com/lucas34/SwiftQueue
SwiftQueue is a job scheduler for iOS inspired by popular android
libraries like android-priority-jobqueue or android-job. It allows you
to run your tasks with run and retry constraints.
Features
Sequential execution
Concurrent run
Persistence
Cancel all, by id or by tag
Delay
Deadline
Internet constraint
Single instance in queue
Retry: Max count, exponential backoff
Periodic: Max run, interval delay
Start / Stop queue
They also have a Battery charging constraint that's not listed in the features above.

Related

Execute a Task after specific time, even if app is in background on iOS using Swift

I have a VPN-Client app that asks the user to pause the connection for 5, 30, and 120 Minutes. The user probably leaves the application to do some work outside of my app in this period, therefore I need to Reconnect the app even if is in the background.
I tested these ways:
UIApplication.shared.beginBackgroundTask: It only leaves the app unsuspended for 30 seconds.
DispatchQueue.global(qos: .background).asyncAfter: It waits to app enter the foreground to toggle.
Thread.sleep in Background Thread: This waits to launch as DispatchQueue
Local Notification: Unfortunately it does not support silent mode as APNS.
My problem with possible ways:
Using APNS and Scheduled Push Notification` to send a silent message: This way probably works, but I prefer to handle it without a server.
Using Background Fetch from Capabilities in Background Modes: I searched a lot about this, and I think it was used for background app refresh and cycling tasks that should be run every day, hour, etc. Therefore, my case can't be used, or it's not efficient at all.
Using Background processing from Capabilities in Background Modes: I searched a lot about this too, I didn't quite catch that it can be used once, or this should be used in a cyclic way as Background Fetch. and my task to reconnect is not that heavy and long to use this strict feature that many times apple mentioned using alternative ways if possible.
Apple only allows a very limited set of app types to run in the background:
Music streaming apps, turn-by-turn navigation apps, VoIP apps, and maybe one or 2 more. (I haven't looked at this in detail for a couple of years so my info is a little stale.)
They do support various tasks like background downloading that the system performs on your app's behalf, but you want your app to re-launch after the designated period and start running again. (Even if the user just locks their phone while your app is paused, the app won't get any CPU time and may be terminated without warning.)
In short, I suspect you are out of luck.
It seems like a VPN app is another class of app that should get "always running in the background" status.
If you are a licensed Apple developer I suggest using one of your pre-paid support tickets to ask about OS support for what you are trying to do, but I have a feeling the answer is going to be "no dice."

iOS Background service limitations

I would like to know if there are limitations regarding how often I can execute something in the background. I found this library : background fetch and it says that on the iOS part I cannot execute it more often than 15 minutes.
Are there workarounds for this?
My purpose is to check in the background the available Bluetooth devices detected and to send them to a database.
I only have experience in android and I'm not sure how to convert it to iOS or if it is possible.
Yes, there are limitations imposed by iOS. It will decide when your app is given time to execute background tasks such as a fetch of web data. It can be more frequent than 15 minutes but on average it may be every 20 minutes at best. It might be two hours or more. We are not privy to the algorithm and cannot predict the result.
Known factors are power state, how well your app conforms to the rules and gets its work done in the time allotted, and some measure of how (and when) the user uses your app. Low battery? Fewer background tasks allowed. User never uses the app before 8AM? Few fetches called overnight. It's all beyond developer control.
A developer can use a timer to trigger a routine task but it's only relevant if the app stays active in the foreground.

Force a POST to Background sync regardless of current connectivity - behaviour on Firefox and Safari?

So I've managed to implement Background Sync with Workbox, working beautifully on Chrome. Rather than wait for a fetch to fail, I'm immediately pushing it into the bg sync queue - so that users will never have to wait for an image upload, even if they have network connectivity.
Now, on Safari and Firefox - I understand the fallback will be to attempt a background sync every time the service worker starts. However, in this case the service worked has not stopped because there has not been an interruption in network service. Does this mean I will only get this item uploaded the next time the browser is started, or the specific PWA is started, or the URL is refreshed?
To answer your question, it's impossible to know for sure when a service worker will stop running. Each browser will stop a service worker after a period of time without any events, and then start up the service worker again the next time there's an event it needs to handle (fetch, sync, etc.) But each browser implements that exact timing differently.
Workbox's background sync implementation does have a manual method that could be called to start processing items in the queue on demand.
That being said, I would not recommend interacting with the background sync queue in that fashion.
Actually attempting the upload, and then only adding items to the background sync queue upon failure (automatically, via the BackgroundSyncPlugin would be easiest) is the recommended usage.
The behavior you really want, in which uploads "happen in the background", is enabled via background fetch. Unfortunately, background fetch is also only available in Chrome at this time. I'm not sure that trying to simulate background fetch in browsers that don't support it, and don't support background sync, is going to give non-Chrome users a great experience.

Performing background task every minute

I'm looking to perform network tests every minute for an hour to check whether or not the user has a connection -
Ideally I'd like to get their location every minute (but not 100% necessary) and ping a server. Is this possible by either the user pressing a UIButton "start test" and then if they close the app it still runs?
Or, activate a function when the user is in a location range at a given time? (Looking to perform tests at events)
Or, possibly using a push notification to activate the function? This seems very impractical though.
My research has shown this is typically only available for VOIP or Audio apps, and background fetch based are either restricted in duration or scheduled by the device itself based on the user's behaviour, which I don't want.
Note: The app doesn't necessarily have to be released on the app store, this is just a small project so running it on a few devices will suffice.

swift/ios refreshing app data when in background

I'm writing a iOS/Swift application which reads data from a REST service each X minutes and updates the UI accordingly.
Now I would like that when the app is put in the background, a task keeps being invoked at X minutes intervals reading from the REST service and, in case the data just read satisfies a given condition, show a notification prompting the user to bring the app back to the foreground.
In my searches I've read that during applicationDidEnterBackground event, I should start a task with beginBackgroundTaskWithExpirationHandler.
The problem is that, if I've understood correctly, this allows a maximum of 10/15 minutes after which the app is terminated if the task is not stopped with endBackgroundUpdateTask, while I want the task to keep polling the service indefinitely (at least until the user disable it from the app's settings)
My question is:
How is this kind of functionality performed normally? Do some common solutions or best practices exist for the solution of such a problem?
Use iOS Background Fetch feature where you can specify minimum background fetch interval. But actual interval between successive invocation of your code will be determined by iOS framework. For details checkout this link: http://code.tutsplus.com/tutorials/ios-7-sdk-working-with-background-fetch--mobile-20520
I use this approach in my app and I think it is a preferred way of doing.
You can use a local notification that can be presented from the background in case your condition is met.
Correct, iOS will eventually shut down the background process, you can't enforce continuous background activity. Use the backgroundTimeRemaining property to check how much time your application has left and try to handle it as gracefully as possible by calling endBackgroundTask so that iOS does not force kill your app.
As a solution, you could think about using remote notifications with with content-available : YES, which runs the didReceiveRemoteNotification
Have a look at the Parse.com Their local datastore is an abstraction for what you are trying to acheive.
By the way, is it really necessary to refresh in the background. If call is relatively quick, there is no need to refresh until the user open's the app. Background processes like that, using the net can be quite battery consuming when the user are not on a Wifi. So consider the use case carefully!

Resources