First of all i need to describe what i am going to do: when user launch my application the app start collecting statistics about the user activities and behavior, once the the user close the app (app enter background) the application upload all statistics to server.
the problem if the user presses home button twice and removes application from multitasking screen. then the application may not succeed to send statistics to server. because it will be terminated.
my solutions:
enable Background fetch , in background modes. but I don't think that will help because according to apple: the system does not relaunch apps after they are force quit by the user
using Executing Finite-Length Tasks , i tried it , it won't send the data if user remove the app from multitasking screen.
using NSURLSession to Downloading Content in the Background, but according to apple If the user terminates your app, the system cancels any pending tasks.
so all above solutions will not work if user terminate the application, any solution ?
I noticed that if i terminate the appstore app (remove it from multitasking screen ) while there is an application being downloaded , the application will continue downloading normally. is this just for appstore app ?
If the user terminates an app, the app terminates. There is nothing you can do about this. iOS devices are meant to be controllable by the user.
Depending on what you are trying to achieve, you might add all the statistics to a queue on disk, and empty that queue only after the app has successfully uploaded the data to the server.
If the user doesn't force-quit, this will work at once, in just the way you want.
If the user does force-quit, the data will not be uploaded and the queue will still be present on disk. When the app is started, it can check the queue and upload it immediately.
You ought to be doing something like this in any case, to deal with cases like the user going underground for an hour, or taking a long-distance flight.
I suspect that the App Store app does not install apps, but tells a system process to install them.
Related
In iOS application, I want to upload data on server when internet available. Now problem is, if user has force quit the application then how I can re-invoke the application or can do task in background when internet is available? Is there any possible way in iOS?
Apple is not allowing to run code after the user force quits the app. There are just some special rules to reactivate the app like blutooth implementation. For normal server task, you just can work while the user not force quits the app.
Edit
Not even with special rules you can reactivate your app. Bluetooth reactivation and co only works if the app gets killed by memory issues or something similiar. If the user force quits the app, the app will not run until next app start.
The iOS will give you 3mins to run a background task. Take a look at https://medium.com/#abhimuralidharan/finite-length-tasks-in-background-ios-swift-60f2db4fa01b
If the user performs an action in an iOS app while offline (e.g. airplane mode), can the app complete the action (by sending data to its server) once the user is online, even if the user completely closed the app before going online?
I’m asking because Twitter and Facebook do not have this functionality. (If I post something while offline, then close the app and go online, the post will not be submitted until I start the app again.)
No. If the user kills your app, it's gone. It can no longer execute any of your applications code. The best you can do is research background tasks and you then have ~10 minutes to execute your actions before it's automatically terminated (if the user doesn't do it before the OS).
You can store the actions in a Database (Core Data, Realm) or even in NSUserDefaults. When the app comes online, you can periodically attempt to parse those actions and send the network requests with exponential back-off. I imagine this is the process Facebook and Twitter use.
I disagree with #JoeyClover's answer.
If what you want to do is an HTTP POST, you should be able to set up an NSURLSession for background processing. The system should then take over submitting your post even if the app is not running. See Xcode's docs on NSURLSession for more information. (You can do the same thing for downloads with an HTTP GET, but that's not what you're asking about.)
The exception to this is if the user actually terminates your app by swiping up on it in the task list. In that case the system kills your background upload/download tasks. The info on that is in the section on NSURLSessionConfiguration. To quote Apple's docs:
Use this method to initialize a configuration object suitable for
transferring data files while the app runs in the background. A
session configured with this object hands control of the transfers
over to the system, which handles the transfers in a separate process.
In iOS, this configuration makes it possible for transfers to continue
even when the app itself is suspended or terminated.
If an iOS app is terminated by the system and relaunched, the app can
use the same identifier to create a new configuration object and
session and retrieve the status of transfers that were in progress at
the time of termination. This behavior applies only for normal
termination of the app by the system. If the user terminates the app
from the multitasking screen, the system cancels all of the session’s
background transfers. In addition, the system does not automatically
relaunch apps that were force quit by the user. The user must
explicitly relaunch the app before transfers can begin again.
(I bolded the key bit.)
We have a customer who wants us to have our iOS app check for new data posted every night and download it if it is available. As far as I can tell this is only possible if the app is already open or if they have someone physically accept a notification or initiate the process themselves.
Is this correct? I can't imagine Apple wanting to allow launching of an app and downloading data with no user interaction at all.
Yes, generally you can only download data at exactly specified times if the app is actually running in the foreground, that is correct. It wouldn't matter if the app was open already or the user opened it from a notification, the point is that user interaction is required. So, the client can't have exactly what they want.
Look at background downloading (fetch) from iOS7+ where you can register the app to perform background downloading in advance of usage. iOS is fully in control of this and it may choose to run the app and it may not. iOS will monitor when your app is usually used by a particular user and, if appropriate, it will allow the app to run in the background to do some downloading before the user is expected to use the app.
In particular you're looking at setMinimumBackgroundFetchInterval: and setting the UIBackgroundModes key with to fetch in the Info.plist.
As an aside, here's an idea based on your expanded information:
Use idleTimerDisabled to prevent the app from sleeping during main usage and keep a track of the time
After the main usage period of the app is over, start your downloads
After the downloads are done allow the screen to sleep
On the next day, if a user opens the app, repeat
It isn't perfect, but it's an approximation
I'm little bit confused with background fetch. I read in Apple Developer documentation that fetch happens when OS decides that it should, user can't control background fetch, while on Apple Developer forum post by Apple employee says that if user kills app (double tap on home and button swipe up) background fetch wont happen, in that case user can control background fetch. So can someone please clarify to me if user kills the app with task manager will background fetch still continue in the background or it's killed at the same time as app.
Apple documentation:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW1
From the doc you link:
When a good opportunity arises, the system wakes or launches your app into the background and calls the app delegate’s application:performFetchWithCompletionHandler: method.
So, it seems that the system is able to launch in the background an app that is not running so it executes a background fetch. On the other hand, though, later in the document you can read:
In most cases, the system does not relaunch apps after they are force quit by the user. One exception is location apps, which in iOS 8 and later are relaunched after being force quit by the user. In other cases, though, the user must launch the app explicitly or reboot the device before the app can be launched automatically into the background by the system.
So, Apple's engineer is right: force quitting an app puts it into a sort of special case where background fetches are not allowed anymore.
If the user feels the need to allow background operations, he wouldn't kill the app. But when he kills it, it is only appropriate to disallow background fetch. User can only control if background fetch should happen or not by allowing it to stay in background/by killing the app. But once the app is in background, user cannot control "when" the background fetch happens. The OS determines it based on how free it is.
I think this quote (from the linked document) is the most important for the scenario you're describing:
Once configured, your NSURLSession object seamlessly hands off upload and download tasks to the system at appropriate times. If tasks finish while your app is still running (either in the foreground or the background), the session object notifies its delegate in the usual way. If tasks have not yet finished and the system terminates your app, the system automatically continues managing the tasks in the background. If the user terminates your app, the system cancels any pending tasks.
I have a problem guys.I have requirement where my app should detect if the device is idle without any application running or without any user interaction from my application or at-least to know if the device is in home screen.What i am asking may be stupid but this is my requirement.Is there a way to achieve this. Help me
OK, enterprise apps are different. I think this can be done.
Have your app record whenever it's launched by the user (the app delegate receives events when the app enters/exits the foreground).
Then setup a "local push notification" several times a day that launches your app in the background and checks the log to see if the last entry is a "did leave".
If it is, then load up the URL to your itms services URL to install the new version of the app.