Vincent Gable’s Blog

June 14, 2010

Ask F-Script!

Filed under: Cocoa,iPhone,MacOSX,Objective-C,Programming | , , , , , ,
― Vincent Gable on June 14, 2010

F-Script is an amazingly useful tool for answering quick API
questions, like “What happens if I pass in nil“. I use it several times a week. For verifying corner-cases, F-Script is faster than google, stackoverflow, or reading header files. Just type in a questionable expression and instantly see what happens.

There’s a good tutorial to get you started quickly. I’m not going to reproduce it here, so if any of these examples aren’t clear, go read it.

Example: NSMutableArray

Objective-C had historically poor support for exceptions, and the Foundation/Cocoa libraries are pretty inconsistent about using them. For example, trying to add nil to an array throws an exception, but trying to remove nil from an array has no effect. Here’s how I used F-Script to verify that,

> a := NSMutableArray array

> a addObject:nil
NSInvalidArgumentException: *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil

> a addObject:'foo'

> a
NSCFArray {'foo'}

> a removeObject:nil

> a
NSCFArray {'foo'}

If you’re not impressed, I understand. Static text really can’t convey the power of an interactive console. Sure, the F-Script syntax is marginally more concise than writing the equivalent code in Objective-C, but not enough that it matters. What matters is the interactivity, I got my answer as soon as I hit return. No waiting on the compiler. No switching between the program and Xcode. Immediate feedback.

You might prefer to use python as a Cocoa console. That’s cool! I prefer F-Script because it’s closer to Objective-C, but any tool with a REPL console works. If you have a favorite, please leave a comment!

REPL consoles for exploring Objective-C on a Mac:

October 23, 2009

GUI is Dead, Long Live UI

Filed under: Design,Programming,Usability | , , , ,
― Vincent Gable on October 23, 2009

The term GUI, Graphical User Interface, pronounced “Gooey” is laughably anachronistic. All interfaces meant for people on modern computers are graphical. The right abbreviation to use today is simply UI, for User Interface, pronounced “You I”.

Believe me, I understand that a command line interface is still useful today. I use them. I’m a programmer. I get the whole UNIX thing. Even without a pipe, a command-line is the highest-bandwidth input mechanism we have today.

But all command lines live inside a graphical OS. That’s how computers work in the 21st century.
Picture 6.png

Whenever I see “GUI” written I can’t help but wonder if the author is dangerously out of touch. Do they still think graphical interfaces are a novelty that needs to be called out?

July 7, 2008

Programatically Excluding Things from Time Machine Backups

Filed under: Cocoa,MacOSX,Objective-C,Programming,UNIX | , ,
― Vincent Gable on July 7, 2008

To exclude files/folders from a Time Machine backup, you can use the C-function CSBackupSetItemExcluded().

As far as I know there isn’t an official way to do this from the command-line or a shell script. As near as I can tell, the safest way to it without using compiled C-code is:

sudo defaults write /Library/Preferences/com.apple.TimeMachine \
SkipPaths -array-add "PATH-ONE" "PATH-TWO"

where "PATH-ONE" "PATH-TWO" are of course paths to items you want to exclude.

Credit to Ellis Jordan Bojar for this solution. (original article) Using defaults instead of tinkering with .plist files directly is really the way to go!

March 13, 2008

Useful Mac OS X Text-Editing Shortcuts

Filed under: MacOSX,Tips,UNIX,Usability | , , ,
― Vincent Gable on March 13, 2008

Here is a handful of lesser-known Mac OS X keyboard shortcuts that I’ve found to be very useful for working with text. They work in all standard text-fields, which means they work in most programs. Sadly, they don’t work in Microsoft products, and a few other apps that use non-standard text fields.

option = you will see the mouse cursor into a + , and you can now select columns of text! Unfortunately it only seems to work in editable text-fields, which is a great shame.

ctrl + d = forward delete, even if you don’t have it on your MacBook’s keyboard.

ctrl + a = Go to the beginning of the line the insertion-point is on.

ctrl + e = Go to the beginning end of the line line the insertion-point is on.

ctrl + k = “kill the current line”, deletes everything from the right of the insertion point to the next newline. This is very useful in Terminal, because you can delete the tail of a long command

command + delete = “Delete To Beginning Of Line”. Just like ctrl+k, but backwards, not forwards. (It even puts the killed text on the yank-pasteboard — don’t worry if that makes no sense, it’s an emacs-ism I don’t find useful.)

And yes, that’s ctrl, not command, because these are shortcuts inherited from the old UNIX text-editor emacs. There are more emacs “key bindings” that are available, but I have never found them useful. This long list of Mac OS X keyboard shortcuts includes them.

command + ctrl + d = look up the word under the mouse in the dictionary. I can’t believe that other operating systems haven’t done this for decades, it’s that useful.

