Я попытался использовать следующий механизм кэширования для кэширования видео, которые добавляются в ячейки моего приложения:
import Foundation
public enum Result<T> {
case success(T)
case failure(NSError)
}
class CacheManager {
static let shared = CacheManager()
private let fileManager = FileManager.default
private lazy var mainDirectoryUrl: URL = {
let documentsUrl = self.fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
return documentsUrl
}()
func getFileWith(stringUrl: String, completionHandler: @escaping (Result<URL>) -> Void ) {
let file = directoryFor(stringUrl: stringUrl)
//return file path if already exists in cache directory
guard !fileManager.fileExists(atPath: file.path) else {
completionHandler(Result.success(file))
return
}
DispatchQueue.global().async {
if let videoData = NSData(contentsOf: URL(string: stringUrl)!) {
videoData.write(to: file, atomically: true)
DispatchQueue.main.async {
completionHandler(Result.success(file))
}
} else {
DispatchQueue.main.async {
let error = NSError(domain: "SomeErrorDomain", code: -2001 /* some error code */, userInfo: ["description": "Can't download video"])
completionHandler(Result.failure(error))
}
}
}
}
private func directoryFor(stringUrl: String) -> URL {
let fileURL = URL(string: stringUrl)!.lastPathComponent
let file = self.mainDirectoryUrl.appendingPathComponent(fileURL)
return file
}
}
Используется так для каждой ячейки , если по этому индексу это видео :
CacheManager.shared.getFileWith(stringUrl: videoURL) { result in
switch result {
case .success(let url):
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = CGRect(x: -8, y: 0, width: 138, height: 217)
cell.imageOrVideoView.layer.addSublayer(playerLayer)//seems to use the the first video for all videos...
cell.profImage.sd_setImage(with: URL(string: "\(self.postArray[indexPath.item].user.profileImageUrlString!)"), placeholderImage: UIImage(named: "media"))
break;
// do some magic with path to saved video
case .failure(let error):
print(error, " failure in the Cache of video")
break;
// handle errror
}
}
Проблема в том, что теперь второй URL-адрес видео используется в качестве видео (которое я не воспроизводю) для каждой отдельной видеоэлемента.
Нужно ли перезагрузить кеш?Это кажется неправильным ...
Я обнаружил, что это проблемный код:
//return file path if already exists in cache directory
guard !fileManager.fileExists(atPath: file.path) else {
completionHandler(Result.success(file))
return
}
При комментировании охраны каждая ячейка получает правильное видео.Проблема в том, что он не кеширует его. Как я могу это исправить?
Редактировать: Я обнаружил что-то странное, что может быть признаком проблемы.если по указательному пути ячейка должна быть видео, то я печатаю видео, иначе это должно быть изображение для печати изображения.Однако, глядя в консоль, я вижу, что изображение печатается 5 раз, а видео - 2, даже если в виде коллекции есть 11 ячеек.Также я могу подтвердить, что независимо от того, что это я печатаю «здесь», который печатается 7 раз.Опять же, это все, когда (когда вы прокручиваете), есть 11 ячеек, все из которых должны быть разными, но, конечно, у всех видео есть первый кадр второго видео.