UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on 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()
    }
}

3      

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

4      

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

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

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.