Paul Calnan
Published October 21, 2014

I regularly make QuickTime screen recordings of demos for clients. While it's easy to capture the entire screen, it's tricky when you want to capture only a single window. You need to open QuickTime Player, select New Screen Recording, then drag a rectangle over the exact area of the screen where the window is located. It's that last part that's a real pain. Even worse, if you have to do multiple takes, you need to drag out the selection rectangle each time.

One day, after around ten failed takes of a demo I was trying to do with a live voiceover, I got fed up and automated the process.

You can use AppleScript to get the target window's position and to kick off the screen recording. You need to change the process name (here, it's configured to record the iOS Simulator) and possibly the window number (if the app has more than one window).

I couldn't figure out a way to get AppleScript to move or drag the mouse. Originally, this required a small C program. I was recently able to replace it with a Swift script:

The script, saved in my ~/bin directory, takes four arguments: the starting x- and y-coordinates and the x and y distance to move the mouse. For example:

~/bin/clickdrag -x 10 -y 20 -dx 200 -dy 100

This moves the mouse to pixel (10, 20) on the screen, simulates a left mouse button press, waits a half second, drags the mouse 200 pixels to the right and 100 pixels down, waits another half second, and releases the mouse button.

It's not very polished, and you may need to tweak the delays here and there to make it work, but it's better than having to do it by hand.

Published August 27, 2014

I use a lot of TextExpander snippets when doing Objective-C development. I really like Objective-C, but it can be pretty verbose at times. If I find myself typing the same thing repeatedly, I make a new snippet for it.

The snippets make extensive use of Xcode placeholder tokens. For example:

[NSString stringWithFormat:@"<#format string#>", <#args#>]

This will give you two placeholder "bubbles"; one for format string and the other for args. You can tab between the bubbles and replace them with whatever you need in that place.


I use ;init to insert a default initializer:

- (instancetype)init
    if ((self = [super init]))
    return self;

Notice the use of %| which defines the cursor location after the snippet is expanded.

I also use ;iinit to insert an initializer body (iinit for Inside Init):

    if ((self = [super init]))
    return self;

That's useful for writing initializers with parameters. It's indented an extra four spaces since it's going inside the method body.

Default Description Implementation

I use ;desc to generate a -description method that behaves like the default in NSObject. I can then build on it from there.

- (NSString *)description
    return [NSString stringWithFormat:@"<%@: %p>", NSStringFromClass([self class]), self];

UIViewController View Methods

;vwa generates a -viewWillAppear:

- (void)viewWillAppear:(BOOL)animated
    [super viewWillAppear:animated];

;vwd generates a -viewWillDisappear:

- (void)viewWillDisappear:(BOOL)animated
    [super viewWillDisappear:animated];

;vda generates a -viewDidAppear:

- (void)viewDidAppear:(BOOL)animated
    [super viewDidAppear:animated];

;vdd generates a -viewDidDisappear:

- (void)viewDidDisappear:(BOOL)animated
    [super viewDidDisappear:animated];


Variations for readonly, copy, strong, weak, and assign:

;pnra expands to:

@property (nonatomic, readonly, assign)

;pnrc expands to:

@property (nonatomic, readonly, copy)

;pnrs expands to:

@property (nonatomic, readonly, strong)

;pnrw expands to:

@property (nonatomic, readonly, weak)

;pna expands to:

@property (nonatomic, assign)

;pnc expands to:

@property (nonatomic, copy)

;pns expands to:

@property (nonatomic, strong)

;pnw expands to:

@property (nonatomic, weak)

The Strong-Self / Weak-Self Dance

;ws expands to:

__weak typeof(self) weakSelf = self;

;ss expands to:

__strong typeof(weakSelf) strongSelf = weakSelf;

Private Read-Write Property Declarations

Say you have a public interface for a class, like this:

@interface SomeClass : NSObject
@property (nonatomic, readonly, copy) NSString *someString;
@property (nonatomic, readonly, copy) NSDictionary *someDictionary;

If you want to generate a private declaration, simply copy the interface to the pasteboard and run ;dprivate. This is a shell script snippet, that performs the following:

pbpaste | sed -e 's/ : .*$/ ()/' -e 's/, readonly//' | grep -v '^[-+]' | grep -v '^$'

Using the example above, this would output:

@interface SomeClass ()
@property (nonatomic, copy) NSString *someString;
@property (nonatomic, copy) NSDictionary *someDictionary;

Mark Pragmas

;mark expands to:

#pragma mark -

;public expands to:

#pragma mark - Public Methods

;private expands to:

#pragma mark - Private Methods

Declare and Initialize an Object using the Default Initializer

;new uses a fill-in for the type name and variable name:

%filltext:name=typename% *%filltext:name=varname% = [%filltext:name=typename% new];

If you enter NSMutableArray and array, this will yield:

NSMutableArray *array = [NSMutableArray new];

Key-Value Observing Done Right

I've long since lost where I got these, but it's the correct way to register for KVO notifications.

Declare a context variable static to the source file with ;kvocontext:

static void *kKVOContext = &kKVOContext;

Register for KVO notifications in the initializer, viewWillAppear, etc. with ;kvoadd:

[<#(id)#> addObserver:self forKeyPath:<#(NSString *)#> options:<#(NSKeyValueObservingOptions)#> context:kKVOContext];

Deregister from KVO notifications in dealloc, viewWillDisappear, etc. with ;kvoremove:

[<#(id)#> removeObserver:<#(NSObject *)#> forKeyPath:<#(NSString *)#> context:kKVOContext];

And, finally, declare the KVO notification hander with ;kvomethod:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    if (context != kKVOContext)
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

    if ([keyPath isEqualToString:<#(NSString *)#>])

Documents Directory

I used to have to look this up whenever I needed to use the documents directory. Now I use ;document:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *<#path#> = [documentsDirectory stringByAppendingPathComponent:<#filename#>];

The final NSString variable is the full path to a file in the documents directory.

Common Type Names

;nsa expands to NSArray

;nsd expands to NSDictionary

;nss expands to NSString

;nsma expands to NSMutableArray

;nsmd expands to NSMutableDictionary

;nsms expands to NSMutableString

These also work with the ;new snippet, above.


Reference the default NSNotificationCenter using ;dnc:

[NSNotificationCenter defaultCenter]

Make a new NSString by calling -stringWithFormat: with ;swf. The %key:tab% at the end highlights the format string placeholder:

[NSString stringWithFormat:@"<#format string#>", <#args#>]%key:tab%

Make a constant string whose value is equal to the variable name with ;cstr:

NSString *const %fill:name% = @"%fill:name%";

Xcode Paths

These are useful in the Terminal or in the Go to Folder dialog in the Finder.

;iossdks expands to:


;osxsdks expands to:


;simulator expands to:

~/Library/Application\ Support/iPhone\ Simulator

;archives expands to:


;deriveddata expands to:

Published August 12, 2014

The canonical Objective-C block syntax reference misses some cases that I use frequently. At the end of last year, as I was getting back into full-time Objective-C development, I made the following example file that covers every block usage I could think of. It is my go-to reference whenever I'm in doubt as to how to write a particular kind of block.

Published March 30, 2014

Here's another AppleScript I wrote. It would be great if Xcode would show the current Git branch and working directory status in the main window. Unfortunately, the only way to see the current branch is to select the Source Control menu. There's no quick way to see if you have uncommitted modifications.

I wrote this AppleScript, which I have bound to ⌥G using FastScripts. It pops up a notification showing the current branch and status.

This is a notification showing the master branch with no changes or additions:

Clean Working Directory

This is what it looks like when there are modifications:

Modified Files in Working Directory

And, this is the notification when there are modifications and additions:

Modified and Added Files in Working Directory

The script:

Published March 24, 2014

I'm on a bit of an AppleScript kick lately. It's a frustrating language to use as it's often counterintuitive. I'm constantly looking up the right syntax to do things. But, it's a great way to patch little annoyances you encounter in Mac software.

The latest annoyance involves Tweetbot image windows. While I'm reading my timeline, I click on lots of links and images. After a while, I find I have a ton of image windows left over.

There's no good way to close all of those windows without quitting and restarting the app. Holding down ⌥ and clicking on the Window menu shows Close All bound to ⌥W, but it doesn't work for me. The alternative is to click on each window and ⌘W on the keyboard, but who wants to do that?

I wrote a little AppleScript to do it. Tweetbot isn't strictly AppleScriptable, but using System Events and Accessiblity gets the job done. The script is a bit kludgy as the inner repeat loop fails after closing three or four windows. To get around it, I wrapped it in a try...on error block and repeat that until there's only one window left.

I've got this bound to ⇧W using FastScripts.

The script:

Older Posts