個人アプリでOn Demand Resourcesを使いたいところがあり、以下の記事を参考に導入してみました。
https://qiita.com/kukimo/items/39a0eeb40626a4cd364f
https://www.raywenderlich.com/520-on-demand-resources-in-ios-tutorial
仕組みや手順は公式ドキュメントと上記記事を参照するのが早いと思います。
Swift Concurrencyで以下のようなユーティリティを作っておくとより簡単に導入できるよというお話。
ResourceLoader.swift
import Foundation
/// On Demand Resourceの読み込みを支援
final class ResourceLoader {
static let `default` = ResourceLoader(bundle: .main)
private let bundle: Bundle
private init(bundle: Bundle) {
self.bundle = bundle
}
/// tagで指定されたOn Demand Resourceを読み込む
/// onSuccessで、実際のリソース読み込み処理を実装する
func load<R>(
tag: String,
onSuccess: () throws -> R
) async throws -> R {
let request = NSBundleResourceRequest(tags: [tag], bundle: bundle)
if await request.conditionallyBeginAccessingResources() {
// リソースは端末にダウンロードされている
} else {
// 端末にリソースをダウンロード
try await request.beginAccessingResources()
}
return try onSuccess()
}
}
使い方はこんな感じ。
let image = try await ResourceLoader.default.load(
tag: "MoreImages",
onSuccess: { UIImage(named: "more_image1") }
)
let url = try await ResourceLoader.default.load(
tag: "MoreSounds",
onSuccess: { Bundle.main.url(forResource: "sound", withExtension: "mp3") }
)