Set NSImage to variable instead of quoted string for image name

Thanks in advance to all. I am sure I am doing something stupid here. This is a macOS project and I am trying to update an image view using a variable, not the quoted name of the image as done here:


self.myAppIcon.image = NSImage(named:"microsoft.png")


That works fine and the app will show the default image on load and then change to the named image ("microsoft.png") when requested. However, when I try to get it to use a variable in the place of the quoted string, I am not getting the app to update to image.


I assumed I could just use something like:


self.myAppIcon.image = NSImage(named: self.theIcon)


where theIcon is set by loading a string from a file read from disk. All the images are in the project and all load is called explicitly. Here I am reading from a file to get the image name:


let myIcon = try String(contentsOf: iconURL, encoding: .utf8)

self.theIcon = myIcon


When I print myIcon I see the value being read properly from the text file. Changing the text file will show the new value on next call. However, the image view does not update. I've tried quite a few variations but either I get a class mismatch (image not string, data not string, etc), or I thow execution errors.


How do I reference a variable to allow the NSImage to update based on a dynamic value? Isn't NSImage(named: String) a string value? Shouldn't I be able to replace that quoted String with a variable that is a string?


Appreciate any help. I suspect this is a remarkably simple solution but I am too deep into the forest to see the trees at this point and likely need to step away.

  • Hi Strontium90 , if you could give me a hand. You replied and help on this thread: https://discussions.apple.com/thread/250537136 since there is no direct way to contact someone I'm trying here you should see the comment.

    For weird reasons when copy-pasting terminal lines on the communities forum some chunks are missing.

    here is my email voycom at me.com

    I started I new tread but not getting any answer.... https://discussions.apple.com/thread/253002760

    will delete this in a couple of days... Thank's in advance

Add a Comment

Accepted Reply

Thanks for helping out. Here is what I am doing:


//Set the variable

var theIcon:String = ""


//Connect the outlet

@IBOutlet weak var myAppIcon: NSImageView!


//Set name of file

let icon = "icon.txt"


//Read the contents of the file

if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

let iconURL = dir.appendingPathComponent(icon)

do {

let myIcon = try String(contentsOf: iconURL, encoding: .utf8)

self.theIcon = myIcon

print(myIcon)


}

catch {/* error handling here */}

}


//Update the UI

DispatchQueue.main.async {

print("update some UI")


self.myAppIcon.image = NSImage(named: self.theIcon)

}




The file, icon.txt, contains the full name of the file. For example, microsoft.png or printer.png. I can update the file while the app is running and the value is printed to the output window.


printers.png


update some UI


Am i dealing with a new line issue here?


Oh my oh my. I am such a doofus. It was the newline! I was using echo to test updating the file and I did not use -n. All along the issue was bad input from the file because I was getting microsoft.png\n not microsoft.png. I am kicking myselft for failing to pay attention to the gapping white space between the logging output.


Thank you for making be take a break and also looking at the obvious.

Replies

of course you can replace

self.myAppIcon.image = NSImage(named:"microsoft.png")

by

let imageName = "microsoft.png"

self.myAppIcon.image = NSImage(named: imageName)


and get the exact same result.


So the problem is elsewhere.


In NSImage

(named name: NSImage.Name)

name is NSImage.Name which is only a typealias for String


When I print myIcon I see the value being read properly from the text file.

What do you get exactly ? Is it a name with an extension or not ?


Could you show more code ?

Thanks for helping out. Here is what I am doing:


//Set the variable

var theIcon:String = ""


//Connect the outlet

@IBOutlet weak var myAppIcon: NSImageView!


//Set name of file

let icon = "icon.txt"


//Read the contents of the file

if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

let iconURL = dir.appendingPathComponent(icon)

do {

let myIcon = try String(contentsOf: iconURL, encoding: .utf8)

self.theIcon = myIcon

print(myIcon)


}

catch {/* error handling here */}

}


//Update the UI

DispatchQueue.main.async {

print("update some UI")


self.myAppIcon.image = NSImage(named: self.theIcon)

}




The file, icon.txt, contains the full name of the file. For example, microsoft.png or printer.png. I can update the file while the app is running and the value is printed to the output window.


printers.png


update some UI


Am i dealing with a new line issue here?


Oh my oh my. I am such a doofus. It was the newline! I was using echo to test updating the file and I did not use -n. All along the issue was bad input from the file because I was getting microsoft.png\n not microsoft.png. I am kicking myselft for failing to pay attention to the gapping white space between the logging output.


Thank you for making be take a break and also looking at the obvious.

Thanks for the feedback and good continuation.


Don't forget to close the thread.