Simply Hacking

Mac OS X and iOS Programming

Initial Release of MHConvore

| Comments

Just pushed the first cut of a small framework to connect with the newly launched chatservice Convore. In short Convore is an attempt to create a better way to chat than IRC and also support a web frontend while making it possible to connect with native clients.

The API will likely change a bit and it’s fresh out of the editor so might be a bit flaky still.

The API makes heavy use of blocks for actions initiated from your code and a client listener for notifications initiated from the server.

A small example of how you use the API, I will add a better example later.

1
2
3
4
@interface AppDelegate : NSObject <NSApplicationDelegate, MHConvoreClientListener> {
@private
    MHConvoreClient *client;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)connectToServer
{
    MHConvoreClient *client = [MHConvoreClient clientWithUsername:@"u" password:@"p"];
    client.listener = self;

    [client verifyAccount:^ (MHConvoreUser *user, NSError *error) {
        if (error == nil) {
            //   [self doSomething];
            [client listen];
        } else {
            NSLog(@"Error while verifying account: %@", error);
        }
    }];
}

/* Called when the client receives a new message */
- (void)newMessage:(MHConvoreMessage *)message
{
    NSLog(@"[%@]: %@", message.user.name, message.message);
}

To connect to Convore you first need to create an account through their website.

There still is work that needs to be done to it so feel free to fork and hack on it. For example there is currently no way to cancel the listener.

The code at Github

Code Separation Using Blocks

| Comments

This is a short blog entry to describe how you can use blocks to seperate a generic code from problem specific using blocks. Those that have been looking at Project Euler might recognize this problem description.

The program is supposed to calculate the sum of all even-valued Fibonacci numbers that doesn’t exceed a STOP_VALUE.

To keep the Fibonacci calculations generic I wanted to separate the problem specific logic from the code calculating the Fibonacci sequence. Blocks can be really helpful for that which is shown below.

1
+ sequenceWithBlock:^ void (NSInteger value, BOOL *stop);

This method accepts a block that is called for every Fibonacci number in the sequence until the blocks sets the stop flag. The problem specific code is then placed inside the block.

1
2
3
4
5
6
7
8
9
10
11
__block int total = 0;

[Fibonacci sequenceWithBlock:^ void (NSInteger value, BOOL *stop) {
    if (value > STOP_VALUE) {
        *stop = YES;
    }

    if (value % 2 == 0) {
        total += value;
    }
}];

Debug Method in Xcode

| Comments

I often find myself add a bunch of #ifdefs for code that I only want executed during the development but not in the shipped products. In order to make the code a bit easier to read I decided to make a small method that takes a C block (available in iOS 4.0 and Mac OS X 10.6) instead.

You would use it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Simple example of usage
 */

#include "debug.h"

int
main(int argc, **argv)
{
    debug(^ {
        // Your debug code here
    });

    return 0;
}

You can download debug.[ch] from GitHub and simply add them to your project. You also need to edit your project settings for the Debug configuration to set the DEBUG macro.

Project Settings Dialog

http://gist.github.com/534487

Spacedust Xcode Theme

| Comments

I decided it was time to create a new Xcode theme and created one that works well with dark backgrounds. It’s called Spacedust and should look good on most dark tints.

Feel free to grab it if you like it.

Spacedust.xccolortheme.zip

To install it, simply unpack it and place Spacedust.xccolortheme.zip in: ~/Library/Application Support/Xcode/Color\ Themes.

Core Animation Layered Clock

| Comments

I wanted to get into Core Animation a bit over the weekend and decided to write a simple digital clock. With the help from Richard I set out to hack it up and figured it might be useful for others just starting out with Core Animation.

Resulting App

After creating a normal Cocoa Application and setting up a custom view in Interface Builder it’s time to setup the layers that will make up the final interface. Make sure that you set the custom view to your class so that it is actually used:

Info panel in Interface Builder

Layers in Core Animation are built up as a tree where the layer you set to your view with setLayer: is the root layer. All other layers are added as sublayers to the root layer or another layer with addSublayer:. In the code snippets below backgroundLayer is my root layer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (CALayer *)setupLayers
{
    backgroundLayer = [self setupBackgroundLayer];

    [backgroundLayer addSublayer:[self setupClockFaceLayer]];
    [backgroundLayer addSublayer:[self setupBorderLayer]];
    [backgroundLayer addSublayer:[self setupGlossLayer]];

    return backgroundLayer;
}

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        clockTimer = [[ClockTimer alloc] init];

        [self setLayer:[self setupLayers]];
    }
    return self;
}

- (void)awakeFromNib
{
    [self setWantsLayer:YES];
}

ClockTimer is a simple class that updates the string displaying the time once a second. This string is available through the property outputString on the ClockTimer object.

As you can see the clock is built up from four different layers: The background layer, a clock face layer, a border layer and finally a gloss layer adding the nice shine.

The Background Layer:

The background layer is created as a CAGradientLayer to give the clock background the nice blue gradient. This layer type was added in 10.6 so it won’t work on earlier versions of Mac OS X but should be fairly straight forward to do manually.

In order to help with positioning of layers Core Animation comes with the notion of Layout Managers which can be added to a layer in order to layout its sublayers. The CAConstraintLayoutManager lets us set constraints on the layers sublayers in order to control how they are positioned. In this case the constraints will be set on the clock face to make it centered on the background.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (CALayer *)setupBackgroundLayer
{
    backgroundLayer = [CAGradientLayer layer];

    CGColorRef gradientColor1 = CGColorCreateGenericRGB(13.0f / 255.0, 116.0f / 255.0, 1.0, 1.0f);
    CGColorRef gradientColor2 = CGColorCreateGenericRGB(0.0f, 53.0f/255.0f, 126.0f/255.0f, 1.0f);

    NSArray *colors = [NSArray arrayWithObjects:(id)gradientColor1, (id)gradientColor2, nil];

    CFRelease(gradientColor1);
    CFRelease(gradientColor2);

    [(CAGradientLayer *)backgroundLayer setColors:colors];
    [backgroundLayer setCornerRadius:12.0f];

    CAConstraintLayoutManager *layout = [CAConstraintLayoutManager layoutManager];
    [backgroundLayer setLayoutManager:layout];

    return backgroundLayer;
}

The ClockFace Layer:

Core Animation comes with several layer types to help us with various tasks. One of these is the CATextLayer which like the name suggests, make it really easy to output text. It also makes it really easy to customize how the text is displayed by setting font and font size. Using the normal shadow properties from CALayer you can add a nice drop shadow on the text.

Using Cocoa bindings I connect the text layers string property with the outputString on my ClockTimer. This way the layer will automatically redraw itself everytime the timer updates the output string.

This is also where we setup the constraints mentioned above to make sure that the text is centered in relation to its super layer (in this case the background).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (CALayer *)setupClockFaceLayer {
    CATextLayer *clockFaceLayer = [CATextLayer layer];
    [clockFaceLayer bind:@"string" toObject:clockTimer withKeyPath:@"outputString" options:nil];
    [clockFaceLayer setFont:@"Menlo"];
    [clockFaceLayer setFontSize:60.0f];
    [clockFaceLayer setShadowOpacity:.9f];

    // Constrain the text layer in the middle
    CAConstraint *constraint = [CAConstraint constraintWithAttribute:kCAConstraintMidX
                                                          relativeTo:@"superlayer"
                                                           attribute:kCAConstraintMidX];
    [clockFaceLayer addConstraint:constraint];

    constraint = [CAConstraint constraintWithAttribute:kCAConstraintMidY
                                            relativeTo:@"superlayer"
                                             attribute:kCAConstraintMidY];
    [clockFaceLayer addConstraint:constraint];

    return clockFaceLayer;
}

The Border Layer:

There are likely other ways of doing this but by using a separate layer I can use built in functionality to draw a border around a layer. I make the layer slightly smaller than the background layer, set its corner radius to the same value used for the background and simply set it to draw its border with a white color.

1
2
3
4
5
6
7
8
9
10
11
- (CALayer *)setupBorderLayer
{
    CALayer *borderLayer = [CALayer layer];
    CGRect borderRect = CGRectInset([self frame], 8.0f, 8.0f);
    [borderLayer setCornerRadius:12.0f];
    [borderLayer setBorderColor:CGColorGetConstantColor(kCGColorWhite)];
    [borderLayer setBorderWidth:2.0f];
    [borderLayer setFrame:borderRect];

    return borderLayer;
}

Notice that I do not have to set any constraints here as I create the layer frame from simply shrinking the frame size on all sides which ensures it will be set in the middle already.

