FREE TRIAL: Accelerate your app development career with Hacking with Swift+! >>

NSImage in SwiftUI for macOS

Forums > macOS

Hello all, I've had a heck of a time trying to find any examples online regarding loading images from URLs in swiftUI for MacOs. I have the following example that runs perfectly on iOS, but because UIImage is not available in MacOS, i need a substitue. I read somewhere to swap NSImage for all the UIImage calls, although, while not producing an error, it also never displayed my image... Can anyone shed some light on the mystery?! For the record, i have combined my "imageLoader" and "contentView" files below into one for simplicity.

Thanks in advance!

import SwiftUI
import UIKit

private let _imageCache = NSCache<AnyObject, AnyObject>()

class ImageLoader: ObservableObject {
    @Published var image: UIImage?
    @Published var isLoading = false

    var imageCache = _imageCache

    func loadImage(with url: URL) {
        let urlString = url.absoluteString
        if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = imageFromCache
            return
        }
        DispatchQueue.global(qos: .background).async { [weak self] in
            guard let self = self else { return }
            do {
                let data = try Data(contentsOf: url)
                guard let image = UIImage(data:data) else {
                    return
                }
                self.imageCache.setObject(image, forKey: urlString as AnyObject)
                DispatchQueue.main.async { [weak self] in
                    self?.image = image
                }

            } catch {
                print(error.localizedDescription)
            }
        }
    }
}

struct ContentView: View {
    @ObservedObject var imageLoader = ImageLoader()

    var body: some View {
        HStack {

            ZStack {
                Rectangle()
                    .fill(Color.gray.opacity(0.3))
                if self.imageLoader.image != nil {
                    Image(uiImage: self.imageLoader.image!)
                    .resizable()
                }
            }
            .aspectRatio(16/9, contentMode: .fit)
            .cornerRadius(8)
            .shadow(radius: 4)
            Text("test")
        }
        .onAppear {
            let url = URL(string: "https://www.davisenterprise.com/files/2018/09/Red-apples-768x520.jpg")
            self.imageLoader.loadImage(with: url!)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

   

Change

import UIKit

to:

import Cocoa

Change all instances of UIImage to NSImage

Change:

Image(uiImage: self.imageLoader.image!)

to:

Image(nsImage: self.imageLoader.image!)

And then—very important!—you must allow outgoing connections in your target.

outgoing connections

   

aha! it was the outgoing connections!! SUPER!! Thanks a bunch!

   

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Get started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.