在OSX中使用Swift 2设置桌面背景

6

在学习了Javascript之后,我正在尝试创建一些简单的工具来解决自己的需求,并且开始涉足OSX/iOS编程。

然而,我立刻就遇到了一个障碍。

我找到了两个应该能够工作的例子:

  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

这是第二个例子:

#!/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!")
  }
}

这在XCode 7 beta 3中不起作用。

希望将其简化为基本要素,我得出:

#!/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!")
}

并保存为文件wallpaper.swift

执行时出现错误:

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

现在我完全陷入困境了... 我尝试查阅NSWorkspaceNSScreen文档并在playground中运行,但这超出了我的能力范围。
删除它抱怨的额外参数(error: nil)只会给出不同的错误:
./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 )

代码在哪里出错了,我该如何理解并使其正常运行?

不熟悉OSX函数,但从错误来看,您是否尝试从“workspace.setDesktopImageURL”函数中删除“error:nil”? - Caleb
是的,返回的错误是./wallpaper3.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 )。这个“额外参数”错误似乎是那些“它坏了,自己想办法修”的错误之一。 - joshfindit
在Xcode中,使用ALT + CLICK查看对象的类型。如果您在.setDesktopImageURL上执行ALT + CLICK,则Xcode将向您显示此方法的类型和签名。然后,您将看到必须使用的正确参数(文档可能未更新)。 - Eric Aya
@EricD。这很方便,谢谢。我点击了.setDesktopImageURL,但它没有快速帮助,但当我按住命令键单击时,它将我带到了声明处(也很方便,我没想到)。那里的代码是func setDesktopImageURL(url: NSURL, forScreen screen: NSScreen, options: [String : AnyObject]) throws。这样错误更容易理解了吗? - joshfindit
4个回答

9
在您的示例中,您将nil作为options传递给该方法。 我猜之前它可以工作,但现在在您展示的注释中显示了当前方法签名:
(url: NSURL, forScreen screen: NSScreen, options: [String : AnyObject]) throws

我们可以看到,options应该是一个非可选的字典。

这意味着您不能再使用nil作为options参数:如果没有选项,只需传递一个空字典。

此外,在Swift 2中,此方法不再返回Bool,而是抛出异常。

这意味着您必须使用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)
}

这段代码完美运行,解释清晰。 谢谢。 我还有很多要学习的。 - joshfindit
运行得非常好!有什么办法可以在多个空间设置桌面图片吗? - Heestand XYZ
@Hexagons 很遗憾,这方面没有API可用。一些技巧曾经有效,但现在似乎不再起作用了。 - Eric Aya

5

Swift 3的更新示例:

do {
   let imgurl = NSURL.fileURL(withPath: singleImage)
   let workspace = NSWorkspace.shared()
   if let screen = NSScreen.main()  {
       try workspace.setDesktopImageURL(imgurl, for: screen, options: [:])
   }
} catch {
   print(error)
}

2

Swift 5.x 的更新版本:

do {
    let imageURL = URL(fileURLWithPath: "/path/to/image")
    if let screen = NSScreen.main {
        try NSWorkspace.shared.setDesktopImageURL(imageURL, for: screen, options: [:])
    }
} catch {
    print(error)
}

1
对于使用Xamarin Mac的我们,可以这样实现:
string filepath = "/Users/you/Desktop/sweet-wallpaper.jpg";

var workspace = NSWorkspace.SharedWorkspace;
var screen = NSScreen.MainScreen;

NSUrl url = NSUrl.FromFilename(filepath);
NSDictionary options = new NSDictionary();
NSError errorContainer = new NSError();

workspace.SetDesktopImageUrl(url, NSScreen.MainScreen, options, errorContainer);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接