The Gloss Layer:

As a final touch I wanted to add the shine to give the clock a glossy look. The simplest way I could figure out to do this was to create a transparent image in Photoshop and setup the layer to draw it. Optimally it should be generated in code or at least use a scalable image to make the clock resizable without loosing any quality in the gloss layer.

Even if we set the same corner radius as the background layer the layer will happily draw the image outside of this unless we call setMasksToBounds to ensure that it doesn’t draw the image outside of the rounded corners.

setupGlossLayer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (CALayer *)setupGlossLayer
{
    CALayer *glossLayer = [CALayer layer];
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"clock-gloss" ofType:@"png"];
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];

    CGImageSourceRef glossySource = CGImageSourceCreateWithURL((CFURLRef)fileURL, NULL);
    CGImageRef glossyImage = CGImageSourceCreateImageAtIndex(glossySource, 0, NULL);
    CFRelease(glossySource);
    [glossLayer setContents:(id)glossyImage];
    CFRelease(glossyImage);

    [glossLayer setOpacity:0.8f];
    [glossLayer setCornerRadius:12.0f];
    [glossLayer setMasksToBounds:YES];
    [glossLayer setFrame:[self frame]];

    return glossLayer;
}

Finally I subclassed NSWindow in order to turn off the window decoration and shape the window as the background layer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (id)initWithContentRect:(NSRect)contentRect
                styleMask:(NSUInteger)aStyle
                  backing:(NSBackingStoreType)bufferingType
                    defer:(BOOL)flag
{
    self = [super initWithContentRect:contentRect
                            styleMask:NSBorderlessWindowMask
                              backing:bufferingType
                                defer:flag];
    if (self) {
        [self setOpaque:NO];
        [self setBackgroundColor:[NSColor clearColor]];
        [self setMovableByWindowBackground:YES];
        [self setLevel:NSPopUpMenuWindowLevel];
    }

    return self;
}

NSBorderlessWindowMask makes the window draw without the border and setOpaque together with setting the background color to [NSColor clearColor]. Using the NSPopUpMenuWindowLevel ensures that the clock is always on top of other windows.

I hope you find this helpful and please make sure to subscribe to my feed if you did. I’ll do my best to answer any questions you might have in the comment section below.

The full source as an Xcode project can be browsed at: Github or downloaded.

Reversing an Array in Objective C

| Comments

Was looking for the best way to reverse an array in Objective C and stumbled over this solution that might not be obvious to everyone (wasn’t to me at least).

1
NSArray *reversedArray = [[array reverseObjectEnumerator] allObjects];

Macruby Support in Any Cocoa Application

| Comments

Yesterday I published a post about Cocoa Prototyping with Webview and today I found out about Macruby thanks to @sarnesjo. Already looking for ways of prototyping in Cocoa it’s hard to not find Macruby very interesting.

Macruby turns out to be a very powerful tool for prototyping (as well as writing entire applications in) as it fits perfectly fine in a normal Objective-C code base. What I wanted was something like this:

1
2
3
4
5
6
7
8
9
10
class SimpleController
    attr_accessor :label
    attr_accessor :button
    attr_accessor :my_view

    def buttonPressed(sender)
        label.setStringValue("I am (im)pressed!")
        my_view.backgroundColor = NSColor.redColor
    end
end

Where the view :my_view is implemented in Objective-C.

Here are the simple steps I used to hook it into a normal Xcode Cocoa project.

First of all, install Macruby which is as easy as downloading the zip-file from the website and run the installer.

In order to link to the Macruby framework you need to use garbage collection in your project, if you aren’t already you enable it in the project inspector:

Set the project to use Garbage Collection

Next you need to make your project link against the Macruby framework:

Add the Macruby framework

That’s it for the project settings, let’s hook it up in the code. When you use the built-in project template for a Macruby project a small Ruby file called rb_main.rb is created for you. Since I’m using a generic Cocoa application template I needed to create this file and simply copied the file into my new project (its code below). It loads all Ruby files in your bundle and starts the Cocoa main loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Loading the Cocoa framework. If you need to load more frameworks, you can
# do that here too.
framework 'Cocoa'

# Loading all the Ruby project files.
dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation
Dir.entries(dir_path).each do |path|
  if path != File.basename(__FILE__) and path[-3..-1] == '.rb'
    require(path)
  end
end

