XCode file template for custom NSWindow subclass

14
Dec
0

This has been for a while now in my drafts and I wanted to polish it so it wouldn’t require as much editing as some previous tutorials. I hope you’ll enjoy reading this one as much as I enjoyed writing this. I present you – custom NSWindow template tutorial.

From time to time while programming you’ll have to draw custom window. If it’s more often than “from time to time” you’ll find yourself writing the same code again and again. Of course it’s easy to extract repetitive code into separate class and include that class in every project (or few times into the same project), but this still not the prettiest solution. Im suggesting you an approach that exploits XCode’s customization – template for custom class that you’ll be able to include into your projects anytime you need it. In this case – it’s custom NSWindow subclass.

So here’s how we’re going to achieve this:

  1. Create project in XCode where we will code a template for custom NSWindow. If you are really good with Objective C – you can code our custom class in any text editor (TextEdit, TextMate) or in an IDE of your choice.
  2. Create custom NSWindow class
  3. Replace hardcoded constants (class names) with identifiers
  4. Move created class files to a location where XCode can consider them as being custom template files

Creating XCode project

This part should be really clear. Create simple cocoa application project. Let’s name it “CustomWindowTemplate”.

New XCode project

Custom NSWindow subclass

Now we need to create the meat of our custom NSWindow class that will serve as template for future implementations. When I was googling around for custom NSWindow drawing I found this very useful and concise tutorial on how to easily draw custom NSWindow. I present you Matt Gallagher’s Cocoa With Love post “Drawing a custom window on Mac OS X“. I’d suggest to go through all of that tutorial for deeper understanding of how window drawing is done in Cocoa.

Once you’re done with the custom NSWindow class (you can download the prepared XCode project from the same tutorial page), you need to replace hardcoded class names with XCode identifiers, so that upon new class creation they would be replaced with your provided name.

Custom XCode identifiers

The identifier we are interested in most is «FILEBASENAMEIDENTIFIER». It plays the most important role as it’s the placeholder who’s value will be used for our newly created custom NSWindow class. Here’s the list of other interesting identifiers you may have a use for (like constructing the comment above the declaration of the class).

  • «FILENAME» – the actual file name that will be created (will be substituted for both .h and .m files);
  • «PROJECTNAME» – the name of the project you’re creating new custom window class;
  • «YEAR» – pretty much self explanatory;
  • «ORGANIZATIONNAME» – self explanatory as well. You can change that via defaults;

If you’re interested, the default one looks like this:

//
//  «FILENAME»
//  «PROJECTNAME»
//
//  Created by «FULLUSERNAME» on «DATE».
//  Copyright «YEAR» «ORGANIZATIONNAME». All rights reserved.
//

So the declaration of custom NSWindow class in our header template should look like this:

...
@interface «FILEBASENAMEASIDENTIFIER» : NSWindow {
...

Hence the declaration of the class in implementation template should look like this:

...
«OPTIONALHEADERIMPORTLINE»
 
@implementation «FILEBASENAMEASIDENTIFIER»
...

The «OPTIONALHEADERIMPORTLINE» identifier I haven’t mentioned is the one replaced with #import statement of custom class’s header file.

Now for almost-the-last step we need to create template’s meta-data file which is practically a simple plist with a few properties. Or you can just copy paste the following XML markup code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>MainTemplateFile</key>
	<string>class.m</string>
	<key>CounterpartTemplateFile</key>
	<string>class.h</string>
	<key>Description</key>
	<string>A custom NSWindow subclass.</string>
</dict>
</plist>

All tags and values should be self explanatory: we define two template files (one is the counterpart of the other, like .m and .h) and add a description that will be shown in XCodes “New File…” dialog window.

Final destination

Now open up finder and go (⌘ + ⇧ + G) to ~/Library/Application Support/Developer/Shared/Xcode. Create a folder named File templates (if it’s not already there). This folder will keep your all custom file template categories as folders. Go inside that folder and create Cocoa Class folder. This folder will serve as a “category” for custom Cocoa classes. Now for the final destination go to that newly created folder folder and create another one named Objective-C NSWindow subclass.pbfiletemplate (mind the “extension” of the folder). This is the final destination for all template-related files. Now move template meta-data file (the plist) together with your header and implementation files to that folder. Just to check – your final path for files should be this:

  • ~/Library
  • /Application Support
  • /Developer
  • /Shared
  • /Xcode
  • /File templates
  • /Cocoa class
  • /Objective-C NSWindow subclass.pbfiletemplate

Note that your header and implementation files must be named class.h and class.m accordingly.

Now if you’ve done everything correctly – fire up XCode and create a new project or open up any existing one. After that – try adding new file to your project. In new file dialog you’ll see this:

custom NSWindow subclass template

Now press next, type a name for your custom NSWindow subclass and you’re good to go!

Things not included here

As you may have noticed in the tutorial – this one does not include content view that fills the transparent window. Well, it’s not here ’cause it’s impossible so far to create two files out of template while creating “New File…” in a project (we’d need to create the subclass of NSView to fill our custom NSWindow). At least if it IS possible – I’m yet to find that out. Or if you know – please feel free to share that with me in the comments.

But there is still solution for that – you can create custom NSView class that does some simple drawing and create a template out of it using the technique above (by replacing the classnames with identifiers and writing template meta-data file).

Enjoy this article?

Consider subscribing to our RSS feed!

No Comments

No comments yet.

Leave a comment

RSS feed for comments on this post