Leap into the future with Clear for Mac

Posted by Nik

Just before Christmas, the Clear for Mac team gathered around a box that had arrived from San Francisco. Inside, was a rather intriguing piece of hardware. Over the past couple of months, we’ve been stealthily working on adding support for this futuristic piece of hardware to Clear for Mac - and today we’re thrilled to announce that Clear for Mac will soon support the rather incredible Leap Motion controller.

We’re still hard at work finishing all the interactions for Clear + Leap, however to give you an idea of how you’ll be able to use Clear with the Leap Motion controller, here’s a short video showing some of our work so far.

Stay tuned for news about this next Clear for Mac update by following Clear on Twitter, and if you’ve not already picked up a copy of Clear for Mac you can do so for just $6.99 on the Mac App Store!

Working with Date and Time

Posted by James

It’s highly likely that somewhere in your app you may need to work with dates and times; whether that be parsing, displaying or performing calendrical calculations. There are some important considerations to make and most certainly a few gotchas to watch out for. This post aims to give an overview of some of the Cocoa classes available to you and some tips and tricks on working with dates and times.

At Your Disposal

NSDate

The NSDate class is essentially a wrapper for an NSTimeInterval. This NSTimeInterval is nothing more than a double used to specify the number of seconds since the reference date in time. As a double it yields sub-millisecond precision over a range of 10,000 years. An NSDate represents a point in time in relation to this reference date. The references date remains a fixed point in time but can be interpreted differently depending on the calendar.

  • Gregorian calendar, 1 January 2001 00:00:00 +0000.
  • Buddhist calendar, 1 January 2544 00:00:00 +0000.

NSTimeZone

A time zone in the world is a geopolitical region where by the government have defined a set of rules for how local time should be calculated from the reference time zone of the world (GMT). In it’s simplest terms this is just an offset by a number of seconds, but there is a lot more that NSTimeZone accounts for. Daylight saving time is one of these as well as the fact that governments can changes the rules of their time zone between different years.

NSCalendar

There are many calendars in the world; Gregorian, Buddhist, Japanese, etc. Each define arithmetic properties such as the number of months in a year and the first weekday. An NSCalendar knows the mapping of an NSTimeInterval to and from a calendar date and also how to perform calendrical calculations such as “what’s the day 10 days from now”.

NSLocale

An NSLocale encapsulates a set of default regional settings for the current user. However the user can override these settings so you should not assume them. The settings define the way date and time should be formatted when presented to the user.

NSDateComponents

An object containing a set of calendar components such as month, day, hour, etc. It’s good to remember that an NSDateComponents can represent both an absolute and relative time.

  • Absolute, 14:45 in the afternoon.
  • Relative, 14 hours and 45 minutes.

You can use an NSCalendar object to convert an NSDateComponents to an NSDate, which kindly handles unit roll overs for you. For example an instance with components 2012 years, 13 months and 5 days becomes 5th January 2013.

NSDateFormatter

An NSDateFormatter is used for converting dates both to and from human-readable form, as well as machine readable form, i.e. a string with a schema. New objects are initialised with the locale settings of the current user. There are some predefined format styles for varying length outputs, e.g. NSDateFormatterShortStyle, NSDateFormatterLongStyle, or you can customise the output with a format string.

Tips & Tricks

Calendrical Calculations

The most important tip I can give you is to use the system algorithms for calendrical calculations. Do not try and write your own algorithms, as there are a lot of specific cases to account for such as:

  • The leap day in the Gregorian calendar, 29th February. Happens mostly every four years, the next omitted leap year is 2100.
  • The leap month in the Hebrew Calendar. Months are numbered 1-13 and 7 can be a leap month.
  • Time zone transitions. A forward transition causes an hour skip and a backward transition causes an hour to occur twice. In the UK the daylight saving time happens at 01:00 or 02:00 where as in Brazil the transition is at midnight.
  • Dateline transitions. In 2011 Samoa had a time zone change and moved from one side of the international date line to the other. At the end of the day on 29th December 2011, it became 31st December 2011, skipping 30th December 2011 entirely.
  • Japanese Imperial Eras. When a new Emperor comes in to power a new era begins and the year is set to 1. This means that a year can be set back to 1 during any point in the current year.

