0

I've been struggling with this for a bit, I can't seem to load an image(I've tried absolute/relative paths and different folders). The app is to set the wallpaper using an image. Also for some reason the image file doesn't show up in Appcode but it does in the terminal.

import Cocoa

let screens = NSScreen.screens[0]
let imgurl = NSURL.init(fileURLWithPath: "cheese.jpg")
try! NSWorkspace().setDesktopImageURL(imgurl as URL, for: screens)

wallpapersetter/main.swift:32: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=4 "The file doesn’t exist."

enter image description here

I did some searching and thought it might be a sandboxing issue but sandboxing has been disabled when i tried it in xcode and it still didn't work. It's also quite difficult to find info as the majority of swift questions are about IOS

magnusn
  • 1
  • 1
  • 1
    Use URL instead of NSURL and what is the real path to the image? – Joakim Danielson Jan 10 '23 at 16:08
  • The absolute path? it's /Users/magnus/Documents/wallpapersetter/wallpapersetter/cheese.jpg Oh amazing that works now with the absolute path, but it's still not working if i just use cheese.jpg as the path, any idea why? – magnusn Jan 10 '23 at 16:10
  • Why would the app know what the rest of the path is? – Joakim Danielson Jan 10 '23 at 16:12
  • I'm not too familiar with swift or the mac operating system, but in other programming languages it's quite common to use relative paths i think. That explains why it wasn't working though, tyvm – magnusn Jan 10 '23 at 16:14
  • Are you perhaps thinking about resources that are included in the app binary because that exists in the Swift world as well but this is an external file so then you need the absolute path. – Joakim Danielson Jan 10 '23 at 16:19

1 Answers1

0

URL doesn't provide a current directory like other programming languages

The most relative API Foundation supports is

let url = URL(string: "wallpapersetter/wallpapersetter/cheese.jpg",
        relativeTo: try! FileManager.default.url(for: .documentDirectory,
                                                 in: .userDomainMask,
                                                 appropriateFor: nil,
                                                 create: false))

for: .documentDirectory, in: .userDomainMask points to the Documents directory of the current user. If the project is sandboxed it points to the Documents directory in the application container.

Another way is to put the resource into the application bundle (if there is one). Bundle provides (relative) APIs to access items inside the bundle.

vadian
  • 274,689
  • 30
  • 353
  • 361