【发布时间】:2020-04-02 03:16:44
【问题描述】:
我有一个服务器,您可以将视频导入到该服务器,上传后应直接下载到应用程序。问题是应用程序将在视频文件完全上传到服务器之前开始下载视频文件。
我设置了一个每 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()
}
【问题讨论】:
-
documents 读起来很有趣
-
更好的解决方案是在服务器上安装一个 API,该 API 以单独调用的形式返回文件的文件大小
-
“我有一个服务器,您可以在上传时将视频导入到该服务器” - 所以,我的下一个想法是,当文件实际上传(完全)时,有服务器生成一个静默通知,提醒应用程序有新文件可供下载
-
NSData(contentsOf: url) 总是耗尽内存imo。如果您不介意,可以使用 AVAsset 类来确定视频的高度和宽度。
-
@MadProgrammer 我问其他开发人员是否可以设置 API 来返回文件大小,但他说他不能,因为我们将文件复制并粘贴到文件夹中。我不确定那是多么真实。
标签: swift xcode download urlsession