It’s also favourable to avoid stress boundaries. If you only care about the date and not the time set it to noon instead of the default of midnight. Similarly if you only care about the time and not the date use the reference date and set your time.

Another important fact is that 1 day does not always equal 86,400 seconds! If for instance you did [date dateByAddingTimeInterval:86400] where date is 30th March 2013 11:50 PM, you will get a results of 31st March 2013 00:50 AM. The issue here being that the daylight saving time transition has occurred but was not accounted for. Instead create an NSDateComponents and set the day components [dateComponents setDay:1]. Now you can add the components and daylight saving time transition is correctly handled.

NSDate *start = ...; // start: 30th March 2013 11:50 PM
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:1];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *end = [calendar dateByAddingComponents:dateComponents toDate:start options:0];
// end: 31st March 2013 11:50 PM

When performing calendrical calculation you should always work relative to your starting date and not to any intermediate date. For example taking 31st January, adding one month, and then adding a further month to the result would mean the following.

31st January -> 28th February -> 28th March

This is because there is no 31st February so the result returned is the last day of February. So when adding an additional month to this date the day number is preserved and we’re returned 28th March.

So as mentioned, always work relative to your starting date, and in this example add two months to 31st January to get 31st March.

31st January -> -> 31st March

Displaying Dates

To display a date to the user you’ll use an NSDateFormatter. Remember that these are always initialised with the locale settings of the current user, as well as with any customisations the user may have made.

Some user preferences override even a specifically set date format, for instance a user may prefer to see a 24-hour clock format. Setting the date format may seem like the correct way to get the output you’re after. However although the following is a valid date format for here in the UK, it isn’t for China.

[dateFormatter setDateFormat:@"dd/MM/yyyy"];

It’s always best to use the predefined format styles which will be based on the locale settings of the current user, or what they have customised in their system preferences.

[dateFormatter setDateStyle:NSDateFormatterShortStyle];

When these format styles don’t suit and you need to use a date format, use the method +dateFormatFromTemplate:options:locale: to generate a locale specific format.

NSString *format = [NSDateFormatter dateFormatFromTemplate:@"EdMMM" options:0 locale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:format];
  • en_US locale generates @"EEE, MMM d" format, “Wed, Feb 20”.
  • de_DE locale generates @"EEE, d. MMM" format, “Mi., 20. Feb”.

This also works perfectly for the AM/PM of time.

NSString *format = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
[dateFormatter setDateFormat:format];
  • en_US locale generates @"h a" format, “6 PM”.
  • de_DE locale generates @"HH 'Uhr'" format, “18 Uhr”.

Parsing Dates

When parsing a date make sure you explicitly configured your NSDateFormatter with the correct calendar to ensure you get the correct result.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[dateFormatter setCalendar:calendar];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:@"2013-02-20"];

When parsing fixed-format dates like those from a web server, setting the date formatter locale to en_US_POSIX often works well. This locale is specifically designed to yield US English results regardless of both user and system preferences and will remain fixed even if the US changes the way it formats dates in the future.

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:locale];

Working with Time Zones

Ensure you set the appropriate time zone when storing and parsing a date. The time in the string 2013-02-20 13:00:00 is 1pm in GMT. But if the time zone is not correctly set and a user in New York parsing the date it will be interpreted as 1pm EST, the equivalent of 6pm GMT.

[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:@"2013-02-20 13:00:00"];

Working with Week-based Calendars

All calendars can be interpreted in a week-based fashion; a cyclic period of 7 days. There are two properties that define a week-based calendar.

  • The weekday which is the beginning of the week (and year).
  • Minimum number of days a straddling week needs in the new year to be considered the first week of that new year.

