Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the Desktop background on OSX using Swift 2

After an introduction to Javascript, I'm trying to tackle OSX/iOS programming by creating some simple tools to scratch my own itches.

However, right from the jump I hit a roadblock.

I found two examples that should work.

  1. https://github.com/hinderberg/ios-swift-kurs/blob/master/swift-intro/wallpaper.swift
  2. https://www.snip2code.com/Snippet/196825/Swift-shell-script-to-randomize-wallpape

Here's the second:

#!/usr/bin/env xcrun swift

import Foundation
import AppKit
let imagesDir = "/Users/david/Dropbox/Graphics/Wallpaper-HD/"
var err: NSError?

let fs = NSFileManager.defaultManager()
let filenames = fs.contentsOfDirectoryAtPath(imagesDir, error: &err) as [String]?

if let error = err {
  NSLog(error.localizedDescription)
} else {

  let imagenames = filenames!.filter { $0.hasSuffix(".jpg") || $0.hasSuffix("png") }
  let ir = Int(arc4random_uniform(UInt32(imagenames.count)))
  let imgurl = NSURL.fileURLWithPath(imagesDir + imagenames[ir])

  let workspace = NSWorkspace.sharedWorkspace()
  let screen = NSScreen.mainScreen()
  let ok : Bool = workspace.setDesktopImageURL( imgurl!, forScreen: screen!, options: nil, error: nil )

  if ok { 
    println( "New wallpaper: " + imagenames[ir] ) 
  } else { 
    println("Oops!")
  }
}

This didn't work in XCode 7 beta 3.

Hoping to reduce to the essentials, I arrived at:

#!/usr/bin/env xcrun swift
import Foundation
import AppKit
let imagesDir = "/Users/josh/Downloads/"
let singleImage = "/Users/josh/Downloads/xlarge.png"


let imgurl = NSURL.fileURLWithPath(singleImage)

let workspace = NSWorkspace.sharedWorkspace()
let screen = NSScreen.mainScreen()
let ok : Bool = workspace.setDesktopImageURL( imgurl, forScreen: screen!, options: nil, error: nil )

if ok {
    print( "New wallpaper set!" )
} else {
    print("Oops!")
}

And saved as the file wallpaper.swift.

On execution, the error is:

./wallpaper.swift:17:49: error: extra argument 'error' in call
let ok : Bool = workspace.setDesktopImageURL( imgurl, forScreen: screen!, options: nil, error: nil )

And now I'm completely stuck... I've tried referring to NSWorkspace and NSScreen documentation as well as running through playground, but it's beyond my current skills.

Removing the extra argument it complains about (error: nil) simply gives a different error:

./wallpaper.swift:13:31: error: cannot invoke 'setDesktopImageURL' with an argument list of type '(NSURL, forScreen: NSScreen?, options: nil)'
let ok : Bool = workspace.setDesktopImageURL( imgurl, forScreen: screen, options: nil )

Where is the code failing, and how can I understand how to make it work properly?

like image 294
joshfindit Avatar asked Aug 05 '15 18:08

joshfindit


1 Answers

In your example you're passing nil as options to the method.

I guess it worked before but now in the comments you showed the current method signature:

(url: NSURL, forScreen screen: NSScreen, options: [String : AnyObject]) throws

We see that options should be a non-Optional Dictionary.

It means you can't use nil anymore for the options parameter: if you don't have options, just pass an empty Dictionary.

Also, now in Swift 2, this method doesn't return a Bool anymore, it throws.

Meaning you have to use it with do try catch:

do {
    let imgurl = NSURL.fileURLWithPath(singleImage)
    let workspace = NSWorkspace.sharedWorkspace()
    if let screen = NSScreen.mainScreen()  {
        try workspace.setDesktopImageURL(imgurl, forScreen: screen, options: [:])
    }
} catch {
    print(error)
}
like image 112
Eric Aya Avatar answered Oct 20 '22 19:10

Eric Aya