views:

62

answers:

2

How do you change the desktop picture in cocoa/objective-c? I've tried using defaults but had many errors.

NSArray *args=[NSArray arrayWithObjects:@"write",@"com.apple.desktop", @"Background", @"'{default = {ImageFilePath = \"~/desktop.jpg\";};}'", nil];

NSTask *deskTask=[[NSTask alloc] init];

[deskTask setArguments: args];

[deskTask setLaunchPath:@"/usr/bin/defaults"];
[deskTask launch];
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.desktop" object:@"BackgroundChanged"];

The command works successfully in terminal. I don't need anyone to tell me exactly what to do but I would like some insight.

EDIT: My OS is 10.4.11

+3  A: 

I think the canonical way is to use scripting with System Events. The Applescript version is something like:

tell application "System Events"
    tell current desktop
        set picture to (whatever)
    end tell
end tell

You can use the Scripting Bridge to do it from Objective-C.

Chuck
I forgot to add in my question that my OS is 10.4.11 (Scripting Bridge is unavailable unfortunately). Is there a workaround?
alexy13
Sure. Use appscript instead: http://appscript.sourceforge.net/
Chuck
Thanks! I'll try this right now.
alexy13
+2  A: 

When you use a tilde-compressed path in the shell, the shell expands the tilde for you, so when you run the command in the shell, you set the desktop-picture path to the expanded path (/path/to/desktop.jpg). There is no shell at work when you use NSTask, so the code you showed sets it to the tilde-compressed path. Very few things expect such a path; they don't expand the tilde, so it doesn't work.

To make that code work, you need to expand the tilde itself using the appropriate method of the NSString object, or construct the path by appending to the path returned by NSHomeDirectory().

That said, talking to System Events as Chuck suggested is a much better way to implement this. Note his comment telling you how to do it without requiring Leopard.

Peter Hosey