Below illustrates the different ways, including in a week-based fashion, to represent the date 20th February 2013 in the Gregorian calendar. Note: Weekday 1 is a Sunday.

  • {Year, Day} : {2013, 51}
  • {Year, Month, Day} : {2013, 2, 20}
  • {YearForWeekOfYear, WeekOfYear, Weekday} : {2013, 8, 4}

Do not mix an ordinary year number with week-based components, nor a week-based year number with ordinary components. For week based use the following NSCalendar component types.

NSWeekOfYearCalendarUnit
NSWeekOfMonthCalendarUnit
NSYearForWeekOfYearCalendarUnit

Also when using a date format string using the correct format is important.

  • @"YYYY" is week-based calendar year.
  • @"yyyy" is ordinary calendar year.

Unit Lengths

Finally NSCalendar has some methods to determine unit lengths. For instance if in your application you want to draw a calendar, you’d use the following method on your calendar object to determine how many months to draw.

NSRange months = [calendar maximumRangeOfUnit:NSMonthCalendarUnit];

You can ask for a range too, so you could use the following to determine how many days are in the month of the specified date. This also means you don’t need to hard code a leap year algorithm yourself.

NSRange days = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];

There are a lot of complexities in date, time and calendrical calculations. Make sure you let the Foundation framework do all the heavy lifting for you and you don’t try and write your own algorithms. I hope you’ve been able to pick up a few tips and tricks and if you’ve anything else to add give me a shout on Twitter.

Building an FTP and HTTP Server

Posted by Keith

When we moved in to our new office last year we wanted to connect our motion camera to hubot so that we could pull images from it into our Campfire chat on demand, because it’s cool.

We used the camera from the café at our old office which has support for sending periodic snapshots to a server via SMTP and FTP. It was originally configured to send the image files over the public Internet via FTP to a server outside the office network, these files were then served by an HTTP server configured to read files from the same directory.

The problem we encountered with this setup was that the FTP server would write to the same file which the HTTP server was reading from and there was no coordination between the processes. When you requested the image while the FTP server was mid-write, the image you’d receive in response would be in a partially written state and appear corrupt.

Corrupted image capture

To avoid this both processes would have had to; share a file system that supported file locking, and been built with support for a locking mechanism such as lockf. Alternatively if their shared file system supported mandatory locks, only one of the processes would have to support and use file locking - the other process attempting to use the file would have its I/O blocked waiting for the mandatory lock to be released, dependent on the type of operation it was attempting with the file. For an example of a file locking API specific to OS X see Damien’s post which demonstrates File Coordination.

Another possible solution to prevent simultaneous reading and writing to the same file, that is to ensure the HTTP server could only ever read complete files from its directory, would have been to configure the FTP server to write new files to a separate directory on the same file system first and then add a link to the original directory pointing to the new file.

Rather than continuing to run the service on the public Internet and having to either, adapt the servers to coordinate their file access or workaround a lack of coordination, I decided to build an application which would run both an FTP and HTTP server in the same process, sharing an atomic in-memory file system. I had already built an Objective-C HTTP server a while ago so I just needed to build the FTP support. I started with RFC 959 and subsequent updates and was pointed to http://cr.yp.to/ftp.html by my friend Mike Abdullah. I added support for FTP commands incrementally using a combination of Transmit and the FTP camera itself to test out functionality.

The FTP server is bare bones and only supports a few commands, but it’s interoperable enough for what we need. The HTTP server responds to requests by reading files from the file system and includes a small dynamic resource which matches a path with a “/latest” suffix and redirects to the location of the latest file in that file system directory (this is currently determined by sorting the directory contents by name numerically rather than by date).

The project is camera_server. Retrieving the images from it over our local network is crazy fast, and this time they are always atomic copies. The first version of the file system suffered from poor performance which limited its practical usage to less than a thousand or so images, my next post will cover how I tuned its performance to support 250K images.

Block Debugging

Posted by Damien

As a software engineer, a working day can be divided into three main areas:

  1. Writing code: the easy part. If you know your frameworks, it’s really just a matter of putting your thoughts on “paper”.
  2. Designing interfaces: the hard part. Even though writing code is not so hard, writing reusable, easy to read and extend code is much harder.
  3. Debugging: the fun part. Stopping the execution of a program and inspect its internals.

I’d say that only 40% of my day is spent writing code, 30% designing and a good 30% debugging.
Of course I include in debugging much more than simply stepping through my own code hunting for bugs.

When stepping through instructions in the debugger one often encounters an instance of __NSGlobalBlock__, __NSStackBlock__ or __NSMallocBlock__ as argument to a method or simply being invoked. Inspecting what is happening in that a block might seem daunting at first sight but if one remembers that a block is really nothing more than a simple struct containing a function pointer, things get a bit easier.

Calling conventions

Before diving into it we need to talk about calling conventions. In this article I will be discussing the x86-64 instruction set which is what processors on most Mac computers use. This is not what ARM processors on iOS devices use but it shouldn’t be too hard to translate, the underlying concept is not much different.

The main piece of documentation one needs is the System V Application Binary Interface - AMD64 Architecture Processor Supplement that used to be available online but has since seemed to be removed. I have taken the liberty to host a version I have on our website so that it is accessible.

In order to inspect function arguments when stepping through instructions in the debugger, one needs to know where the various arguments are actually located, in the registers or on the stack. The calling convention for x86-64 is as following:

Calling convention registers on x86-64

The remaining arguments are placed on the stack. One should also know that return values are located in the accumulator register %rax. Note that for simplicity we won’t discuss floating points that would involve vector registers or functions that return a struct (in this case the return value is located somewhere else, likely on the stack, and its address is passed in %rdi, the remaining arguments being in the following registers, as per the calling convention).

Another key concept is preservation. Some registers are preserved across function calls, which means that the value they store will not change after a call instruction. They might be mutated during the function execution but they have to be restored to their original values so that they don’t appear changed from a caller perspective. This is usually why you see a number of push and pop instructions in a function prologue and epilogue, the idea being storing the state of the registers before and restoring it after the function execution. All the registers used for passing arguments are, by their very nature, not preserved.

So, as an example, if one inspects the various registers just before a call instruction for the following function

int function(int firstArgument, int secondArgument);

one would find firstArgument in %rdi and secondArgument in %rsi. By stepping over the call instruction, one would then find the return value in %rax.

But what about Objective-C methods? Well, as we know, an Objective-C message send is turned by the compiler into an objc_msgSend function call. The objc_msgSend function definition can be found in the Objective-C Runtime open source project and is

void objc_msgSend(void /* id self, SEL op, ... */ )

Thus, an Objective-C method becomes an objc_msgSend function call where the first argument is the receiver and the second argument the selector. The remaining arguments are simply following (The reason for the function taking void is to prevent using objc_msgSend without a cast, so that the compiler can use the correct calling convention at the call site). Similarly as with a plain function, the return value for an Objective-C method will be placed in %rax.
It is important to note that the runtime uses a few additional functions for sending messages, mainly for special cases such as messaging super, methods that return floating-point values or structs. However we won’t be discussing these here.

So, taking the following method as an example, the compiler will transform it into a function call:

- (NSString *)substringToIndex:(NSUInteger)idx;

((void (*)(id, SEL, NSUInteger))objc_msgSend)(self, @selector(substringToIndex:), idx)

This means that just before the call instruction, the receiver self can be found in %rdi, the selector in %rsi and the method first argument in %rdx. The return value (a pointer to an NSString object) will be located in %rax upon return of the function.

Block structure

With all this in mind, we can now get back to our block discussion. The LLVM project has a very useful page for the Block Implementation Specification. The libclosure Open Source page is also very useful if one wants to know more about Apple’s block implementation. One key part is the definition of the structure of a block:

struct Block_literal_1 {
    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
    int flags;
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor_1 {
        unsigned long int reserved; // NULL
        unsigned long int size;         // sizeof(struct Block_literal_1)
        // optional helper functions
        void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
        void (*dispose_helper)(void *src);             // IFF (1<<25)
        // required ABI.2010.3.16
        const char *signature;                         // IFF (1<<30)
    } *descriptor;
    // imported variables
};

The first member isa is interesting since it is the reason why a block is after all an Objective-C object. After a flags integer and a reserved member we can find the actual function pointer void (*invoke)(void *, …);. The last member is a reference to a Block_descriptor_1 struct that contains additional data such as a copy and dispose function pointers, a size and a signature.

It is important to notice that the first parameter of the invoke function is a pointer, leading us to hint that this is actually the block itself, similarly to the receiver being the first argument of the objc_msgSend function. If only this argument was easy to get from within a block body this would make recursive blocks less ugly and error prone, in particular when using ARC.

In practice

Following is a simple sample program that we will use in order to inspect a block in the debugger:

// clang -framework Foundation -fobjc-arc -o block block.m

#import <Foundation/Foundation.h>

@interface HelperClass : NSObject

- (void)doThingWithBlock:(BOOL (^)(NSString *arg1, NSInteger arg2))block;

@end

@implementation HelperClass

- (void)doThingWithBlock:(BOOL (^)(NSString *arg1, NSInteger arg2))block
{
    block(@"Oh Hai", 22);
}

@end

int main(int argc, char **argv)
{
    @autoreleasepool {
        HelperClass *object = [HelperClass new];

        NSInteger capturedInteger = 2;

        [object doThingWithBlock:^ BOOL (NSString *arg1, NSInteger arg2) {
            NSInteger someInteger = arg2 + capturedInteger;

            printf("%p %li\n", arg1, someInteger);

            return YES;
        }];

        return 0;
    }
}

Compile the code and launch the program in the debugger by running

$ clang -framework Foundation -fobjc-arc -o block block.m
$ lldb block

Thus in LLDB, set a breakpoint on the method call and run the program

(lldb) breakpoint set --name "-[HelperClass doThingWithBlock:]"
(lldb) run

We should now hit our breakpoint in the doThingWithBlock: method. We have stopped execution at the very start of the method implementation. The very few first instructions, a series of push and mov are the function prologue and take care of storing the value of registers that should be preserved by pushing them on the stack.
As we saw earlier, if we print the content of the above mentioned registers we should be able to retrieve our arguments.

(lldb) po $rdi
$2 = 4296049056 <HelperClass: 0x1001081a0>
(lldb) p (char *)$rsi
(char *) $3 = 0x0000000100000ef2 "doThingWithBlock:"
(lldb) po $rdx
$4 = 140734799804432 <__NSStackBlock__: 0x7fff5fbff810>

Note that here we used the convenience that selectors are currently just strings. This might not always be the case though so a more robust solution would be to actually get the string representation of a selector by mean of the function const char *sel_getName(SEL sel) from the runtime. This function currently returns the selector casted to (const char *) but again this could easily change in the future.

We are mostly interested about the first method argument (the third argument of the objc_msgSend function) which happens to be a stack block. Now, obviously we know exactly what the arguments, return value and body of this block are since we wrote it, but think if you were stepping through framework code and you find such an instance, you would have no idea. And from experience, the actual interesting bits often happen to be in that very block. Well, this is unfortunately where most people would stop investigating but it is also exactly where any debugging aficionado starts to have some fun!

As we mentioned above, we are mainly interested in knowing two things from the block:

  • the body of the invoke function
  • the block signature

Invoke function

Let’s start with the invoke function. We saw in the block structure that the invoke function pointers is the fourth member in the struct. We previously printed the address of the block itself so if we manage to infer the address of the function pointer it should be trivial to disassemble it.

