Skip to content

Instantly share code, notes, and snippets.

@dmytro-anokhin
Created January 1, 2021 17:07
Show Gist options
  • Save dmytro-anokhin/381478d6d5c478b73a3318009fab5e1a to your computer and use it in GitHub Desktop.
Save dmytro-anokhin/381478d6d5c478b73a3318009fab5e1a to your computer and use it in GitHub Desktop.
import SwiftUI
import Combine
import PlaygroundSupport
final class RemoteImage : ObservableObject {
enum LoadingState {
case initial
case inProgress
case success(_ image: Image)
case failure
}
@Published var loadingState: LoadingState = .initial
let url: URL
init(url: URL) {
self.url = url
}
func load() {
loadingState = .inProgress
cancellable = URLSession(configuration: .default)
.dataTaskPublisher(for: url)
.map {
guard let value = UIImage(data: $0.data) else {
return .failure
}
return .success(Image(uiImage: value))
}
.catch { _ in
Just(.failure)
}
.receive(on: RunLoop.main)
.assign(to: \.loadingState, on: self)
}
private var cancellable: AnyCancellable?
}
struct URLImage : View {
init(url: URL) {
remoteImage = RemoteImage(url: url)
remoteImage.load()
}
var body: some View {
ZStack {
switch remoteImage.loadingState {
case .initial:
EmptyView()
case .inProgress:
Text("Loading")
case .success(let image):
image
case .failure:
Text("Failed")
}
}
}
@ObservedObject private var remoteImage: RemoteImage
}
let url = URL(string: "https://homepages.cae.wisc.edu/~ece533/images/airplane.png")!
let view = URLImage(url: url)
.frame(width: 320.0, height: 320.0)
PlaygroundPage.current.setLiveView(view)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment