ASINetworkQueue Correct Usage and Storage - ios

I have an app that submits data using ASIFormDataRequest to a remote web site. I want to allow the user to store them for upload later if they are offline (eg: iPod touch or out of cell coverage, etc). Is ASINetworkQueue the appropriate tool to use? I imagine I would store the request in a queue belonging to the app delegate and, whenever a new submission was added or the app launched, reachability would be tested and, if good, would complete each request in the queue.
Is that logic correct? (I know it is bad practice to check reachability immediately on app launch, but I would tweak that to a good time.)
If so, my next question is, how do I get a ASINetworkQueue to persist between launches, both cold and from background? I imagine it would involve writing it to NSData and writing that to NSUserDefaults or even to file.
Thanks for any help!

If you are going to upload data asynchronously but handle offline usage, I would recommend writing the data to a local database or file and then having some sort of "uploaded at" timestamp for a status. When your app starts up you can query your local database for any objects that have not been uploaded. I don't know what your app is doing but you may find this method less error prone and better for giving proper feedback to your user through the UI.

Related

iOS background uploads - how to verify responses received if app crashes?

When performing background uploads in iOS, is there a mechanism in place that will re-deliver upload results from the system if the app crashes while handling said results? I was hoping to see some sort of confirmation system in place telling the OS that the app has finished processing all of the data it was sent, etc but I do not see something like this in the documentation.
What I am worried about is that my users will upload 100 items and once these are all uploaded in the background my app will launch (in background mode), allowing me to handle the responses. If the app crashes while processing the response data, the other unprocessed response data is forever lost now.
This is of course an issue when doing uploads in the app as well - if you upload something and crash while handling the response you'd lose that upload (and any other uploads in flight at the time), but you risk losing way too much data in the background IMO.
For an upload task in a background session, as soon as you reconnect to the existing session by “creating” a session with the same session name, your app should get delegate calls just as though it were still running from before.
Obviously you will have to persist any app-specific data structures that tie the task’s identifier and session name to the specific content you’re uploading, since anything previously in memory is obviously gone at that point.

How can I post data to the server when my app is be Terminated?

How can I post data to the server when my app is be Terminated ? I use the NSURLSession class. I try to post data when applicationWillTerminate is running but it doesn't work.
applicationWillTerminate is not meant for such tasks and you may not have enough time to perform the actions related to server.
Refer this apple doc
This method lets your app know that it is about to be terminated and
purged from memory entirely. You should use this method to perform any
final clean-up tasks for your app, such as freeing shared resources,
saving user data, and invalidating timers. Your implementation of this
method has approximately five seconds to perform any tasks and return.
If the method does not return before time expires, the system may kill
the process altogether.
Use applicationDidEnterBackground method for this purpose.
Building on the other legitimate answers, you could try sending the data when the application enters the background, but in some cases the app may be terminated before the request completes. An alternative could be to store the data (depending on what your data consists of) locally (i.e. NSUserDefaults) and then make the request when the app is opened at some point in the future. An obvious caveat is that if the user is accessing the data from multiple clients like a website or another device, you will need to reconcile this when you make your request.

How do bring my App "up to date" - background fetch?

