Skip to content

Instantly share code, notes, and snippets.

@fitomad
Last active April 22, 2020 02:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fitomad/9892155776c8c736b8a0d9e70aee3365 to your computer and use it in GitHub Desktop.
Save fitomad/9892155776c8c736b8a0d9e70aee3365 to your computer and use it in GitHub Desktop.
A SwiftUI example about async image loading.
//
// ImageLoader.swift
// DubDubKit
//
// Created by Adolfo Vera Blasco on 27/06/2019.
// Copyright © 2019 Adolfo Vera Blasco. All rights reserved.
//
#if os(macOS)
import AppKit
#else
import UIKit
#endif
import SwiftUI
import Combine
import Foundation
public class ImageLoader: ObservableObject
{
/// Ubicación de la imagen
private var imageURL: URL
/// La imagen. Avisamos de un cambio para que la
/// interface de usuario se actualize.
public private(set) var imageData: Data?
{
willSet
{
self.objectWillChange.send()
}
}
#if os(macOS)
/// La `NSImage` a partir de los datos recibidos
public var image: NSImage?
{
return NSImage(data: self.imageData)
}
#else
/// La `UIImage` a partir de los datos recibidos
public var image: UIImage?
{
guard let data = self.imageData else
{
return nil
}
return UIImage(data: data)
}
#endif
// MARK: - ObservableObject Protocol -
/// Informamos de los cambios a la vista.
public var objectWillChange = PassthroughSubject<Void, Never>()
/**
La URL donde se encuentra la imagen
*/
public init(from url: URL)
{
self.imageURL = url
}
//
// MARK: - Operations -
//
/**
Proceso de desacarga de la imagen
*/
public func requestImage() -> Void
{
let imageTask = URLSession.shared.dataTask(with: self.imageURL) { (data: Data?, response: URLResponse?, error: Error?) -> Void in
DispatchQueue.main.async
{
self.imageData = data
}
}
imageTask.resume()
}
}
//
// View de ejemplo
//
import SwiftUI
internal struct ImageView : View
{
///
@ObservedObject private var imageLoader: ImageLoader
var body: some View
{
Image(uiImage: self.imageLoader.image ?? UIImage(named: "EmptyImage")!)
.resizable()
.cornerRadius(6)
.shadow(radius: 8)
.frame(height: 200)
.padding(.bottom, 24)
.onAppear()
{
// Cargamos la imagen cuando la `View` se carga
self.imageLoader.requestImage()
}
}
/**
*/
internal init()
{
self.imageLoader = ImageLoader(from: URL(string: "https://pbs.twimg.com/profile_images/1051214278336888833/BevEdlCa_400x400.jpg")!)
}
}
@fitomad
Copy link
Author

fitomad commented Jul 18, 2019

Updated to Xcode 11 beta 4 BindableObject new implementation. didChange became willChange

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment