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 commented Jun 6, 2019

How would you go and make this change animate in ?

@loganmoseley

This comment has been minimized.

Copy link

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 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 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 commented Dec 12, 2019

Thanks man this was really useful :)

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.