Skip to content

Instantly share code, notes, and snippets.

@Czajnikowski
Last active December 3, 2020 20:11
Show Gist options
  • Save Czajnikowski/924006474814d665f990214a86bee4b0 to your computer and use it in GitHub Desktop.
Save Czajnikowski/924006474814d665f990214a86bee4b0 to your computer and use it in GitHub Desktop.
A couple of abstractions useful in situations where you want to display some loadable content (whatever it is - news feed, image loaded from a URL or an output image from a filter or anything else)
import SwiftUI
LoadableResourceView(resourceProvider) { loadableResource in
SomeView(loadableResource)
}
import SwiftUI
public protocol LoadableResourceProviding: ObservableObject {
associatedtype Resource
var loadableResource: LoadableResource<Resource> { get }
func loadResource()
}
extension LoadableResourceProviding {
var loadedResource: Resource? {
loadableResource.loadedResource
}
}
public enum LoadableResource<Resource> {
case
idle,
loading(percentageLoaded: Int),
loaded(Resource),
failed
init(_ resource: Resource) {
self = .loaded(resource)
}
var loadedResource: Resource? {
if case let LoadableResource.loaded(resource) = self {
return resource
}
return nil
}
}
import SwiftUI
struct LoadableResourceView<ResourceProvider>: View where ResourceProvider: LoadableResourceProviding {
@StateObject var resourceProvider: ResourceProvider
let buildViewFor: (LoadableResource<ResourceProvider.Resource>) -> AnyView
var body: some View {
buildViewFor(resourceProvider.loadableResource)
.onAppear(perform: resourceProvider.loadResource)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment