Swift - 下载前从服务器检查文件大小导致应用延迟
Swift - Checking file sizes from a server before downloading is causing a lag in the app
我有一个服务器,您可以在其中导入视频,上传后应该会直接下载到应用程序中。问题是应用程序将在视频文件完全上传到服务器之前开始下载它。
我设置了一个每 10 秒运行一次的计时器,用于检查文件夹中是否有新视频。如果有新视频,我会使用 URL 会话下载它。如果视频在启动应用程序之前已经上传到服务器,或者如果视频非常小并且在 10 秒计时器再次运行之前上传,这很好,但这不切实际。
我的想法是检查视频大小并在几秒钟后进行比较。如果视频大小相同,则下载它。下面是我用来获取大小并添加到数组中的代码,这样我就可以将它与以前的文件大小数组进行比较。
//videos data array is fetched from the server
for video in videos.components(separatedBy: "") {
if !video.hasPrefix("._"){
guard let videoUrl = video.encodeUrl() else {return}
if let url = URL(string:String(self.session.imports_dir + "/" + videoUrl)) {
//Gets the file size
let data = NSData(contentsOf: url)
let fileSize = Double(data!.length)
videoArrayFileSize.append(fileSize)
}
}
}
如果videoArrayFileSize 与之前的Filesize 数组不同,则先不要下载视频。问题是即使我使用
上面的代码也会导致应用程序严重滞后
DispatchQueue.global(qos: .background).async
是否有更好的方法来检查文件大小或其他方法来检查文件是否已完全上传到服务器?
我无法编辑服务器代码,所以如果可能的话,我喜欢一种从应用程序中进行编辑的方法。
更新
我尝试使用下面的代码通过 URLSession 获取尺寸,它适用于测试视频 Big Bunny 但不适用于我服务器上的视频。我猜 HEAD 内容长度在我的视频中留空,给出 0。
func getFileSize(_ url: URL, completion: @escaping (Int64, Error?) -> Void){
let timeoutInterval = 5.0
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeoutInterval)
request.httpMethod = "HEAD"
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request) { (data, response, error) in
let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
completion(contentLength, error)
group.leave()
}.resume()
}
解决方案是使用 URL 请求并使用 HTTP 方法 "HEAD"。使用 "expectedContentLength",您可以找出文件大小,与前面提到的方法相比,这不会造成延迟。
func getFileSize(_ url: URL, completion: @escaping (Int64, Error?) -> Void){
let timeoutInterval = 5.0
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeoutInterval)
request.httpMethod = "HEAD"
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request) { (data, response, error) in
let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
completion(contentLength, error)
group.leave()
}.resume()
}
如果需要,您可以使用下面的代码将大小转换为 MB
let countBytes = ByteCountFormatter()
countBytes.allowedUnits = [.useMB]
countBytes.countStyle = .file
let fileSizeInMB = countBytes.string(fromByteCount: Int64(ENTERYOURVALUEHERE))
我有一个服务器,您可以在其中导入视频,上传后应该会直接下载到应用程序中。问题是应用程序将在视频文件完全上传到服务器之前开始下载它。
我设置了一个每 10 秒运行一次的计时器,用于检查文件夹中是否有新视频。如果有新视频,我会使用 URL 会话下载它。如果视频在启动应用程序之前已经上传到服务器,或者如果视频非常小并且在 10 秒计时器再次运行之前上传,这很好,但这不切实际。
我的想法是检查视频大小并在几秒钟后进行比较。如果视频大小相同,则下载它。下面是我用来获取大小并添加到数组中的代码,这样我就可以将它与以前的文件大小数组进行比较。
//videos data array is fetched from the server
for video in videos.components(separatedBy: "") {
if !video.hasPrefix("._"){
guard let videoUrl = video.encodeUrl() else {return}
if let url = URL(string:String(self.session.imports_dir + "/" + videoUrl)) {
//Gets the file size
let data = NSData(contentsOf: url)
let fileSize = Double(data!.length)
videoArrayFileSize.append(fileSize)
}
}
}
如果videoArrayFileSize 与之前的Filesize 数组不同,则先不要下载视频。问题是即使我使用
上面的代码也会导致应用程序严重滞后DispatchQueue.global(qos: .background).async
是否有更好的方法来检查文件大小或其他方法来检查文件是否已完全上传到服务器?
我无法编辑服务器代码,所以如果可能的话,我喜欢一种从应用程序中进行编辑的方法。
更新
我尝试使用下面的代码通过 URLSession 获取尺寸,它适用于测试视频 Big Bunny 但不适用于我服务器上的视频。我猜 HEAD 内容长度在我的视频中留空,给出 0。
func getFileSize(_ url: URL, completion: @escaping (Int64, Error?) -> Void){
let timeoutInterval = 5.0
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeoutInterval)
request.httpMethod = "HEAD"
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request) { (data, response, error) in
let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
completion(contentLength, error)
group.leave()
}.resume()
}
解决方案是使用 URL 请求并使用 HTTP 方法 "HEAD"。使用 "expectedContentLength",您可以找出文件大小,与前面提到的方法相比,这不会造成延迟。
func getFileSize(_ url: URL, completion: @escaping (Int64, Error?) -> Void){
let timeoutInterval = 5.0
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeoutInterval)
request.httpMethod = "HEAD"
let group = DispatchGroup()
group.enter()
URLSession.shared.dataTask(with: request) { (data, response, error) in
let contentLength = response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown
completion(contentLength, error)
group.leave()
}.resume()
}
如果需要,您可以使用下面的代码将大小转换为 MB
let countBytes = ByteCountFormatter()
countBytes.allowedUnits = [.useMB]
countBytes.countStyle = .file
let fileSizeInMB = countBytes.string(fromByteCount: Int64(ENTERYOURVALUEHERE))