Created
October 19, 2020 01:00
-
-
Save liuzhida33/6253cffa4492c9e1f495d3407f6c88ee to your computer and use it in GitHub Desktop.
计算iOS常见缓存大小及清除缓存
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RxCocoa | |
import RxSwift | |
import Kingfisher | |
import NSObject_Rx | |
import WebKit | |
/// 缓存管理 | |
final class CacheManager: HasDisposeBag { | |
/// 缓存类型 | |
struct CacheType: OptionSet { | |
let rawValue: Int | |
static let picture = CacheType(rawValue: 1 << 0) /// 图片缓存 | |
static let file = CacheType(rawValue: 1 << 1) /// 文件缓存 | |
static let request = CacheType(rawValue: 1 << 2) /// 网络请求缓存 | |
static let web = CacheType(rawValue: 1 << 3) /// web缓存 | |
static let all: CacheType = [.picture, .file, .request, .web] | |
} | |
/// The default singleton instance. | |
static let shared = CacheManager() | |
private let cacheChanged = PublishSubject<Void>() | |
/// 返回某类型的缓存大小 | |
/// | |
/// - Parameter type: 缓存类型 | |
/// - Returns: 缓存大小(单位MB) | |
func size(_ type: CacheType = .all) -> Observable<Double> { | |
return cacheChanged.startWith(()) | |
.debounce(.milliseconds(250), scheduler: MainScheduler.instance) | |
.flatMap({ _ -> Observable<Double> in | |
return Observable.zip(type.helpers.map { $0.size() }).map { $0.reduce(0, { $0 + $1 }) / 1024 / 1024 } | |
}) | |
.share(replay: 1) | |
} | |
/// 清理缓存 | |
/// | |
/// - Parameter type: 缓存类型 | |
func clearDiskCache(_ type: CacheType = .all) { | |
Observable.zip(type.helpers.map { $0.clearCache() }) | |
.flatMap { Observable.from($0) } | |
.bind(to: cacheChanged) | |
.disposed(by: disposeBag) | |
} | |
} | |
extension CacheManager.CacheType { | |
fileprivate var helpers: [CacheHelper] { | |
switch self { | |
case .picture: return [KingfisherCacheHelper()] | |
case .file: return [FileCacheHelper()] | |
case .request: return [RequestCacheHelper()] | |
case .web: return [WebCacheHelper()] | |
case .all: return [KingfisherCacheHelper(), FileCacheHelper(), RequestCacheHelper(), WebCacheHelper()] | |
default: return [] | |
} | |
} | |
} | |
private protocol CacheHelper { | |
func calculateSize(completion handler: @escaping (Double) -> Void) | |
func clearCache(completion handler: (() -> Void)?) | |
} | |
extension CacheHelper { | |
func size() -> Observable<Double> { | |
return Observable.create({ observer -> Disposable in | |
self.calculateSize(completion: { size in | |
observer.onNext(size) | |
}) | |
return Disposables.create() | |
}) | |
} | |
func clearCache() -> Observable<Void> { | |
return Observable.create({ observer -> Disposable in | |
self.clearCache(completion: { | |
observer.onNext(()) | |
}) | |
return Disposables.create() | |
}) | |
} | |
} | |
/// Kingfisher缓存 | |
private struct KingfisherCacheHelper: CacheHelper { | |
func calculateSize(completion handler: @escaping (Double) -> Void) { | |
Kingfisher.ImageCache.default.calculateDiskStorageSize { result in | |
switch result { | |
case .success(let size): | |
handler(Double(size)) | |
case .failure(let error): | |
handler(Double(0)) | |
assertionFailure(error.localizedDescription) | |
} | |
} | |
} | |
func clearCache(completion handler: (() -> Void)?) { | |
Kingfisher.ImageCache.default.clearDiskCache { | |
handler?() | |
} | |
} | |
} | |
/// 下载文件缓存 | |
private struct FileCacheHelper: CacheHelper { | |
func calculateSize(completion handler: @escaping (Double) -> Void) { | |
FileHelper.shared.calculateDiskStorageSize { result in | |
switch result { | |
case .success(let size): | |
handler(Double(size)) | |
case .failure(let error): | |
handler(Double(0)) | |
assertionFailure(error.localizedDescription) | |
} | |
} | |
} | |
func clearCache(completion handler: (() -> Void)?) { | |
FileHelper.shared.clearDiskCache { | |
handler?() | |
} | |
} | |
} | |
/// 网络缓存 | |
private struct RequestCacheHelper: CacheHelper { | |
func calculateSize(completion handler: @escaping (Double) -> Void) { | |
handler(Double(URLCache.shared.currentDiskUsage)) | |
} | |
func clearCache(completion handler: (() -> Void)?) { | |
URLCache.shared.removeAllCachedResponses() | |
handler?() | |
} | |
} | |
/// web缓存 | |
private struct WebCacheHelper: CacheHelper { | |
func calculateSize(completion handler: @escaping (Double) -> Void) { | |
handler(0) | |
} | |
func clearCache(completion handler: (() -> Void)?) { | |
WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), modifiedSince: Date(timeIntervalSince1970: 0)) { | |
handler?() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment