Purge cache (IOS-14)
This commit is contained in:
parent
951f46353f
commit
6b12224578
|
@ -10,7 +10,7 @@ protocol AboutViewControllerDelegate: AnyObject {
|
|||
class AboutViewController: UIViewController {
|
||||
|
||||
let tableView: UITableView
|
||||
let sections: [AboutSettingsSection]
|
||||
private(set) var sections: [AboutSettingsSection] = []
|
||||
var tableViewDataSource: UITableViewDiffableDataSource<AboutSettingsSection, AboutSettingsEntry>?
|
||||
weak var delegate: AboutViewControllerDelegate?
|
||||
|
||||
|
@ -20,17 +20,6 @@ class AboutViewController: UIViewController {
|
|||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
tableView.register(AboutMastodonTableViewCell.self, forCellReuseIdentifier: AboutMastodonTableViewCell.reuseIdentifier)
|
||||
|
||||
sections = [
|
||||
AboutSettingsSection(entries: [
|
||||
.evenMoreSettings,
|
||||
.contributeToMastodon,
|
||||
.privacyPolicy
|
||||
]),
|
||||
AboutSettingsSection(entries: [
|
||||
.clearMediaCache(AppContext.shared.currentDiskUsage())
|
||||
])
|
||||
]
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
let tableViewDataSource = UITableViewDiffableDataSource<AboutSettingsSection, AboutSettingsEntry>(tableView: tableView) { [weak self] tableView, indexPath, itemIdentifier in
|
||||
|
@ -58,6 +47,20 @@ class AboutViewController: UIViewController {
|
|||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
update(with:
|
||||
[AboutSettingsSection(entries: [
|
||||
.evenMoreSettings,
|
||||
.contributeToMastodon,
|
||||
.privacyPolicy
|
||||
]),
|
||||
AboutSettingsSection(entries: [
|
||||
.clearMediaCache(AppContext.shared.currentDiskUsage())
|
||||
])]
|
||||
)
|
||||
}
|
||||
|
||||
func update(with sections: [AboutSettingsSection]) {
|
||||
self.sections = sections
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<AboutSettingsSection, AboutSettingsEntry>()
|
||||
|
||||
|
@ -66,7 +69,7 @@ class AboutViewController: UIViewController {
|
|||
snapshot.appendItems(section.entries)
|
||||
}
|
||||
|
||||
tableViewDataSource?.apply(snapshot)
|
||||
tableViewDataSource?.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import UIKit
|
||||
import AuthenticationServices
|
||||
import MastodonCore
|
||||
|
||||
protocol SettingsCoordinatorDelegate: AnyObject {
|
||||
func logout(_ settingsCoordinator: SettingsCoordinator)
|
||||
|
@ -71,9 +72,18 @@ extension SettingsCoordinator: AboutViewControllerDelegate {
|
|||
case .privacyPolicy:
|
||||
delegate?.openPrivacyURL(self)
|
||||
case .clearMediaCache(_):
|
||||
//TODO: appContext.purgeCache()
|
||||
//FIXME: maybe we should inject an AppContext/AuthContext here instead of delegating everything to SceneCoordinator?
|
||||
break
|
||||
AppContext.shared.purgeCache()
|
||||
viewController.update(with:
|
||||
[AboutSettingsSection(entries: [
|
||||
.evenMoreSettings,
|
||||
.contributeToMastodon,
|
||||
.privacyPolicy
|
||||
]),
|
||||
AboutSettingsSection(entries: [
|
||||
.clearMediaCache(AppContext.shared.currentDiskUsage())
|
||||
])]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,76 +126,51 @@ extension AppContext {
|
|||
return formatter
|
||||
}()
|
||||
|
||||
private static let purgeCacheWorkingQueue = DispatchQueue(label: "org.joinmastodon.app.AppContext.purgeCacheWorkingQueue")
|
||||
|
||||
public func purgeCache() -> AnyPublisher<ByteCount, Never> {
|
||||
Publishers.MergeMany([
|
||||
AppContext.purgeAlamofireImageCache(),
|
||||
AppContext.purgeTemporaryDirectory(),
|
||||
])
|
||||
.reduce(0, +)
|
||||
.eraseToAnyPublisher()
|
||||
public func purgeCache() {
|
||||
ImageDownloader.defaultURLCache().removeAllCachedResponses()
|
||||
|
||||
let fileManager = FileManager.default
|
||||
let temporaryDirectoryURL = fileManager.temporaryDirectory
|
||||
let fileKeys: [URLResourceKey] = [.fileSizeKey, .isDirectoryKey]
|
||||
|
||||
if let directoryEnumerator = fileManager.enumerator(
|
||||
at: temporaryDirectoryURL,
|
||||
includingPropertiesForKeys: fileKeys,
|
||||
options: .skipsHiddenFiles) {
|
||||
for case let fileURL as URL in directoryEnumerator {
|
||||
guard let resourceValues = try? fileURL.resourceValues(forKeys: Set(fileKeys)),
|
||||
resourceValues.isDirectory == false else {
|
||||
continue
|
||||
}
|
||||
|
||||
try? fileManager.removeItem(at: fileURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In Bytes
|
||||
public func currentDiskUsage() -> Int {
|
||||
let alamoFireDiskBytes = ImageDownloader.defaultURLCache().currentDiskUsage
|
||||
//TODO: Add temp directory files
|
||||
return alamoFireDiskBytes
|
||||
}
|
||||
|
||||
private static func purgeAlamofireImageCache() -> AnyPublisher<ByteCount, Never> {
|
||||
Future<ByteCount, Never> { promise in
|
||||
AppContext.purgeCacheWorkingQueue.async {
|
||||
// clean image cache for AlamofireImage
|
||||
let diskBytes = ImageDownloader.defaultURLCache().currentDiskUsage
|
||||
ImageDownloader.defaultURLCache().removeAllCachedResponses()
|
||||
let currentDiskBytes = ImageDownloader.defaultURLCache().currentDiskUsage
|
||||
let purgedDiskBytes = max(0, diskBytes - currentDiskBytes)
|
||||
promise(.success(purgedDiskBytes))
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private static func purgeTemporaryDirectory() -> AnyPublisher<ByteCount, Never> {
|
||||
Future<ByteCount, Never> { promise in
|
||||
AppContext.purgeCacheWorkingQueue.async {
|
||||
let fileManager = FileManager.default
|
||||
let temporaryDirectoryURL = fileManager.temporaryDirectory
|
||||
|
||||
let resourceKeys = Set<URLResourceKey>([.fileSizeKey, .isDirectoryKey])
|
||||
guard let directoryEnumerator = fileManager.enumerator(
|
||||
at: temporaryDirectoryURL,
|
||||
includingPropertiesForKeys: Array(resourceKeys),
|
||||
options: .skipsHiddenFiles
|
||||
) else {
|
||||
promise(.success(0))
|
||||
return
|
||||
}
|
||||
|
||||
var fileURLs: [URL] = []
|
||||
var totalFileSizeInBytes = 0
|
||||
for case let fileURL as URL in directoryEnumerator {
|
||||
guard let resourceValues = try? fileURL.resourceValues(forKeys: resourceKeys),
|
||||
let isDirectory = resourceValues.isDirectory else {
|
||||
continue
|
||||
}
|
||||
|
||||
guard !isDirectory else {
|
||||
continue
|
||||
}
|
||||
fileURLs.append(fileURL)
|
||||
totalFileSizeInBytes += resourceValues.fileSize ?? 0
|
||||
}
|
||||
|
||||
for fileURL in fileURLs {
|
||||
try? fileManager.removeItem(at: fileURL)
|
||||
}
|
||||
|
||||
promise(.success(totalFileSizeInBytes))
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
var tempFilesDiskBytes = 0
|
||||
let fileManager = FileManager.default
|
||||
let temporaryDirectoryURL = fileManager.temporaryDirectory
|
||||
let fileKeys: [URLResourceKey] = [.fileSizeKey, .isDirectoryKey]
|
||||
|
||||
if let directoryEnumerator = fileManager.enumerator(
|
||||
at: temporaryDirectoryURL,
|
||||
includingPropertiesForKeys: fileKeys,
|
||||
options: .skipsHiddenFiles) {
|
||||
for case let fileURL as URL in directoryEnumerator {
|
||||
guard let resourceValues = try? fileURL.resourceValues(forKeys: Set(fileKeys)),
|
||||
resourceValues.isDirectory == false else {
|
||||
continue
|
||||
}
|
||||
|
||||
tempFilesDiskBytes += resourceValues.fileSize ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
return alamoFireDiskBytes + tempFilesDiskBytes
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue