VIMediaCache
VIMediaCache copied to clipboard
Add basic support to control cache
I think cache control is primary requirement. Plz add this feature, thanx
I have basic idea to control cache by just extending VICacheManager like below
extension VICacheManager {
static var maxCacheAge: TimeInterval = 60 * 60 * 24 * 7 // 1 week
/// The maximum size of the cache, in bytes.
static var maxCacheSize: UInt = 1000000 * 1000
static private let fileManager = FileManager.default
static fileprivate let ioQueue = DispatchQueue(label: "com.vgplayer.ioQueue")
/// Delete old file if cache size is exceede to maxCacheSize
static func cleanOldFilesIfNeeded(completion handler: (()->())? = nil) {
var error:NSError? = nil
let currentCacheSize = calculateCachedSizeWithError(&error)
guard error == nil, currentCacheSize > maxCacheSize else {
return
}
ioQueue.sync {
var (urlsToDelete, diskCacheSize, cachedFiels) = getOldFiles()
//Delete old file
for fileUrl in urlsToDelete {
cleanCache(for: fileUrl, error: nil)
}
//Check remaining cache size
if maxCacheSize > 0 && diskCacheSize > maxCacheSize {
let targetSize = maxCacheSize/2
let sortedfiles = cachedFiels.keysSortedByValue({ (v1, v2) -> Bool in
if let date1 = v1.contentAccessDate, let date2 = v2.contentAccessDate {
return date1.compare(date2) == .orderedAscending
}
return true
})
for fileUrl in sortedfiles {
diskCacheSize -= UInt(cachedFiels[fileUrl]?.totalFileAllocatedSize ?? 0)
cleanCache(for: fileUrl, error: nil)
urlsToDelete.append(fileUrl)
if diskCacheSize < targetSize {
break
}
}
}
DispatchQueue.main.async {
handler?()
}
}
}
static func getOldFiles() -> (urlsToDelete: [URL], diskCacheSize: UInt, cachedFiels:[URL: URLResourceValues]) {
var urlsToDelete = [URL]()
var diskCacheSize: UInt = 0
var cachedFiles = [URL: URLResourceValues]()
guard let expiredDate = maxCacheAge < 0 ? nil : Date(timeIntervalSinceNow: -maxCacheAge) else { return (urlsToDelete, diskCacheSize, cachedFiles) }
let fullPath = (cacheDirectory() as NSString).expandingTildeInPath
let url = URL(fileURLWithPath: fullPath)
let configurationExtention = "mt_cfg" //More detail -> VICacheConfiguration.m
let resourceKeys:[URLResourceKey] = [.contentAccessDateKey, .totalFileAllocatedSizeKey]
if let directoryEnumerator = fileManager.enumerator(at: url, includingPropertiesForKeys: resourceKeys, options: .skipsHiddenFiles, errorHandler: nil) {
for (_, value) in directoryEnumerator.enumerated() {
if let fileURL = value as? URL, fileURL.pathExtension != configurationExtention, let resourceValues = try? fileURL.resourceValues(forKeys: [.contentAccessDateKey, .totalFileAllocatedSizeKey]) {
if let lastAccessDate = resourceValues.contentAccessDate, (lastAccessDate as NSDate).laterDate(expiredDate) == expiredDate {
urlsToDelete.append(fileURL)
continue
} else {
cachedFiles[fileURL] = resourceValues
}
if let size = resourceValues.totalFileAllocatedSize {
diskCacheSize += UInt(size)
}
}
}
}
return (urlsToDelete, diskCacheSize, cachedFiles)
}
}
fileprivate extension Dictionary {
func keysSortedByValue(_ isOrderedBefore: (Value, Value) -> Bool) -> [Key] {
return Array(self).sorted{ isOrderedBefore($0.1, $1.1) }.map{ $0.0 }
}
}
It doesn't seem like this package is actively maintained. Is there a more active fork somewhere?