Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS在下载前获取文件大小_Ios_Download_Size_Nsurlsession_Nsurlsessiondownloadtask - Fatal编程技术网

iOS在下载前获取文件大小

iOS在下载前获取文件大小,ios,download,size,nsurlsession,nsurlsessiondownloadtask,Ios,Download,Size,Nsurlsession,Nsurlsessiondownloadtask,我找不到适合我的解决方案。但是我需要得到我正在下载的视频的文件大小,这样我才能确保用户的手机上有足够的空间来下载 我的想法是检查视频的大小,然后如果用户有空间,我会下载它。有什么建议吗 NSURL *url = [NSURL URLWithString:stringURL]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLSession *session = [NSURLSession sharedSession]

我找不到适合我的解决方案。但是我需要得到我正在下载的视频的文件大小,这样我才能确保用户的手机上有足够的空间来下载

我的想法是检查视频的大小,然后如果用户有空间,我会下载它。有什么建议吗

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) {...}];

使用此函数可获取URL的远程大小。请注意,此函数是同步的,将阻止线程,因此从不同于主线程的线程调用它:

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
    }
}
let size = url.remoteSize
然后在与主线程不同的线程上,在需要的任何位置调用remoteSize变量:

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
    }
}
let size = url.remoteSize

使用此函数可获取URL的远程大小。请注意,此函数是同步的,将阻止线程,因此从不同于主线程的线程调用它:

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
    }
}
let size = url.remoteSize
然后在与主线程不同的线程上,在需要的任何位置调用remoteSize变量:

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
    }
}
let size = url.remoteSize
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
    }
}
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
    }
}
Swift 3: 因为您正在调用dataTask,所以不能使用块外的值,所以请这样使用它

 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()
Swift 3: 因为您正在调用dataTask,所以不能使用块外的值,所以请这样使用它

 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()

以下是其他答案的一个变体,它使用函数(在Swift 4中)在检索大小时调用闭包:

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()
}
以下是如何使用此功能:

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).")
    }
})

以下是其他答案的一个变体,它使用函数(在Swift 4中)在检索大小时调用闭包:

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()
}
以下是如何使用此功能:

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).")
    }
})

看@RayKing增加超时,现在是5秒,你可以像这样增加你所需要的吗?DispatchQueue.main.asyncAfter(截止日期:.now()+15){print(NSURL(fileURLWithPath:track.url!).remoteSize)}此时仍然会得到-1@RayKing在调度组等待中更改5。我注意到在swift 3版本中,作者省略了这行代码unusable@RayKing增加超时时间,现在是5秒,你可以像这样增加你所需要的时间吗?DispatchQueue.main.asyncAfter(截止日期:.now()+15){print(NSURL(fileURLWithPath:track.url!).remoteSize)}此时仍然会得到-1@RayKing在调度组等待中更改5。我注意到在swift 3版本中,作者省略了这一行,这使得代码无法使用