It is unfortunate when programs use text-fields that do not support commands the operating system should give to every application. It’s always a mistake. Fundamentally, not supporting ctrl+a (go to beginning) is no different then not supporting command+c (copy).

If you find these commands useful, please teach them, and let developers know it’s a problem when you can’t use them. That will improve computing for everyone.

March 5, 2008

Calling the Command Line from Cocoa

Filed under: Cocoa,MacOSX,Objective-C,Programming,Tips,UNIX | , , , ,
― Vincent Gable on March 5, 2008

The best way to call a shell-command from Coca is by using an NSTask. Here are the three resources on using an NSTask that I found the most helpful:
CocoDev’s write up
A few quick exaples
NSTask Class Refrence

And here is some sample code to do it for you. You are free to use this code however you please, but attribution is always appreciated. The two principle functions are:

+ (NSString*) executeShellCommandSynchronously:(NSString*)command executes the command “command” with sh, wait until it finishes, and return whatever it printed to stdout and stderr as an NSString.
CAUTION: may deadlock under some circumstances if the output gets so big it fills the pipe. See http://dev.notoptimal.net/search/label/NSTask for an overview of the problem, and a solution. I have not experienced the problem myself, so I can’t comment.

executeShellCommandAsynchronously: will have sh execute command in the background, without blocking anything.

For quick hacks, the POSIX int system(const char* command) function, might be a good one-line solution. It synchronously evaluates command with sh.

Enjoy!

EDITED 2009-11-29: this code probably won’t have the same $PATH you would get if you used Terminal. See this question on stackoverflow for more details. A solution that seems to work is to do,

    [task setLaunchPath:@"/bin/bash"];
    NSArray	*args = [NSArray arrayWithObjects:@"-l",
    				 @"-c",
    				 commandlineHere,
    				 nil];
    [task setArguments: args];

This launches bash (not in sh compatibility mode), and -l (lowercase L) tells it to “act as if it had been invoked as a login shell”. I haven’t tested this on systems where bash isn’t the default shell. There are lots of ways $PATH could be set, and I haven’t tested them all. But you are almost certainly going to be OK if everything you refer to is in /usr/bin:/bin:/usr/sbin:/sbin.

February 28, 2008

Useful MacOSX Terminal Commands

Filed under: MacOSX,Tips,UNIX | , ,
― Vincent Gable on February 28, 2008

Here are some OS X specific terminal commands that I have found useful, and you might not be aware of. Running man command in the Terminal will give you more information about command as it is on your system.

open
open file will open file the same way it would have been opened if you double-clicked it in the Finder. You can also specify what program to use to open the file.

pbcopy, pbpaste
Bridges the clipboard and the command line; you can pipe the clipboard into stdout, or pipe stdout into the clipboard.

ps -axww
Lists every process running on the system, and gives the full-path to them, and their PSN. I almost never use any other arguments to ps.

osascript
Execute an AppleScript. osascript -e “code-goes-here”, will execute the AppleScript inside the “”. This is a great way to get AppleScript functionality in a good scripting language.

ditto
Can do the work of cp or zip, but it does the right thing on OS X, and won’t throw away Mac-specific bits.
ditto -ckX --rsrc --keepParent path_to_a_bundledFile.bundle bundledFile.bundle.zip will compress path_to_a_bundledFile.bundle, and keep all the Mac-bits intact.

hdiutil
Create and manipulate disk-images; you can even use it to burn a disk-image to CD/DVD.
Inside a perl-script I do:
hdiutil create -ov -fs HFS+ -format UDBZ -volname \”IMLocation v$version (beta)\” -srcfolder $IMLBuildDir ~/Projects/Website/imlocation/IMLocation.dmg

To make the disk-image for IMLocation out of the contents of the directory $IMLBuildDir.

screencapture
Lets you take a screenshot. Unfortunately not very well documented.
screencapture -x /tmp/screen.png
Will silently take a screenshot, and save it to /tmp/screen.png.
I think this could be great for bug-reporting.

system_profiler
Reports system hardware and software configuration; with no arguments it reports everything. Obviously great for bug reports and research.

sw_vers
Prints version information about the Mac OS X.
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.5
BuildVersion: 9A581
$ sw_vers -productName
Mac OS X
$ sw_vers -productVersion
10.5
$ sw_vers -buildVersion
9A581

systemsetup
Configuration tool for certain machine settings in System Preferences.

defaults
Read and write application preferences. You can use it to discover and activate hidden settings, like Safari’s Debug menu. defaults read > all_defaults.txt will give you a grep-able text-file with every default on your system. It’s also a useful tool for automated testing, since you can twiddle configurations.

class-dump (3rd party tool)
Makes .h files from a binary. Great for reverse-engineering.

In addition to standard UNIX commands, Mac OS X includes many powerful command-line tools. This article only scratches the surface, and ignores many tools like podcast that are probably very useful, but aren’t part of my workflow.

Powered by WordPress