Files
ios-gitea-prs/GiteaPR/Inbox/InboxCache.swift
T
Hermes 2b929e65e9
Build iOS App / Build .ipa and publish source (push) Successful in 23s
Speed up landing screen: drop per-PR enrichment + add inbox cache; bump to 2.1
The inbox was slow because it enriched every PR with CI runs + reviews (2
extra API calls per PR, sequential). Drop that from the list — CI/review
status now shows only in the PR detail screen. Add a disk cache so the landing
screen renders instantly from the last load, then refreshes in the background
and keeps the cached list on network failure. Bump to 2.1.
2026-08-13 06:27:32 +00:00

44 lines
1.6 KiB
Swift

import Foundation
/// Persists the inbox PR list to disk so the landing screen can render
/// instantly from the last load, then refresh in the background.
struct InboxCache {
private let fileURL: URL
init() {
let dir = FileManager.default.urls(for: .cachesDirectory,
in: .userDomainMask)[0]
fileURL = dir.appendingPathComponent("inbox.json")
}
func load() -> [PRRow] {
guard let data = try? Data(contentsOf: fileURL) else { return [] }
return (try? Self.decoder.decode([PRRow].self, from: data)) ?? []
}
func save(_ rows: [PRRow]) {
guard let data = try? JSONEncoder().encode(rows) else { return }
try? data.write(to: fileURL)
}
/// Same ISO8601-with-offset date strategy the API decoder uses, so the
/// cached `Date?` fields decode correctly.
private static let decoder: JSONDecoder = {
let d = JSONDecoder()
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
d.dateDecodingStrategy = .custom { decoder in
let container = try decoder.singleValueContainer()
let str = try container.decode(String.self)
if let date = formatter.date(from: str) { return date }
let plain = ISO8601DateFormatter()
plain.formatOptions = [.withInternetDateTime]
if let date = plain.date(from: str) { return date }
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "Cannot decode date string \(str)")
}
return d
}()
}