Downloading large files - ios

I am currently developing a application which has to be able to show offline videos which need to be downloaded first.
The problem was that these videos can be bigger that the memory that I can allocate to my application. So parts that are downloaded have to be saved immediately instead of saved in a NSData object. I'm hearing conflicting stories on whether or not RESTKit should work, and ASIHTTPRequest seems to be deprecated.
I will follow the suggestion from this thread as it seems to be the best option.
NSURLConnection download large file (>40MB)

Consider using NSURLConnection to download the video file and write the data directly to a file (NSFileHandle).
One advantage of using this method is that the NSURLConnection didReceiveData delegate method is continuously called as data is received, so you can update a progress bar.

Check out AFNetworking for network managing. I am not sure if they have video downloading, but the framework works great for images and other types of downloads that I have down before.

Without explaining all the hasle with dealing with HTTP responses by chunks and streams I would recommend using AFDownloadRequestOperation. It supports resuming downloads and has callbacks for showing download progress. I love it and use it in most of my projects.
P.S. It uses AFNetworking, which is a great framework for making all kinds of HTTP requests.

Related

How to handle large files with NSData?

I have a very large video and I need to chunk this video to upload it to Dropbox.
I tried to use NSData, but because this file is too large, my application always crashes, so I don't know what I can do now.
For smaller videos, I used this:
NSData(contentsOfURL: self.newAsset.URL)!.subdataWithRange(NSMakeRange(0, 10000000))
and I didn't have any problem with that, but when the video is too large I have an error:
Cannot allocate memory
So, what can I do to chunk the data of large videos?
For best practice go with NSURLSession if you want to implement custom otherwise lots for third party library are there like RESTKit or AFNetworking. For NSURLSession the session NSURLSession supports three types of tasks: data tasks, download tasks, and upload tasks. All it support the background uploads/downloads as well. source(apple developer)
Data tasks send and receive data using NSData objects. Data tasks are intended for short, often interactive requests from your app to a server. Data tasks can return data to your app one piece at a time after each piece of data is received, or all at once through a completion handler.
Download tasks retrieve data in the form of a file, and support background downloads while the app is not running.
Upload tasks send data in the form of a file, and support background uploads while the app is not running.
Image Source raywenderlich.com
You should use video file url to upload large data using NSURLSession
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;

iOS How do I retrieve and store data from URL?

I am looking for best practices.
In my app, I send a request to my server for the URLs of the images I need to download and some meta data. I then need to store these images on disk. Once they are saved I have to update view. Storing on disk is also necessary for offline view so maybe I'll even have to store the file path to CoreData.
I think I can just use NSURLConnection to retrieve the image urls, then the images and then write them to disk. My concern is what should I do when the app is waiting for all this to occur? How do I know when to update, for example, a table? What if the user moves away and the view unloads? Just looking for advice.
Should I create a separate NSObject class to handle all this?
PS: How would I check for an existing internet connection before I do any of this anyway?
if you are already using CoreData, consider storing the images directly in the CoreData-DB. that depends on the size of the image, of course.
For synchronization of the db, this might be helpful: http://www.raywenderlich.com/15916/how-to-synchronize-core-data-with-a-web-service-part-1. They also use a separate class to handle this.
To check the internet connection, apple has a wonderful sample app:
https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html
EDIT: Oh, and NSURLConnection loads data asynchronously by default, so your app will stay responsive during data loading operations, you can handle the update-vioew-operations in the respective callback methods.
See the docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/
pay special attention to the difference between
sendAsynchronousRequest:queue:completionHandler: and
sendSynchronousRequest:returningResponse:error:

limit download transfer speed of nsurlconnection to prioritize others

I am currently using NSURLConnection to download and upload data in my app.
Files are loaded directly to a cache.
When a user scrolls over a collection view I start downloading the relevant images (similar to pinterest homescreen).
I already have a system in place that downloads 'last requested' first, but finished the downloads that are currently running first of course.
Since I'm going to integrate download of larger files, like video or larger images than thumbnails for detail views, I was wondering whether I could limit the download speed of a connection to prioritise later requested 'large' files.
I've so far looked into ASIHTTPRequest, but they only allow throttling the entire connection.
I would like to avoid implementing everything on my own using CFStreams. Ant ideas?
AFNetworking does not offer this feature, since it builds on NSURLConnection and most other frameworks I've looked at don't offer this feature.

Download big file

I have a problem regarding the best approach to make an App that has to download and show pdf's, It is fed by a JSON that has links to 147 pdf files, sized between 1 and 2 MB.
Questions:
What is the best approach to download all the files to an iPad?
Shall I use AFNetworking 2.0?
Is NSFileManager the way to save all the files?
Problems I may encounter:
With an asynchronous download, if lost connection or no more space on the iPad, what are the counter mesures?
Are there tutorials or examples that deal with this situation?
Sorry for all the questions but I'm new to this.
Best Regards.
What is the best approach to download all the files to an iPad?
This is really broad as #rmaddy suggested. Specific questions are more easily answered. There are lots of ways you could download a file via an HTTP request to your device each with pros/cons depending on your situation.
Shall I use AFNetworking 2.0?
Sure. You'll get no argument from me. This is a widely used and solid API to interface with HTTP-based resources.
Is NSFileManager the way to save all the files?
Yes. NSFileManager is the class you use to read/write files from/to your app's sandbox.
With an asynchronous download, if lost connection or no more space on the iPad, what are the counter measures?
I'm not 100% certain so I can't speak to exactly what happens in this case. AFNetworking may provide some help by writing to a temporary file during a download, etc....
Are there tutorials or examples that deal with this situation?
I have a sample project on Github that shows a table of files that you can download. You can watch the progress of your downloads, pause each request, resume and cancel as well. When you're done you can view the file you downloaded. It uses AFNetworking and might be useful to you:
https://github.com/chefnobody/StreamingDownloadTest
When downloading large files, the main counsel would be to avoid trying to load these into memory as you download them. Instead, make sure you stream them directly to persistent storage. In terms of handling space-specific errors, just make sure you check NSError objects that are returned to you in completion handlers or the appropriate delegate methods.
If using AFNetworking, you can specify the outputStream of the AFURLConnectionOperation to reference a NSOutputStream that you create, referencing some path in your persistent storage.
See Memory pressure issue while downloading multiple files using AFNetworking for example.
Alternatively, you can use NSURLSession (whether via AFNetworking or you do it yourself) and instantiate a NSURLSessionDownloadTask, which does the same sort of thing.
Google "NSURLSessionDownloadTask example" and you'll find tons of references. The block-based rendition of downloadTaskWithURL is incredibly simple. To do background downloads is a little more complicated and requires delegate-based implementation (see Downloading Files and Handling iOS Background Activity sections of URL Loading System Programming Guide: Using NSURLSession or watch the WWDC 2013 video, What’s New in Foundation Networking.)
Either way, you avoid some of the memory consumption challenges associated with downloading large files.

iOS - Progressive Download Indicator While Downloading Files

So this question has been asked a bunch of times, but all the answers are to us ASIHTTP library which is no longer supported.
So I was hoping someone could steer me in the right direction.
I download files (images / videos) in my app using NSData and was wondering how to go about displaying a progress bar/indicator that actually tracks the progress of the download (i.e. 20%, 30% etc etc)
Are there any built-in classes that allow file downloads to be tracked with progress updates?
If you have an NSURLConnection delegate then:
the NSURLResponse you receive to connection:didReceiveResponse: will be of type NSHTTPURLResponse. If you access [[response allHeaderFields] valueForKey:#"Content-Length"] you'll get a string with the length of the data you're expecting to receive;
subsequently through the accumulation of data via connection:didReceiveData: you'll know how much data has been returned.
Since you know how many bytes you've received and how many you're expecting you'll be able to work out the percentage pretty easily.
There are several replacement options for ASIHTTP. The leading one is AFNetworking. It includes support for a progress bar for downloads.
Check out ASIHTTPRequest . It is awesome an will do this any many more wonderous things.
http://allseeing-i.com/ASIHTTPRequest/

Resources