Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
final class Loader: BindableObject {
let didChange = PassthroughSubject<Data?, Never>()
var task: URLSessionDataTask!
var data: Data? = nil {
didSet {
didChange.send(data)
}
}
init(_ url: URL) {
task = URLSession.shared.dataTask(with: url, completionHandler: { data, _, _ in
DispatchQueue.main.async {
self.data = data
}
})
task.resume()
}
deinit {
task.cancel()
}
}
let placeholder = UIImage(named: "placeholder.jpg")!
struct MyView: View {
init(url: URL) {
self.imageLoader = Loader(url)
}
@ObjectBinding private var imageLoader: Loader
var image: UIImage? {
imageLoader.data.flatMap(UIImage.init)
}
var body: some View {
Image(uiImage: image ?? placeholder)
}
}
@Plnda

This comment has been minimized.

Copy link

@Plnda Plnda commented Jun 6, 2019

How would you go and make this change animate in ?

@loganmoseley

This comment has been minimized.

Copy link

@loganmoseley loganmoseley commented Jun 6, 2019

I haven't gotten to try SwiftUI myself, but I think I remember an example from a session to animate a change:

    var body: some View {
        withAnimation { Image(uiImage: image ?? placeholder) }
    }
@JaroVoltix

This comment has been minimized.

Copy link

@JaroVoltix JaroVoltix commented Jun 19, 2019

That code make Xcode unable to build my project or Segmentation fault occurs

@tagmetag

This comment has been minimized.

Copy link

@tagmetag tagmetag commented Nov 2, 2019

Update code for newest (when @BindableObject has been depreciated):

import SwiftUI

final class Loader: ObservableObject {
    
    var task: URLSessionDataTask!
    @Published var data: Data? = nil
    
    init(_ url: URL) {
        task = URLSession.shared.dataTask(with: url, completionHandler: { data, _, _ in
            DispatchQueue.main.async {
                self.data = data
            }
        })
        task.resume()
    }
    deinit {
        task.cancel()
    }
}

let placeholder = UIImage(named: "placeholder.jpg")!

struct AsyncImage: View {
    init(url: URL) {
        self.imageLoader = Loader(url)
    }
    
    @ObservedObject private var imageLoader: Loader
    var image: UIImage? {
        imageLoader.data.flatMap(UIImage.init)
    }
    
    
    var body: some View {
        Image(uiImage: image ?? placeholder)
    }
}

@Hakonslie

This comment has been minimized.

Copy link

@Hakonslie Hakonslie commented Dec 12, 2019

Thanks man this was really useful :)

@swagatnayak

This comment has been minimized.

Copy link

@swagatnayak swagatnayak commented Apr 29, 2020

Thanks, dear....really you save my day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.