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

后端 未结 1 901
南旧
南旧 2021-02-06 09:18

I know that SDWebImage loads the image in a background thread so you\'re not blocking the UI/main thread when this downloading is going on. Furthermore, it will als

1条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-02-06 10:02

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

    Swift 4:

    import Foundation
    
    public enum Result {
        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) -> 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;
            }
        }
    

    0 讨论(0)
提交回复
热议问题