Download 1 file at a time using NSUrlSession in iOS - objective-c

I am downloading multiple files using NSUrlSession in my iOS app. I want to download only one file at a time. But it is downloading multiple files at 1 time. Please suggest a way to download files one at a time.
I tried this property :
sessionConfiguration.HTTPMaximumConnectionsPerHost = 1
But it also download multiple files if they are hosted on different servers.Please suggest a way to do this

You have 2 options:
sync: Daisy chain your requests from the completionHandler, triggering a new NSURLSession resume upon the completion or failure of the previous one.
async: Each operation must complete before the next one can start, and waits until completion signals using a semaphore. The thread performing the scheduling of each NSURLSession resume will wait for that operation to complete. See https://stackoverflow.com/a/21205992/218152
sync/async clarification
Neither of these options are suggesting to run your operations on the main thread: sync/async is merely referring to the background thread responsible for the scheduling.

Related

NSURLSession background session can run data tasks?

The doc mentions gives one line
In Background sessions, Only upload and download tasks are supported (no data tasks)
but this doc,
seems to indicate that background sessions can execute data tasks?
The behavior of a session is determined by the configuration object used to create it. Because there are three types of configuration objects, there are similarly three types of sessions: default sessions that behave much like NSURLConnection, ephemeral sessions that do not cache anything to disk, and download sessions that store the results in a file and continue transferring data even when your app is suspended, exits, or crashes.
Within those sessions, you can schedule three types of tasks: data tasks for retrieving data to memory, download tasks for downloading a file to disk, and upload tasks for uploading a file from disk and receiving the response as data in memory.
what is correct? will I be able to make a GET http request on an NSURL and then JSONSerialize the NSDATA received in the "Background"
You can only run upload and download tasks in the background. Here's a quote taken directly from the ULR Loading System.
Background Transfer Considerations
The NSURLSession class supports background transfers while your app is suspended. Background transfers are provided only by sessions created using a background session configuration object (as returned by a call to backgroundSessionConfiguration:).
With background sessions, because the actual transfer is performed by a separate process and because restarting your app’s process is relatively expensive, a few features are unavailable, resulting in the following limitations:
The session must provide a delegate for event delivery. (For uploads and downloads, the delegates behave the same as for in-process transfers.)
Only HTTP and HTTPS protocols are supported (no custom protocols).
Only upload and download tasks are supported (no data tasks).
Redirects are always followed.
If the background transfer is initiated while the app is in the background, the configuration object’s discretionary property is treated as being true.
What you want to do instead is run your GET request as a download request and save the JSON data to a file. Once the download is completed, read the contents of the file into memory, and parse the NSData just like you would if it came from a data request.

RestKit network limits blocks other calls when parallel requests are running

we are facing a problem.
we have background requests that are downloading files constantly (up to 5MB each file). meanwhile, we have a UI that most navigations require REST calls.
we limited the number of background downloads so it won't suffocate the operationQueue that RESTkit uses.
when several files are downloaded in background, we see the network usage with 1->2 MB (which is understandable).
The problem is: the user navigates through the app, and each navigation calls a quick REST call that should return very little data. but because of the background downloads, the UI call is taking forever (~10 seconds).
Priority did not help, i saw that the UI call i make instantly is handled by the operation queue (because we limited the downloads limit and the NSOperationQueue had more space to fulfill other requests.
when we limited the concurrent REST download calls to 5 - the REST calls from the UI took 10 seconds.
when we limited the concurrent REST download calls to 2 - everything worked fine.
the issue here is that because we let only 2 downloads occur in the background - the whole background operation of downloading files will take forever.
the best scenario would be that every UI call would be considered as most important network-wise and even pause the background operations and let only the UI call to be handled - then resume the background operation - but i'm not sure it's possible.
any other idea to address this issue?
You could use 2 RKObjectManagers so that you have 2 separate queues, then use one for 'UI' and the other for 'background'. On top of that you can set the concurrent limits for each queue differently and you could suspend the background queue. Note that suspending the queue doesn't mean already running operations are paused, it just stops new operations from being started.
By doing this you can gain some control, but better options really are to limit the data flow, particularly when running on a mobile data network, and to inform the user what is happening so they can accept the situation or pause it till later.

NSURLSession remaning background time in finished download delegate

I'm using the NSURLSession background download service.
If my app is suspended and in background and a NSURLSessionDownloadTask has finisehd the NSURLSessionDownloadDelegate method
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
gets called as documented.
I observed that every time the delegate method is called the [UIApplication sharedApplication].backgroundTimeRemaining) decreases from 30 seconds at the start to 0 after some downloads. If it reaches 0 the app crashes with "has active assertions beyond permitted time:".
This means the total time I have to handle completed background downloads (unzip, move) is 30 seconds in total. This may work for a couple of files but not if the download consists of a lot or big zip files.
This time interval is not mentioned in any Apple documentation. Is this a limitation of the NSURLSEssion framework or did I implement it wrong?
thanks Christian
You can use -[UIApplication beginBackgroundTaskWithExpirationHandler:] and -[UIApplication endBackgroundTask:] to let your app run long running background tasks. This will likely give your app much more time in the background before it is terminated.
Another possibility to consider is chaining your download requests so that when one completes and your URLSession delegate is called you process the file and issue the next download request. That way, you never have more than one file to process at a time (presuming it doesn't take too long to process a single file).

How many downloads at a time can NKAssetDownload make?

Is it possible to make multiple downloads at a time?
When you send downloadWithDelegate message to NKAssetDownload the Newsstand framework just add it into its queue to download. After that there is no control in developer's hand as to when download starts. As far as I can tell from my experience, it do not start 2 download simultaneously. When one completes it start another one from the queue. I don't know why it is implemented this way but no parallel download.

How to run two tasks independently

I am building one application on Mac OS X (10.6). In this application, I have one screen where user will provide input and that will be saved as a plist in local folder. This plist file needs to be trasferred to server using HTTP POST service. There should be check for server connectivity and if connections fails the files will be saved in local folder. With certain time duration, again the server connection will be checked and if found, then send all the files store in local folder one by one.
Basically, The GUI application will run continously to get input from user and in another thread there should be check for server connectivity and sending the files.
So my question is what might be the good approach to solve the problem and if any one can send some sample code, it would be great to me.
Thanks,
Barun
There are several approaches to threading in Objective-C! The easiest strategy is NSOperationQueue. Override NSOperation to handle your HTTP request, optionally set a completion block if you need to be notified when it's done, add an instance of it to an NSOperationQueue object and you're good to go. Set up an NSTimer to reschedule the upload if it fails the first time. You can use NSURLConnection to handle the web stuff. Note that NSURLConnection can make connections asynchronously or blocking. Since your NSOperation subclass runs in a separate thread already, you probably want to use the blocking method (if you don't you have to create a concurrent NSOperation subclass, which is a lot more work).
You can also use Grand Central Dispatch's API, detach a new thread to methods you specify, or use plain old c (I wouldn't recommend the last two but it's good to mention them). As a bonus, NSOperationQueue and Grand Central Dispatch both know "what's right" when you have multiple operations running at once, and will scale the number of threads to fit the number of core's in the user's computer to obtain the best performance.
Check the docs for NSOperationQueue, NSOperation, and NSURLConnection. The guides and example projects will have all the source code you need to get you started in the right direction.