Im attempting to make a cache system in order that cache some movies in splash display to have higher person expertise specifically for first time opening the app
here is what I did in my cache supervisor
class CacheManager {static let shared = LocalJackpotsCacheManager()
personal let fileManager = FileManager.default
personal let cacheDirectory: URL
personal let databaseURL: URL
personal var db: OpaquePointer?
personal init() {
// Set cacheDirectory to the Paperwork listing
cacheDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("VideoCache")
databaseURL = cacheDirectory.appendingPathComponent("videoCacheMetadata.sqlite")
createCacheDirectoryIfNeeded()
setupDatabase()
}
personal func createCacheDirectoryIfNeeded() {
if !fileManager.fileExists(atPath: cacheDirectory.path) {
do {
strive fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Didn't create cache listing: (error)")
}
}
}
personal func setupDatabase() {
if sqlite3_open(databaseURL.path, &db) == SQLITE_OK {
let createTableQuery = """
CREATE TABLE IF NOT EXISTS VideoCache (
id TEXT PRIMARY KEY,
path TEXT,
lastAccessed INTEGER
);
"""
if sqlite3_exec(db, createTableQuery, nil, nil, nil) != SQLITE_OK {
print("Didn't create VideoCache desk")
}
} else {
print("Unable to open database")
}
}
func cacheVideo(from url: URL, forKey key: String, completion: @escaping () -> Void) {
let hashedKey = key.sha256()
let destinationURL = cacheDirectory.appendingPathComponent(hashedKey)
if fileManager.fileExists(atPath: destinationURL.path) {
completion() // File already cached
return
}
let downloadTask = URLSession.shared.downloadTask(with: url) { tempURL, _, error in
guard let tempURL = tempURL, error == nil else {
print("Obtain error: (error?.localizedDescription ?? "Unknown error")")
completion()
return
}
do {
strive self.fileManager.moveItem(at: tempURL, to: destinationURL)
self.updateDatabase(with: hashedKey, filePath: destinationURL.path)
completion() // Name completion on success
} catch {
print("Error saving video to cache: (error)")
completion()
}
}
downloadTask.resume()
}
func getCachedURL(forKey key: String) -> URL? {
let hashedKey = key.sha256()
let fileURL = cacheDirectory.appendingPathComponent(hashedKey)
return fileManager.fileExists(atPath: fileURL.path) ? fileURL : nil
}
personal func updateDatabase(with key: String, filePath: String) {
let updateQuery = """
INSERT OR REPLACE INTO VideoCache (id, path, lastAccessed) VALUES (?, ?, ?);
"""
var assertion: OpaquePointer?
if sqlite3_prepare_v2(db, updateQuery, -1, &assertion, nil) == SQLITE_OK {
let timestamp = Int(Date().timeIntervalSince1970)
sqlite3_bind_text(assertion, 1, key, -1, nil)
sqlite3_bind_text(assertion, 2, filePath, -1, nil)
sqlite3_bind_int(assertion, 3, Int32(timestamp))
sqlite3_step(assertion)
} else {
print("Error making ready replace assertion")
}
sqlite3_finalize(assertion)
}
func cleanOldCache(restrict: Int) {
let selectOldItemsQuery = """
SELECT id, path FROM VideoCache ORDER BY lastAccessed ASC LIMIT ?;
"""
var selectStatement: OpaquePointer?
if sqlite3_prepare_v2(db, selectOldItemsQuery, -1, &selectStatement, nil) == SQLITE_OK {
sqlite3_bind_int(selectStatement, 1, Int32(restrict))
whereas sqlite3_step(selectStatement) == SQLITE_ROW {
let id = String(cString: sqlite3_column_text(selectStatement, 0))
let path = String(cString: sqlite3_column_text(selectStatement, 1))
// Delete the file from disk
do {
strive fileManager.removeItem(atPath: path)
} catch {
print("Error deleting file from disk: (error)")
}
// Take away from database
deleteCacheEntry(withId: id)
}
}
sqlite3_finalize(selectStatement)
}
personal func deleteCacheEntry(withId id: String) {
let deleteQuery = "DELETE FROM VideoCache WHERE id = ?;"
var deleteStatement: OpaquePointer?
if sqlite3_prepare_v2(db, deleteQuery, -1, &deleteStatement, nil) == SQLITE_OK {
sqlite3_bind_text(deleteStatement, 1, id, -1, nil)
sqlite3_step(deleteStatement)
} else {
print("Error making ready delete assertion")
}
sqlite3_finalize(deleteStatement)
}
}
and the way Im attempting to make use of it
if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {
// Log cached file particulars for affirmation
do {
let information = strive Information(contentsOf: cachedFileURL)
print("Cached file efficiently loaded into Information object, dimension: (information.depend) bytes")
} catch {
print("Didn't load cached file into Information object: (error.localizedDescription)")
}
// Put together the video for playback
let asset = AVURLAsset(url: cachedFileURL, choices: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let playerItem = AVPlayerItem(asset: asset)
let participant = AVPlayer(playerItem: playerItem)
// Configure the cell with the participant
cell.configure(with: participant)
participant.play() // Begin playback instantly if desired
} else {
// If file isn't cached, obtain and cache it
LocalJackpotsCacheManager.shared.cacheVideo(from: videoURL, forKey: cacheKey) {
if let cachedFileURL = LocalJackpotsCacheManager.shared.getCachedURL(forKey: cacheKey) {
DispatchQueue.important.async {
// Put together the downloaded video for playback
let asset = AVURLAsset(url: cachedFileURL, choices: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let playerItem = AVPlayerItem(asset: asset)
let participant = AVPlayer(playerItem: playerItem)
cell.configure(with: participant)
participant.play()
}
}
}
}
dk what precisely unsuitable with this however file loaded and printed it is dimension ! preserve says Can’t open
attempt to cache and play video from native and preserve fails