Back to OSS
swift-cached-remote-image
SwiftUI向けリモート画像キャッシュ - メモリ&ディスクの二層キャッシュで高速表示
Swift
swiftuiimage-cacheasync
swift-cached-remote-image
SwiftUI でリモート画像をキャッシュ付きで表示するパッケージ
概要
swift-cached-remote-image は、SwiftUI でリモート画像を効率的に読み込み、メモリとディスクキャッシュで管理するためのパッケージです。非同期画像読み込み、リトライポリシー、カスタマイズ可能なプレースホルダーなどの機能を提供します。
主な機能
- ✅ SwiftUI ネイティブな API - SwiftUI と完全に統合された使いやすいインターフェース
- ✅ メモリ & ディスクキャッシュ - 自動的な二層キャッシュで高速表示
- ✅ 非同期画像読み込み - async/await を使った現代的な並行処理
- ✅ 柔軟な ImageSource - URL、URL 文字列、画像 ID から読み込み可能
- ✅ 画像 ID サポート - ImageService 経由でリソースから画像を取得
- ✅ カスタマイズ可能なリトライポリシー - 定数、指数バックオフなど
- ✅ プレースホルダーとエラー表示のカスタマイズ - 完全にカスタマイズ可能な UI
- ✅ キャッシュ管理 - リソースとデータキャッシュの個別管理
- ✅ iOS 17.0+ および macOS 14.0+ 対応 - クロスプラットフォームサポート
必要要件
- iOS 17.0+
- macOS 14.0+
- Swift 6.0+
依存関係
- swift-api-client - HTTP クライアント
前提条件
このパッケージを .imageId で使用する場合、指定された形式のレスポンスを返す REST API が必要です。
必須 API エンドポイント
- GET
/images/{imageId}- 画像リソース取得 - POST
/images- 画像アップロード(multipart/form-data) - DELETE
/images/{imageId}- 画像削除
必須レスポンス形式(JSON、camelCase)
{
"id": "img_123",
"url": "https://example.com/images/photo.jpg"
}
重要: レスポンスは camelCase である必要があります。
URL 直接指定(.url / .urlString)の場合は、API サーバーは不要です。
インストール
Swift Package Manager
Package.swift に以下を追加してください:
dependencies: [
.package(url: "https://github.com/no-problem-dev/swift-cached-remote-image.git", from: "1.1.0")
]
または Xcode で:
- File > Add Package Dependencies
- パッケージ URL を入力:
https://github.com/no-problem-dev/swift-cached-remote-image.git - バージョンを選択:
1.1.0以降
クイックスタート
最もシンプルな使用例:
import SwiftUI
import CachedRemoteImage
CachedRemoteImage(
source: .url(URL(string: "https://example.com/image.jpg")!)
)
これだけで、画像の読み込み、キャッシュ、デフォルトのローディング表示が行われます。
使い方
基本的な使用例
import SwiftUI
import CachedRemoteImage
struct ContentView: View {
var body: some View {
CachedRemoteImage(
source: .url(URL(string: "https://example.com/image.jpg")!)
) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
} placeholder: {
ProgressView()
}
}
}
URL 文字列から直接使用
CachedRemoteImage(
source: .urlString("https://example.com/image.jpg")
) { image in
image.resizable()
}
ImageSource の種類
CachedRemoteImage は ImageSource enum を通じて柔軟な画像ソースを提供します:
// 1. URL オブジェクトから
let url = URL(string: "https://example.com/image.jpg")!
CachedRemoteImage(source: .url(url))
// 2. URL 文字列から(自動的に URL に変換)
CachedRemoteImage(source: .urlString("https://example.com/image.jpg"))
// 3. 画像 ID から(ImageService 経由でリソースを取得)
CachedRemoteImage(source: .imageId("img_12345"))
注意:
.imageIdを使用する場合は、ImageServiceを環境に注入する必要があります。
ImageService を使った画像 ID からの取得
import APIClient
import CachedRemoteImage
// ImageService をセットアップ
@main
struct MyApp: App {
let imageService: ImageService
init() {
let apiClient = APIClientImpl(baseURL: URL(string: "https://api.example.com")!)
imageService = ImageServiceImpl(
apiClient: apiClient,
imagesPath: "/images",
maxResourceCacheSize: 100
)
}
var body: some Scene {
WindowGroup {
ContentView()
.imageService(imageService)
}
}
}
// 画像 ID で画像を表示
struct ImageView: View {
let imageId: String
var body: some View {
CachedRemoteImage(
source: .imageId(imageId)
) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
}
}
}
キャッシュ設定
リソースキャッシュサイズの設定
// ImageServiceImpl でリソースキャッシュサイズを設定
let imageService = ImageServiceImpl(
apiClient: apiClient,
imagesPath: "/images",
maxResourceCacheSize: 200 // リソースキャッシュ: 最大200エントリ
)
キャッシュクリア
// リソースキャッシュをクリア
await imageService.clearResourceCache()
// 画像データキャッシュをクリア
await imageService.clearImageCache()
// キャッシュサイズを取得
let cacheSize = await imageService.getCacheSize()
print("Current cache size: \(cacheSize) bytes")
画像ごとの設定(Configuration)
// カスタム設定で画像を読み込み
CachedRemoteImage(
source: .url(imageURL),
configuration: CachedRemoteImageConfiguration(
cachePolicy: .useProtocolCachePolicy,
retryPolicy: .exponential(maxAttempts: 3)
)
) { image in
image.resizable()
}
利用可能な設定:
- cachePolicy:
.useProtocolCachePolicy,.reloadIgnoringLocalCacheData,.returnCacheDataElseLoad,.returnCacheDataDontLoad - retryPolicy:
.none,.constant(maxAttempts:),.exponential(maxAttempts:)
ライセンス
このプロジェクトは MIT ライセンスの下で公開されています。詳細は LICENSE ファイルをご覧ください。
サポート
問題が発生した場合や機能リクエストがある場合は、GitHub の Issue を作成してください。