1
0
mirror of https://github.com/immich-app/immich.git synced 2025-08-08 23:07:06 +02:00

feat(mobile): cache latest ios widget entry for fallback (#19824)

* cache the last image an ios widget fetched and use if a fetch fails in a future timeline build

* code review fixes

* downgrade pbx for flutter

* use cache in snapshots
This commit is contained in:
Brandon Wees
2025-07-09 13:59:54 -05:00
committed by GitHub
parent a201665b7e
commit a918481c0b
7 changed files with 248 additions and 146 deletions

View File

@ -2,7 +2,7 @@ import Foundation
import SwiftUI
import WidgetKit
enum WidgetError: Error {
enum WidgetError: Error, Codable {
case noLogin
case fetchFailed
case unknown
@ -23,10 +23,10 @@ extension WidgetError: LocalizedError {
case .albumNotFound:
return "Album not found"
case .invalidURL:
return "An invalid URL was used"
case .invalidImage:
return "An invalid image was received"
@ -46,7 +46,7 @@ enum AssetType: String, Codable {
struct Asset: Codable {
let id: String
let type: AssetType
var deepLink: URL? {
return URL(string: "immich://asset?id=\(id)")
}
@ -75,6 +75,8 @@ struct Album: Codable {
let albumName: String
}
let IMMICH_SHARE_GROUP = "group.app.immich.share"
// MARK: API
class ImmichAPI {
@ -86,7 +88,7 @@ class ImmichAPI {
init() async throws {
// fetch the credentials from the UserDefaults store that dart placed here
guard let defaults = UserDefaults(suiteName: "group.app.immich.share"),
guard let defaults = UserDefaults(suiteName: IMMICH_SHARE_GROUP),
let serverURL = defaults.string(forKey: "widget_server_url"),
let sessionKey = defaults.string(forKey: "widget_auth_token")
else {
@ -189,18 +191,25 @@ class ImmichAPI {
else {
throw .invalidURL
}
guard let imageSource = CGImageSourceCreateWithURL(fetchURL as CFURL, nil) else {
guard let imageSource = CGImageSourceCreateWithURL(fetchURL as CFURL, nil)
else {
throw .invalidURL
}
let decodeOptions: [NSString: Any] = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceThumbnailMaxPixelSize: 400,
kCGImageSourceCreateThumbnailWithTransform: true
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceThumbnailMaxPixelSize: 400,
kCGImageSourceCreateThumbnailWithTransform: true,
]
guard let thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, decodeOptions as CFDictionary) else {
guard
let thumbnail = CGImageSourceCreateThumbnailAtIndex(
imageSource,
0,
decodeOptions as CFDictionary
)
else {
throw .fetchFailed
}