Assuming a 64-bit system, we know exactly the size of each member in the struct. We are only interested in members positioned above the function pointer.

Block struct members size

We can thus conclude that the function pointer is positioned 16 bytes down the struct.
LLDB has a handy tool to read from the memory at a particular address of the process being debugged. Let’s read the memory at the block address, nicely formatted by chunks of 8 bytes (the size of a pointer on 64-bit)

(lldb) memory read --size 8 --format x 0x7fff5fbff810
0x7fff5fbff810: 0x00007fff76b420e0 0x0000000040000000
0x7fff5fbff820: 0x0000000100000de0 0x0000000100001190
0x7fff5fbff830: 0x0000000000000002 0x0000000000000002
0x7fff5fbff840: 0x00000001001081a0 0x00007fff5fbff880

As previously said, the function pointer is located after 16 bytes of content in the struct so we can conclude from the memory reading that the function address itself is 0x0000000100000de0.
If we try to disassemble from this address we should hopefully get the first few instructions of this function.

(lldb) disassemble --start-address 0x0000000100000de0
block`__main_block_invoke:
    0x100000de0:  pushq  %rbp
    0x100000de1:  movq   %rsp, %rbp
    0x100000de4:  subq   $64, %rsp
    0x100000de8:  movq   %rdi, -40(%rbp)
    0x100000dec:  movq   %rsi, %rdi
    0x100000def:  movq   %rdx, -48(%rbp)
    0x100000df3:  callq  0x100000e68               ; symbol stub for: objc_retain
    0x100000df8:  leaq   208(%rip), %rdi           ; "%p %li\n"

One could now try to disassemble further instructions by guessing an --end-address or simply set a breakpoint at the address of the first instruction and step through.

Block signature

Now that we managed to disassemble the actual block invoke function, it would be nice to know the block signature. We could probably infer them from the content of the register in the function prologue but there is a more solid version to get them.
You might have notice the signature string in the descriptor struct in the block. Now if we could get it we could surely create an NSMethodSignature from it.

First thing first, we need to get to the actual descriptor struct. This struct is hold by reference (probably so that its content can be changed along the line without having to change the block definition itself). The descriptor struct pointer address is positioned just after the function pointer which we know to be 8 bytes sized. From our memory read above we can deduce that the its address is 0x0000000100001190.

However, it is not given that the descriptor struct will actually hold a signature. Luckily, the block has a flags mask that gives us some hints about it. The block specification documents the flags in use in the mask as

enum {
    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
    BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
    BLOCK_IS_GLOBAL =         (1 << 28),
    BLOCK_HAS_STRET =         (1 << 29), // IFF BLOCK_HAS_SIGNATURE
    BLOCK_HAS_SIGNATURE =     (1 << 30),
};

The flags integer happens to be the third member in the block struct. Reading the memory from the block address formatted in chunks of 4 bytes (the size of an integer on 64-bit) we find out the flags as 0x40000000:

(lldb) memory read --size 4 --format x 0x7fff5fbff810
0x7fff5fbff810: 0x76b420e0 0x00007fff 0x40000000 0x00000000
0x7fff5fbff820: 0x00000de0 0x00000001 0x00001190 0x00000001

We can quickly check that ((0x40000000 & (1 << 30)) != 0) so we indeed have a signature.

Note that the documentation states that not every block has a signature. From my experience though, both global blocks (blocks that happen to not capture any surrounding variable and thus optimised to be in a fixed global location rather than created on the stack) and stack blocks (and malloc blocks by extension) do indeed have an extensions.
A quick look at the Clang source for the block emitter (see in particular the implementation of the CodeGenFunction::EmitBlockLiteral and buildGlobalBlock functions in CGBlocks.cpp) does show that any block (even global blocks for which the block literal emission function take a fast path) has the BLOCK_HAS_SIGNATURE set in its flags. We can thus be quite confident that blocks in code built with Clang will have a signature.

In order to find the address of the signature variable we also need to figure out which other optional members of the descriptor struct are actually populated (these two members being copy_helper and dispose_helper). In our case ((0x40000000 & (1 << 25)) == 0) so out block doesn’t have a copy and dispose helper function pointers.

So let’s summarise: the signature string pointer will be positioned after two unsigned long variables in the descriptor struct. An unsigned long being 8 bytes on 64-bit, we expect the signature pointer to be 16 bytes below. Let’s inspect the memory at the descriptor address and print the (accordingly casted) string.

(lldb) memory read --size 8 --format x 0x0000000100001190
0x100001190: 0x0000000000000000 0x0000000000000028
0x1000011a0: 0x0000000100000ed7 0x0000000100000eef
0x1000011b0: 0x0000000000000000 0x0000000000000000
0x1000011c0: 0x0000000000000000 0x0000000000000000

(lldb) p (const char *) 0x0000000100000ed7
(const char *) $8 = 0x0000000100000ed7 "c24@?0@8q16"

You might think this is junk but it is actually a signature! We can easily find out by creating an NSMethodSignature from it:

(lldb) po [NSMethodSignature signatureWithObjCTypes:"c24@?0@8q16"]
$9 = 0x000000010010b060 <NSMethodSignature: 0x10010b060>
    number of arguments = 3
    frame size = 224
    is special struct return? NO
    return value: -------- -------- -------- --------
        type encoding (c) 'c'
        flags {isSigned}
        modifiers {}
        frame {offset = 0, offset adjust = 0, size = 8, size adjust = -7}
        memory {offset = 0, size = 1}
    argument 0: -------- -------- -------- --------
        type encoding (@) '@?'
        flags {isObject, isBlock}
        modifiers {}
        frame {offset = 0, offset adjust = 0, size = 8, size adjust = 0}
        memory {offset = 0, size = 8}
    argument 1: -------- -------- -------- --------
        type encoding (@) '@'
        flags {isObject}
        modifiers {}
        frame {offset = 8, offset adjust = 0, size = 8, size adjust = 0}
        memory {offset = 0, size = 8}
    argument 2: -------- -------- -------- --------
        type encoding (q) 'q'
        flags {isSigned}
        modifiers {}
        frame {offset = 16, offset adjust = 0, size = 8, size adjust = 0}
        memory {offset = 0, size = 8}

If all this is Greek to you I suggest reading the Type Encodings in the Objective-C Runtime Programming Guide.

What this says in English is simply: a function that returns a char (aka a BOOL), takes three arguments, a block as first (which is our block reference), a reference to an object as second (our NSString) and a long long as third (the NSInteger).

We were then able to find the signature of a given block and disassemble its invoke function. See, debugging is fun!

If you have any comments, you can leave them below or contact me on Twitter.

How to Produce an App Promo Video.

Posted by Rob

In a recent blog post, Dan talked about promo videos as a great way to build hype for your new app. Between the Clear for iPhone and Clear for Mac promo videos, we’ve had over 1.3 million plays - and lots of people have asked how we produced them, so I thought I would share the details on what it takes to produce a video.

Remember: once your app is live on the App Store the majority of users will only ever see the copy and screenshots you prepare for the App Store. As a result, the video is more than just a teaser - it's an opportunity to show off the things that a screenshot cannot.

1. Hire A Director

It’s entirely possible to create a great video in-house on a shoestring budget, however it’s worth considering the amount of time a video can take away from app development, and that the quality of the production which will be directly associated with the quality of your app. Other factors to consider are the expense of hiring camera equipment and lighting, post production and the knowledge of how to get the best use of all this kit.

Expert camera skills

For both Clear videos we used Mike Prior, a London based Director and Editor from NTSH. In total it cost around £2,500 (including equipment) to hire Mike to film and edit.

If you’re stuck for contacts to help produce a video, you might want to check out Startup Videos - if a particular video catches your eye it might be worth contacting the startup directly to find out who produced the video.

2. Storyboard

Before you start storyboarding, you should definitely spend some time prioritising what you want to show off. You don’t want the video to be too long, and we aim for our videos to be around the 60 second mark. Start by drawing out a scene by scene sketch of how things will look on screen, with a detailed synopsis of what’s going on beneath - the more detail the better. We also found it useful to roughly set up each scene at Realmac HQ and take photos so we could begin to visualise how it may look. Your storyboard is the foundation of your video, so make sure you spend time getting this part right.

Get the entire app team together and go through every step of the storyboard - rewriting it into a step by step text document of what’s happening. We spent a few hours going through this, making sure every item on the iPhone/Mac Clear lists matched in each scene, questioning why certain actions were chosen, modifying and making sure we were completely happy. Be aware that at the end of this process, your promo video may have changed quite a bit from the storyboard version!

3. Casting and Location

It’s important to illustrate your app being used in an environment people can relate to. To find a great location, and cast the right person we worked with a couple of local location and casting agencies - the final cost for the location and actor was around £1,500. If you’re hiring an actor/model always make sure that whoever you cast is familiar with the the hardware and app they will be showing!

With the Clear for iPhone video we actually used a member of the Realmac team - Nik - and were lucky to find a café that were happy for us to shoot for free! It goes without saying, but make sure you have the correct insurance and permission whenever shooting in a public location.

Clear in the kitchen

Once you have the perfect location, make sure you send pictures to the producer so they can figure out lighting and photography details.

4. Filming

Your producer will have had plenty of time to familiarise themselves with the storyboard and location so this should now be the fun part.

Camera rolling

You will need to set up all the props you’ve chosen and talk though the setup of each scene with the director. The director will be responsible for the final look of each shot, so allow time for dressing the set and making small set changes so that the video looks great. You’ll also have to make sure that there’s continuity throughout the entire shoot - not just on set but in the app too! For the Clear for iPhone video, we actually used a special build of the app that would restore to a pre-determined list of tasks when you shook the device.

Make sure you get multiple takes of each scene, so you have plenty of footage to piece together in post-production, and take photos of the scenes too - this may come in useful at a later date.

5. Post-Production

Post-production will generally take around a week. The producer (and video editor) will edit and cut the scenes, making sure the story flows and is cut to time (in our case, 60 seconds). They will make sure that everything looks crisp on screen which may involve comping screenshots of your app onto the footage. Make sure that the final scene contains all the key info you want to get across to the potential user - app icon, name, and release date.

Finding the right soundtrack for your video is really important too - without a soundtrack the results can seem flat and charmless. We worked with Josh Mobley to create a custom track for the video - he also produced the in-app sounds so already had a great appreciation of what we were trying to achieve. There’s obviously some expense involved in custom soundtrack, but we think the extra character it adds to a video is worth it!

Once you’ve got a rough-cut of the video back from the producer, it’s time to get some honest feedback from friends and colleagues who can catch any little things that don’t work.

That’s A Wrap!

All that’s left to do now is to let everybody know about your app. First you need to choose which service to host your video. We’re huge fans of Vimeo, it’s a great service and we host all our videos with them. YouTube is of course an option: it has a larger audience so the opportunity for more people to stumble across your video is greater, however we feel it's just not as nice a place watch videos. Make sure you put in some great copy promoting your app, with links to your website and all the keyword tags that will help your video get found in search.

As Dan detailed in his post, the next step is to launch the teaser site containing the video, and get to work promoting it on your blog and all your social accounts. Be sure to also contact members of the press too!

Your promo video should be a key part of your app launch plan and can really have a massive impact on the success of your app. These steps have worked really well for our videos so far, however you may have some tips to share to and we’d love to hear them - just leave a comment below or let me know on Twitter!