I am iOS developer and currently working on a Project which needs to hit an API after every 1 min in background and I am unable to do that. Is there any solution for it ? Please help.
Short: Not possible
Long:
The most precious resource on a mobile device is the battery power. It has to be sparsely used.
Therefore no application in its sandbox is allowed to run infinite or get waked every minute.
Whatever the usecase for contacting the server is, the process has to be redesigned to fit into a mobile scenario. The options are push, opportunistic background fetch or using background sessions for talking to the server. However none of this options will guarantee a wake up every minute.
Related
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."
I have been investigating iOS background fetch for our enterprise applications. According to articles like this, there are limitations like having 30 seconds to download before the app is terminated and the may be (unconfirmed) a penalty where after 3 timeouts, an app gets banned from background sync. Also if the user kills the app, fetches stop happening -noted here.
The goal is to be able to retrieve data from our servers periodically when app is suspended/not running but sometimes the transfers can take minutes due to long running SQL. I don't want to implement sending periodic notifications to all users.
Before I go down the path of developing for the iOS background sync, I needed to do some due diligence and research alternatives to iOS's background sync and didn't find anything.
Has anyone seen or developed an alternative to iOS's background sync or dealt with this issue for their enterprise apps?
As an enterprise app there's nothing extra you can do except that you can use whatever background modes you want (audio, location, voip etc,) without needing to have a legitimate reason to do so.
Where this might assist is:
you could make use of a significant location change (as opposed to a regular location change) notification to run your app in the background. The problem with this is it of course depends on the user of your app to move around. However, assuming everybody in your workforce commutes to/from work with their iPhone then you would have two opportunities each day for the app to run in the background. A app run due to a location change can be made to execute in the background for more than 30 seconds.
voip pushes: Unlike a regular push notification, a voip push will launch the app even if the user has force terminated it. To make use of this functionality is only a tiny bit more effort than using regular push, you don't have to do anything regarding making or receiving an actual voip call, you just need the voip capability and voip certificates instead of normal push certificates.
The comment in that link is not correct regarding force quitting and background fetch - a user force quitting an app does not make it ineligible to run for a background fetch, I have force quit my own app that uses background fetch but it will still be started by the OS, however what will happen is that the frequency when the app is run will decrease lots, and if the user never runs the app again then the OS will stop launching it.
A user force quitting an app will prevent other things from happening, such as it running in the background in response to a silent push notification for example (unless its a voip push).
Also the 30 seconds in not related to download times, NSURLConnection would stop after 30 seconds, NSURLSession is designed to continue to download on your app's behalf. But if you are downloading and then applying lengthy SQL processing it would be an issue. But minutes of processing time seems excessive, are you sure its all optimized?
The goal is to be able to retrieve data from our servers periodically when app is suspended/not running
The only reliable way to achieve such a behaviour is implementing a User-facing Remote (Push) Notifications framework on backend & apps.
You can append 4kB (or 5 for VOIP) worth of data in the push JSON payload, eliminating need for a network fetch request if implemented in a handshake mechanism.
You can evaluate usage on Silent Remote Notifications to augment content updation & fetch small amounts of content opportunistically, though it has the same as Background App Refresh.
You can definitely improve the API that can take minutes due to long running SQL
And remember you need to have the app updated only when the user actually fires it up. Evaluate implementing a catchy & smooth fetching content screen that transitions into the actual screens once all data is fetched.
First of all it's important to note that I'm developing an Enterprise App, so there is no need for App Store guidelines \ approvals considerations.
My goal is the following:
1) An iPhone app which the user should open only one time only. During this one time he will go through some sign up process.
2) Once step (1) has finished (either by app suspension or app close), the app should "wake up" every hour (more or less) and send the server some data regarding the user from the background (all is done with the user agreement of course).
Optional Solutions I tried:
I read very thoroughly Apple guidelines for running in background in https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
I decided to go with 2 UIBackgroundModes:
location
fetch
1) For location I use:
startMonitoringSignificantLocationChanges();
manager.requestAlwaysAuthorization()
In order to make sure my app will run after "app close" or even "device reboot" I had to use both options. See Apple guidelines:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW1
If you leave the significant-change location service running and your
iOS app is subsequently suspended or terminated, the service
automatically wakes up your app when new location data arrives.
2) For background fetch I use
performFetchWithCompletionHandler()
and
UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum);
For some reason the app doesn't run in background after 24 hours. Meaning the app never "wakes up" again even though according to Apple guidelines whenever significant location update occurs - it suppose to wake up.
What can I do in order to guarantee as much as possible that my app will run regularly in the background?
In your project properties you have to allow background mode for your application to Update location and for background fetch.
Fetch in background is not so easy as it seems.
iOS will define by itself how often it will fetch data in background modeeven you set option for each 15 minutes :(
As my practice shows time interval for fetching new data is less if user open application from time to time so iOS makes some calculations about normal app use. As a result app calls background fetch data according to app ussage.
But you can make one trick:
you can call fetch procedure from you location procedure. For data exchange it was usefull in my projects :)
The solution worked with Silent PN.
My goal as noted in the bounty was: ".. to have an iOS app that runs regularly in the background for 30+ days when not opened at all. Should also run after the app closes."
I found that when sending PN with "content-available" : 1 did the trick for me.
I set up a server which sends every 15 min a "silent PN" to all registered devices. I was able to confirm from the same server that those clients receive the PN and act on it.
Thanks #andlin for the advice.
I am looking for something that is equivalent to Services in Android. As far as I have searched I haven't found anything useful. I found Background Fetch but according to my understanding it cannot be used long processes.
Here is what I want to use it for.
fetch a list of twitter user ids from our web server then auto-follow those usernames in background. As there are limits in Twitter API, so the process will be long possibly 3-4 hours. Is this possible on iOS?
There is no long-running background mode for continuous execution of apps in iOS.
This doesn't really sound like the right task for a mobile device. Running a 3-4 hour background job would be bad for battery life.
You can implement the function on a server somewhere and use push notification to send updates to the device.
An Android Service use case that is often cited is a background music service, which I have implemented as an exercise. It is not a given that a long running task actually will consume a lot of battery. Rather, it appears Apple is guaranteeing that such an event cannot happen through API design.
In my application I need to log user status every 15 minutes. Is it possible if the app is in background (not killed)??
Currently I enables the Background location update. But how to call in each and every 15 minutes
While other answers are correct about background fetch, there is also another background option called VoIP, which apps like Skype use. In this case OS will wake up your application more frequently (even every 10 minutes if I remember correctly) and you can keep pinging your server in background. The obvious down side is that your app must have Voice over IP functionality, otherwise it would get rejected on the App Store.
All you need to do is add call setKeepAliveTimeout:handler: method and have voip enabled in background capabilities.
Just adding this for the sake of completion.
You may want to look at the Background Fetch capabilities added in iOS7 and beyond:
http://www.appcoda.com/ios7-background-fetch-programming/
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html (Search for background fetch)
You won't be able to control the interval to exactly 15 minutes but you will find that this mechanism is the closest Apple will allow.
It is not possible to perform network calls at clearly specified intervals when your app is in background mode. You can tell your app to use background fetches
This article gives a great overview on the capabilities that you can do with this API. Basically it allows you to tell iOS that your app wants to perform networking calls in the background, however you can't exactly control when and how often iOS the network calls are going to be performed. iOS will schedule your network calls for you, and depending on how your app is used it will adopt the frequency with which it performs the requests. Documentation can be found here.