# Starting the Cocoa main loop.
NSApplicationMain(0, nil)

To start the actual Ruby interpreter the file main.m needs to be modified. Since the Ruby code now starts the Cocoa main loop we no longer need to do that in main. Main.m simply becomes:

1
2
3
4
5
6
#import <MacRuby/MacRuby.h>

int main(int argc, char *argv[])
{
    return macruby_main("rb_main.rb", argc, argv);
}

With these changes you can now start writing code in either Ruby or Objective-C within the same project. Here are the files I ended up with in my very small example.

Example Files

The final application simply shows a small window with a button:

Example window

Make sure to watch the great introductionary screencast then download the example project and get started tinkering.

Example project

If you find this as cool and useful as I did, let me hear about it!

Edit: Be sure to read Laurents comment below for an alternative way of loading your Ruby files into your application.

Cocoa Prototyping With Webview

| Comments

While Interface Builder makes it really easy to quickly put together and test the overall design of your user interface it doesn’t help much when it comes to its overall flow. In any non-trivial application you are likely to have some custom views or view switching.

For example, say that you want to try out whether it makes sense to use a source list in order to navigate the application and have your content view switch based on what you select in it.

Wouldn’t it be great if you could try this without having to implement all the code necessary to display and navigate the source list and other views. Using HTML for prototyping can be a powerful, quick and easy solution that is easily available to Cocoa developers.

In order to make it even easier I created a WebView subclass called PrototypeView that displays a piece of HTML and sends a message to its delegate when the user clicks a link.

To give an idea of what it does, take a look at the following screenshot showing a basic prototype UI consisting of two suchs views embedded in a split view.

Prototyped UI, using PrototypeView

Using the PrototypeView is easy.

Step 1: Mock up the UI in Interface Builder

Using Interface Builder, create the UI you want and put custom views where you want to prototype using the PrototypeView.

Setting class to PrototypeView

I used a class called AppController with two outlets to the prototype views by creating an NSObject subclass and set it up in Interface Builder by dragging an NSObject from the library and setting the class to AppController like above.

Step 2: Hooking the view up in the AppController

Back in XCode I create a subclass of NSObject called AppController and setup the two prototype views in its awakeFromNib by using the two method calls setPrototypeDelegate and loadBundleFile. In my example I used two prototype views called sidebarView and contentView and will use the AppController as my delegate.

1
2
3
4
5
6
7
8
- (void)awakeFromNib
{
    [sideBarView setPrototypeDelegate:self];
    [sideBarView loadBundleFile:@"sidebar"];

    [contentView setPrototypeDelegate:self];
    [contentView loadBundleFile:@"content1"];
}

Step 3: Prototype in HTML

Starting the application at this point will cause it to load the files sidebar.html and content1.html and display them. Now that the files are being loaded you can implement the prototyped UI portions in the HTML files. Here is the content of sidebar.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
  <head>
    <link rel="stylesheet" href="sidebar.css" type="text/css" />
  </head>
  <body>
    <ul>
      <li><p class="header">LIBRARY</p>
        <ul>
          <li><a href="method:showViewOne">Initial View</a></li>
          <li><a href="method:showViewTwo">Second View</a></li>
        </ul>
      </li>
    </ul>
  </body>
</html>

Step 4: Adding the methods in AppController

Notice the special links to method:showViewOne, clicking this will make the PrototypeView look if its delegate responds to showViewOne and send the message to it if it does.

1
2
3
4
5
6
7
8
9
- (void)showViewOne
{
    [contentView loadBundleFile:@"content1"];
}

- (void)showViewTwo
{
    [contentView loadBundleFile:@"content2"];
}

That’s it, happy prototyping!

For a closer look you can see the PrototypeView source code or download the example project I used as a tarball.

I’d love any feedback on how to improve this and possibly even supporting using JavaScript to communicate both ways with the HTML view in order to let the application update the views dynamically.

Blogging at Github and Simply Hacking

| Comments

20 Apr 2009 – Stockholm

Decided to move my blog to a simpler solution by using Github and the nice Jekyll site generator by Tom Preston-Werner.

Still need to tweak the stylesheetes a bit to not be a total rip off from Toms (which he is kind enough to let others use) but I definitely like the clean design.

Really looking forward to a simpler blog system where I don’t need to manage an SQL database and keep the software up to date. Comments are done through Disqus.