06/23 Fix Medium//Low-impact issues

This commit is contained in:
Nguyen Ngo
2026-06-23 18:03:40 -04:00
parent a1afea095d
commit fc571b3faa
5 changed files with 173 additions and 39 deletions
+48 -4
View File
@@ -32,16 +32,60 @@ final class LocalIssue {
private static let jsonDecoder = JSONDecoder()
private static let jsonEncoder = JSONEncoder()
// Lightweight decode cache avoids re-parsing identical JSON strings.
// SwiftData may call the getter multiple times per render pass (once for
// isEmpty, once for count, once for ForEach). Caching the last-decoded
// value by JSON string identity means the JSON parse only happens when
// the underlying data actually changes.
// @Transient tells SwiftData not to persist these they're in-memory only.
// Lightweight decode cache split into key+value pairs because SwiftData's
// @Transient macro does not support tuple types. Two separate @Transient
// properties per cache entry achieve the same result with no schema impact.
@Transient private var _cachedLocalKey: String = ""
@Transient private var _cachedLocalValue: [String] = []
@Transient private var _cachedServerKey: String = ""
@Transient private var _cachedServerValue: [String] = []
/// Decoded local photo paths (up to 5)
var photoLocalPaths: [String] {
get { (try? Self.jsonDecoder.decode([String].self, from: Data(photoLocalPathsJSON.utf8))) ?? [] }
set { photoLocalPathsJSON = (try? String(data: Self.jsonEncoder.encode(newValue), encoding: .utf8)) ?? "[]" }
get {
if _cachedLocalKey == photoLocalPathsJSON, !_cachedLocalKey.isEmpty {
return _cachedLocalValue
}
let decoded = (try? Self.jsonDecoder.decode([String].self,
from: Data(photoLocalPathsJSON.utf8))) ?? []
_cachedLocalKey = photoLocalPathsJSON
_cachedLocalValue = decoded
return decoded
}
set {
let encoded = (try? String(data: Self.jsonEncoder.encode(newValue),
encoding: .utf8)) ?? "[]"
photoLocalPathsJSON = encoded
_cachedLocalKey = encoded
_cachedLocalValue = newValue
}
}
/// Decoded server photo paths
var photoServerPaths: [String] {
get { (try? Self.jsonDecoder.decode([String].self, from: Data(photoServerPathsJSON.utf8))) ?? [] }
set { photoServerPathsJSON = (try? String(data: Self.jsonEncoder.encode(newValue), encoding: .utf8)) ?? "[]" }
get {
if _cachedServerKey == photoServerPathsJSON, !_cachedServerKey.isEmpty {
return _cachedServerValue
}
let decoded = (try? Self.jsonDecoder.decode([String].self,
from: Data(photoServerPathsJSON.utf8))) ?? []
_cachedServerKey = photoServerPathsJSON
_cachedServerValue = decoded
return decoded
}
set {
let encoded = (try? String(data: Self.jsonEncoder.encode(newValue),
encoding: .utf8)) ?? "[]"
photoServerPathsJSON = encoded
_cachedServerKey = encoded
_cachedServerValue = newValue
}
}
var createdAt: Date