Don't cache attachments to disk, only avatars and headers

This commit is contained in:
Shadowfacts 2018-11-07 19:24:52 -05:00
parent 3732fe1e31
commit 6393829174
3 changed files with 85 additions and 14 deletions

View File

@ -134,6 +134,7 @@
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; }; D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; };
D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; }; D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; };
D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; }; D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; };
D6F1F84D2193B56E00F5FE67 /* Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F1F84C2193B56E00F5FE67 /* Cache.swift */; };
D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */; }; D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */; };
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; }; D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -333,6 +334,7 @@
D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = "<group>"; }; D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = "<group>"; };
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounter.swift; sourceTree = "<group>"; }; D6E6F26221603F8B006A8599 /* CharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounter.swift; sourceTree = "<group>"; };
D6E6F26421604242006A8599 /* CharacterCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounterTests.swift; sourceTree = "<group>"; }; D6E6F26421604242006A8599 /* CharacterCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounterTests.swift; sourceTree = "<group>"; };
D6F1F84C2193B56E00F5FE67 /* Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = "<group>"; };
D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; }; D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; }; D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -773,9 +775,9 @@
D627FF73217BBC9700CC0648 /* AppRouter.swift */, D627FF73217BBC9700CC0648 /* AppRouter.swift */,
D64D0AAC2128D88B005A6F37 /* LocalData.swift */, D64D0AAC2128D88B005A6F37 /* LocalData.swift */,
D627FF75217E923E00CC0648 /* DraftsManager.swift */, D627FF75217E923E00CC0648 /* DraftsManager.swift */,
04DACE8D212CC7CC009840C4 /* ImageCache.swift */,
D6028B9A2150811100F223B9 /* MastodonCache.swift */, D6028B9A2150811100F223B9 /* MastodonCache.swift */,
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */, D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */,
D6F1F84E2193B9BE00F5FE67 /* Caching */,
D6757A7A2157E00100721E32 /* XCallbackURL */, D6757A7A2157E00100721E32 /* XCallbackURL */,
D62D241E217AA46B005076CC /* Shortcuts */, D62D241E217AA46B005076CC /* Shortcuts */,
D663626021360A9600C9CBA2 /* Preferences */, D663626021360A9600C9CBA2 /* Preferences */,
@ -808,6 +810,15 @@
path = TuskerUITests; path = TuskerUITests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D6F1F84E2193B9BE00F5FE67 /* Caching */ = {
isa = PBXGroup;
children = (
D6F1F84C2193B56E00F5FE67 /* Cache.swift */,
04DACE8D212CC7CC009840C4 /* ImageCache.swift */,
);
path = Caching;
sourceTree = "<group>";
};
D6F953F121251A2F00CF0F2B /* Controllers */ = { D6F953F121251A2F00CF0F2B /* Controllers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1188,6 +1199,7 @@
D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */, D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */,
D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */, D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */,
D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */, D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */,
D6F1F84D2193B56E00F5FE67 /* Cache.swift in Sources */,
D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */, D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */,
D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */, D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */,
D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */, D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */,

View File

@ -0,0 +1,50 @@
//
// Cache.swift
// Tusker
//
// Created by Shadowfacts on 11/7/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import Foundation
import Cache
/// Wrapper around Cache library that provides an API for transparently using any storage type
enum Cache<T> {
case memory(MemoryStorage<T>)
case disk(DiskStorage<T>)
case hybrid(HybridStorage<T>)
func existsObject(forKey key: String) throws -> Bool {
switch self {
case let .memory(memory):
return try memory.existsObject(forKey: key)
case let .disk(disk):
return try disk.existsObject(forKey: key)
case let .hybrid(hybrid):
return try hybrid.existsObject(forKey: key)
}
}
func object(forKey key: String) throws -> T {
switch self {
case let .memory(memory):
return try memory.object(forKey: key)
case let .disk(disk):
return try disk.object(forKey: key)
case let .hybrid(hybrid):
return try hybrid.object(forKey: key)
}
}
func setObject(_ object: T, forKey key: String, expiry: Expiry? = nil) throws {
switch self {
case let .memory(memory):
memory.setObject(object, forKey: key, expiry: expiry)
case let .disk(disk):
try disk.setObject(object, forKey: key, expiry: expiry)
case let .hybrid(hybrid):
try hybrid.setObject(object, forKey: key, expiry: expiry)
}
}
}

View File

@ -11,25 +11,34 @@ import Cache
class ImageCache { class ImageCache {
static let avatars = ImageCache(name: "Avatars") static let avatars = ImageCache(name: "Avatars", memoryExpiry: .seconds(60 * 60), diskExpiry: .seconds(60 * 60 * 24))
static let headers = ImageCache(name: "Headers") static let headers = ImageCache(name: "Headers", memoryExpiry: .seconds(60 * 60), diskExpiry: .seconds(60 * 60 * 24))
static let attachments = ImageCache(name: "Attachments", diskExpiry: .seconds(60 * 60), memoryExpiry: .seconds(60)) static let attachments = ImageCache(name: "Attachments", memoryExpiry: .seconds(60 * 2))
let storage: Storage<UIImage> let cache: Cache<UIImage>
var requests = [URL: Request]() var requests = [URL: Request]()
init(name: String, diskExpiry: Expiry = .seconds(60 * 60 * 24), memoryExpiry: Expiry = .seconds(60 * 60)) { init(name: String, memoryExpiry expiry: Expiry) {
self.storage = try! Storage( let storage = MemoryStorage<UIImage>(config: MemoryConfig(expiry: expiry))
diskConfig: DiskConfig(name: name, expiry: diskExpiry), self.cache = .memory(storage)
memoryConfig: MemoryConfig(expiry: memoryExpiry), }
transformer: TransformerFactory.forImage())
init(name: String, diskExpiry expiry: Expiry) {
let storage = try! DiskStorage<UIImage>(config: DiskConfig(name: name, expiry: expiry), transformer: TransformerFactory.forImage())
self.cache = .disk(storage)
}
init(name: String, memoryExpiry: Expiry, diskExpiry: Expiry) {
let memory = MemoryStorage<UIImage>(config: MemoryConfig(expiry: memoryExpiry))
let disk = try! DiskStorage<UIImage>(config: DiskConfig(name: name, expiry: diskExpiry), transformer: TransformerFactory.forImage())
self.cache = .hybrid(HybridStorage(memoryStorage: memory, diskStorage: disk))
} }
func get(_ url: URL, completion: ((UIImage?) -> Void)?) { func get(_ url: URL, completion: ((UIImage?) -> Void)?) {
let key = url.absoluteString let key = url.absoluteString
if (try? storage.existsObject(forKey: key)) ?? false, if (try? cache.existsObject(forKey: key)) ?? false,
let image = try? storage.object(forKey: key) { let image = try? cache.object(forKey: key) {
completion?(image) completion?(image)
} else { } else {
if let completion = completion, let request = requests[url] { if let completion = completion, let request = requests[url] {
@ -38,14 +47,14 @@ class ImageCache {
let request = Request(url: url, completion: completion) let request = Request(url: url, completion: completion)
requests[url] = request requests[url] = request
request.run { (image) in request.run { (image) in
try? self.storage.setObject(image, forKey: key) try? self.cache.setObject(image, forKey: key)
} }
} }
} }
} }
func get(_ url: URL) -> UIImage? { func get(_ url: URL) -> UIImage? {
return try? storage.object(forKey: url.absoluteString) return try? cache.object(forKey: url.absoluteString)
} }
func cancel(_ url: URL) { func cancel(_ url: URL) {