I'm using Alamofire to download large files in my ios project.
When i cancel a download request (that is currently downloading a large file to disk) - this request produces resumeData with the data downloaded so far - but I would like a responseURL with the URL of the file with the partially downloaded data. I plan to use the responseURL serializer at the end to never load the entire data in memory - but if I want to suspend and resume downloads - then this is forcing me to load the data in memory.
there's a fileURL in the download request - but the documentation states that this is populated after the download has finished.
any pointers/suggestions would be appreciated?
As explained on GitHub, resumeData only includes the data necessary to resume a download, not the actual download data itself, so it's perfectly safe to keep it around in memory. You can parse the value to get the URL of the partially downloaded data, but it's not a formatted encoding, so it's not really appropriate for Alamofire to parse it directly.
Related
I am using downloadTask of URLSession to download a large file. The problem i am facing is how to provide pause and resume functionality. I have read that cancelling the downloadTask with resumeData gives back resumeData which can be used next time to resume the download. But for a really large file, this resumeData can be very large (i think. depending on file size and at what stage download is paused it can be very large). How do i persist this large resumeData so that i can use it next time to resume download.
Also there can be multiple downloads at the same time, which increases the same problem more.
The resume data blob does not contain the actual received data. If it did, you wouldn't be able to resume downloading a multi-gigabyte file on a 32-bit architecture.
What it contains is a bunch of metadata for the transfer:
A URL on disk where the temporary file is stored.
A time stamp indicating when the fetch began so it can ask the server if the file has changed since then.
The request URL.
The set of request headers.
Probably some UUIDs.
And it might just be the URL of a metadata file on disk that contains the things listed above. I'm not sure which.
Either way, you will not get a multi-gigabyte resumeData blob. That would be devastating. The whole point of a download task is that it downloads to disk, not to memory.
My app downloads and display GIFs from the Internet in UIImageViews. The GIFs don't need to be cached/saved at all. However, the app takes up lots of storage on the iPhone with Documents & Data being enormous.
I'd like to be able to clear the Documents and Data folder each time the user opens the app. Is this possible to do with Swift?
The extension you use uses the following code:
Data(contentsOf: url)
https://developer.apple.com/documentation/foundation/nsdata/1413892-init
This method will cache stuff in the system cache.
If you want to keep using that extension you should modify that code to use this one instead:
init(contentsOf:options:)
https://developer.apple.com/documentation/foundation/nsdata/1407864-init
And pass "uncached" as an option to avoid the cache.
https://developer.apple.com/documentation/foundation/nsdata.readingoptions/1412417-uncached
However I think that extension is poorly written, for instance, you should only use this method to load SHORT local files, for bigger files a stream is needed, for network requests you shouldn't be using it at all.
Important
Don't use this synchronous method to request network-based
URLs. For network-based URLs, this method can block the current thread
for tens of seconds on a slow network, resulting in a poor user
experience, and in iOS, may cause your app to be terminated. Instead,
for non-file URLs, consider using the
dataTask(with:completionHandler:) method of the NSURLSession class.
See URL Session Programming Guide for details.
Data(contentsOf: url, options: .uncached)
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;
I'm using NSURLConnection to interact with the server side and I have observed that when the server take time to respond the system allows about 40 mo.
I don't know if I'm the only one to have this problem.
thanks in advance.
Yes this is possible in case if your data for response is large in size. Generally what we do, we create instance of NSData and append all downloaded data to this variable.This works perfect when your data is comparatively small. If you have large data in response, the better way is to create file in Document directory and append all data to that file when connection receives data. Read this data after connection finishes loading.
This concept of saving data is applicable on android also.
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.