A lightweight data model that loads content asyncronously while efficently handling concurrent duplicative requests.
Option A (simple, easy, no dependencies): Copy-and-paste the file into your project.
Option B (auto-updating): Use Swift Package Manager. The library is available at:
https://github.com/Sid-MB/Swift-Cache
In a data model:
class DocumentsModel {
// Set up the cache with the loading method.
private var songsByArtist = Cache { artist in
try await API.getSongs(for: artist)
}
// On the first request for an artist, songs are loaded from the server.
// On subsequent requests, data is pulled instantly from the cache.
func getSongs(for artist: Artist) async throws -> [Song] {
return try await songsByArtist[artist]
}
}
In a SwiftUI View:
struct CollaboratorsList: View {
var collaboratorIDs: [User.Identifier]
// No separate data model file needed.
@StateObject private var userModel = Cache { userID in
return try await API.getUser(id: userID)
}
var body: some View {
ForEach(collaboratorIDs, id: \.self) { userID in
VStack {
// Retrieve user data from the cache.
// When the data finishes loading in the background, the view will automatically update.
if let user = userModel.request(userID) {
Text(user.name)
Text(user.email)
} else {
ProgressView()
}
}
}
}
}
Note
Use within the body of SwiftUI views may require converting the Cache
actor into a class
with a @MainActor
annotation to prevent "synchronous non-isolated context" errors.