How to Cache Videos? iOS - Swift

Is it possible to cache Videos? IOS - Swift

Using Haneke, I wasn't able to retrieve file path for cached video. I handled it by saving video in cached directory.

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 {
completionHandler(Result.failure(NSError.errorWith(text: "Can't download video")))
}
}
}
}

private func directoryFor(stringUrl: String) -> URL {

let fileURL = URL(string: stringUrl)!.lastPathComponent

let file = self.mainDirectoryUrl.appendingPathComponent(fileURL)

return file
}
}

Sample usage of this class looks like this:

CacheManager.shared.getFileWith(stringUrl: "http://techslides.com/demos/sample-videos/small.mp4") { result in

switch result {
case .success(let url):
// do some magic with path to saved video
case .failure(let error):
// handle errror
}
}

How do I asynchronously download and cache videos for use in my app?

So I was able to solve the problem with the following:

Swift 4:

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
}
}

Usage:

      CacheManager.shared.getFileWith(stringUrl: videoURL) { result in

switch result {
case .success(let url):
// do some magic with path to saved video

break;
case .failure(let error):
// handle errror

print(error, " failure in the Cache of video")
break;
}
}


Related Topics



Leave a reply



Submit