Reputation: 367
I couldn't find a solution that worked for me. But I need to get the file size of a video I am downloading so that I can make sure the user has enough space on his phone for it.
My thoughts are to check the size of the video, then if the user has space for it, I would download it. Any recommendations?
NSURL *url = [NSURL URLWithString:stringURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {...}];
Upvotes: 0
Views: 5996
Reputation: 926
Here's a variation of the other answers that uses a function (in Swift 4) to call a closure when the size is retrieved:
func getDownloadSize(url: URL, completion: @escaping (Int64, Error?) -> Void) {
let timeoutInterval = 5.0
var request = URLRequest(url: url,
cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: timeoutInterval)
request.httpMethod = "HEAD"
URLSession.shared.dataTask(with: request) { (data, response, error) in
let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
completion(contentLength, error)
}.resume()
}
Here's how this function could be used:
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png")!
getDownloadSize(url: url, completion: { (size, error) in
if error != nil {
print("An error occurred when retrieving the download size: \(error.localizedDescription)")
} else {
print("The download size is \(size).")
}
})
Upvotes: 10
Reputation: 2238
Swift 3: Since you are calling dataTask you can't use the value outside of the block so use it this way.
var contentLength: Int64 = NSURLSessionTransferSizeUnknown
let request = NSMutableURLRequest(url: url as URL, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30.0);
request.httpMethod = "HEAD";
request.timeoutInterval = 5;
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
//Here you should use the value
print("contentLength",contentLength)
group.leave()
}).resume()
Upvotes: 0
Reputation: 3942
SWIFT 3:
extension NSURL {
var remoteSize: Int64 {
var contentLength: Int64 = NSURLSessionTransferSizeUnknown
let request = NSMutableURLRequest(url: self as URL, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30.0);
request.httpMethod = "HEAD";
request.timeoutInterval = 5;
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
group.leave()
}).resume()
return contentLength
}
}
Upvotes: -1
Reputation: 1485
Use this function to get remote size of URL. Please note this function is synchronous and will block thread, so call it from a thread different from main thread:
extension NSURL {
var remoteSize: Int64 {
var contentLength: Int64 = NSURLSessionTransferSizeUnknown
let request = NSMutableURLRequest(URL: self, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30.0);
request.HTTPMethod = "HEAD";
request.timeoutInterval = 5;
let group = dispatch_group_create()
dispatch_group_enter(group)
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
dispatch_group_leave(group)
}).resume()
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, Int64(5 * NSEC_PER_SEC)))
return contentLength
}
}
then call remoteSize variable everywhere you need, on a thread different from main thread:
let size = url.remoteSize
Upvotes: -1