I am looking for a good way how to make my app "upToDate". These are my requirements:
I have an RESTful Webservice, with tasks for different users. Every user has an iOS App, which should get automatically updated when the Server/Service assigned a task to that User.
So first ill created a manuall "Sync" Button, which checks for new Tasks. Fetches the data with Alamofire, and updated the UI.
But, my goal is automatically sync if there are new tasks.
So, ill guess there are 2 different ways to solve that:
1. Make a Background Fetch (with a NStimer?) every xx Minutes and check if there are new tasks.
After checking that tutorial here:
http://www.raywenderlich.com/92428/background-modes-ios-swift-tutorial i am not sure if a background fetch is a good way to solve that. In that case the App uses an scheduler, to check once for new updates, and not every xx minutes.
So in my case i would create an NStimer in the AppDelegate (maybe in applicationDidEnterBackground) and check every xx minutes for new data (but when there are 3 days not any new task, that would be unnecessary battery consumption, or?)
2. Using Push Notifications.
My other idea is to use Push Notifications, so when there is a new task, ill send a Push Notification an manually start the sync. In my opinion that would use less battery, because he will only start the sync when there is a new task available.
Generaly Questions about using Background Services
So ok, if the user finished the task, some data should be automatically uploaded to the server. Normally not a problem, with the manual sync ill check if there is something to upload. But, what if, when there is no internet connection (ill check if before uploading) - and the user do not press on "manual sync".
So i would prefer to check in my "Background Service" if ill got an Internet connection, and if yes - start uploading some data.
Ill know this is not a specific question, but ill think there are lots of users who have the same requirements and it would be great if someone can help me out whats the best way to solve that in the best and practical way.
Thanks in advance!
Background updates sound wonderful until you realise that Apple throttles them heavily: you can ask to be updated as frequently as possible, but iOS decides what that value actually means based on how often users open your app and when they do so. Apple considers background updates the kind of thing that should happen just before a user opens your app so the latest content is right there, rather than something that runs proactively in the background.
Your push notification solution is a better one, particularly if you use CloudKit to subscribe to record change events using CKSubscription and CKNotificationInfo. If you do this you'll automatically get push messages in your app, so you can get what you want with very little work. You can read my tutorial for more information on subscribing to CloudKit to get push messages.

how to handle a long wait time for data, when ios 8+ app has been backgrounded by user

I've spent a lot of time looking at the options but am still not 100% clear, so wanted to reach out for some guidance.
Scenario is this:
User submits an HTTPS request to our backend server for some data via an iOS app
Depending on the data, the first (only) request can take a REALLY long time. like, say, 10+ minutes (shocking i know)
When that payload finally does become available and is returned via the HTTPS request, we then want to use it to update the UI in background.
The assumption here is that the user has moved on to another app whilst waiting for the data to arrive (and lets also assume they haven't killed the app).
Is it possible to handle this via iOS 8+ API's without the app being force/killed by Apple when in the background ?
Could we use background task for example?
var backgroundTask: UIBackgroundTaskIdentifier
xxx.beginBackgroundTaskWithName...
etc
Before testing some code blocks we just wanted to see if someone has (a) already done this and/or (b) whether we're heading in the right direction
Thanks for your help.
You should re-think on your web service which may take almost 10 min to process. If you are not able to optimize server task processing time then below one of the idea may be help you.
You can divided your one request into multiple request to reduce processing time and get response in faster way.
Your server should sent notification to app when its done with its task. So app will came to know task is done.
I am not sure why you try to update UI when apps in background mode , you may try to update UI when users come to foreground mode from background mode.
Please check this link which show as example of long running task. Where its use a blank audio play to keep alive app background task.
You can used "Background fetch" functionality.
For learning purpose you can refer this link

iOS handling initial data sync which may take several minutes

I have an iOS app that needs to sync a lot of data from the cloud to device when first installed, maybe even 2GB worth if the user wants access to everything offline. Without saying "change your design", how can I ensure this initial sync completes without too much interaction from the user?
Currently it will complete as long as they keep my app in the foreground and don't let the device go to sleep. I'd like to allow them to use other apps or let the screen turn off during this process, since it's a pretty boring thing to watch.
I've seen application:performFetchWithCompletionHandler: and
beginBackgroundTaskWithName:expirationHandler, but they only allow for a short amount of time (around 30 seconds) to complete a task. Is there something better, or do I need to complicate my design by stopping my sync every ~25 seconds, and then resume next time I'm given more time by the OS?
My app is like Microsoft Outlook, it has emails (in some case millions), contacts, calendar, and several other areas. I have different sync options to limit the amount of data, but some users want access to everything offline (yes, even emails and attachments that are 10 years old). I think they are silly, but can't argue with the end-users.
I know this is a really old question, but I suggest you use NSURLSession to download data in the background even without your app running.
You simply create an NSURLSession that uses a Background NSURLSessionConfiguration (use NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier:) and create an NSURLSessionDownloadTask for each request you need to download.
NSURLSession will download the data even when your app is not running at all, and it will save the data as files in your app's sandbox. Implement the NSURLSession delegate methods to receive notification of the download completion, read the downloaded files and save them how you see fit.
You should check out Apple's guide on Using NSURLSession.

Resources