Xcode Local History


I found a hidden (gem) feature in Xcode today out of desperation. As I find myself bouncing from Intelli *Ahem* Android Studio to Xcode I often miss features from the former IDE. Hi, I’m Cliff. You’re here because you screwed up a source file and need to recover. Your project was probably completely functional but then you made some random edits and now you cannot figure out which change broke which thing. Don’t commit often? Then you probably have this problem frequently.

The way out lies in a hidden feature of Xcode, something we Java lovers have been spoiled by for years… Local History! That’s right, Xcode actually auto-saves revisions of your files as you work the same way Eclipse and the IntelliJ platforms do. The only wrinkle is that while Xcode does maintain a local history there is no history viewer in the IDE. The trick is to open the source file in TextEdit then click “File -> Revert to -> Browse all revisions” from the menu bar. You will be dropped into a Time Machine like interface for the current file where you can cycle back through the various edits. This interface, though more dramatic than what you find in the Jetbrains suite of tools is not as functional. For example, you cannot see a record of when tests passed or failed, only time stamps. Also, lacking a hot-key trigger, it requires 3-4 steps to coordinate. You must right click inside the source file in Xcode, choose “Reveal In Finder”, drag/drop the file into he TextEdit icon in the dock, optionally open TextEdit if you don’t have it pinned, then do the file menu dance. Still it is an incredibly useful tool which just might save my bacon today since I changed something and can’t figure out what it was.

Where does Xcode download and install its simulators?


I need to fire off a quick tip before I go to bed tonight. I was stuck on a bad build of an XCode Simulator and I wanted to reinstall it. (Sometimes the downloaded sim is corrupted. This is common in the beta/pre-release builds of XCode.) I had downloaded and installed both 8.4 and 8.1 simulators. Hi, I’m Cliff. You’re here reading this because you suck at uninstalling Simulators in Xcode.

I had the worst luck trying to remove what I’d downloaded and installed. First I tried drilling into the Xcode.app folder to find and remove the downloaded simulator here:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/PhoneSimulator8.1sdk
However, after restarting XCode it still “thought” the simulators were downloaded. I even tried deleting the cache folder here:
~/Library/Caches/com.apple.dt.Xcode
But I had the same results after restarting. The actual path to the downloaded and installed Simulators (since version 6.x) is:
/Library/Developer/CoreSimulator/Profiles/Runtimes

How Many Emcees Must Get Dissed…?


So you’re a programmer?
Yes, yes, yes, yes, yes…
I code very deeply…
In about 4 seconds, a teacher will begin to speak
I code very deeply…

Hi, I’m Cliff. You’re here because you wish to know the answer to the age old question, a question that has been asked by many different people over the ages. (Yes some even asked this very question on Yahoo.) This question is generally understood to be it’s own answer. However, in today’s discussion we will revisit the question in code using test driven design as a unique experiment uncover the answer.

Before we begin, some elaboration is in order for those who do not have a background in heavy beats and sentences terminated by rhyming vocabulary. The question we must ask and answer is, “How many emcees must get dissed before somebody says don’t mess with Cliff?” (Astute readers will note that I am paraphrasing slightly from the original.) We ask this question because over the years there have been many emcees who have had their egos reduces to nothing merely because they didn’t understand the exact count or quantitative answer. “Is it 10, or 11? Was my number twelve? Oh, I lost my ticket!”, they would say on their way towards total annihilation. “What is an emcee?”, you ask. It is the phonetic spelling of one MC which (as Queen Latifah explains) is short for “Microphone Commando”. I digress…

So we begin with an iPhone Xcode 4.2 project which will generate an iOS 5.0 static library. Our end result will be a static library which will be able to be linked to any iPhone app that wishes to provide an answer to this very question. Please open you copy of Xcode and follow along. I named my Project “HowManyEmcees” and created it as a static lib project sacked in my “dev” folder. (Feel free to save your project where ever you see fit.) Make sure you have the “Include UnitTests” checkbox marked and also check the “Create a local git repository” option to enable source control. For some it will be difficult but it’s very important that you follow each step exactly. The idea is to recondition yourself from writing code before you know why you’re writing code. Our first test will be as follows.

//
//  HowManyEmceesTests.m
//  HowManyEmceesTests
//
//  Created by Clifton Craig on 12/27/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import
#import "EmceeWarehouse.h"

@interface HowManyEmceesTests : SenTestCase

@end

@implementation HowManyEmceesTests

- (void)setUp
{
    [super setUp];

    // Set-up code here.
}

- (void)tearDown
{
    // Tear-down code here.

    [super tearDown];
}

- (void)testCanGenerateListOfEmcees
{
}

@end

We start by declaring the need for an “EmceeWarehouse” and beginning a test case that will eventually demonstrate how we get a list of Emcees from the EmceeWarehouse. That said, you can expect a warehouse full of emcees to get dissed in our example. Let’s continue with typical memory management etiquette assigning the warehouse in our setUp and clearing it in our teardown. (I could skip this step if I were to use the new iOS 5.0 ARC features but let’s keep things familiar and not introduce too much at once here.)

@interface HowManyEmceesTests : SenTestCase

@property (nonatomic, retain) EmceeWarehouse *emceeWarehouse;

@end

@implementation HowManyEmceesTests
@synthesize emceeWarehouse;

- (void)setUp
{
    [super setUp];

    self.emceeWarehouse = [[EmceeWarehouse alloc] init];
}

- (void)tearDown
{
    self.emceeWarehouse = nil;

    [super tearDown];
}

Now we hit Cmd+U, compile, crash, and understand that we need to actually have an EmceeWarehouse. It is very important that you compile at this point and verify all of the compile errors. If you are not getting compile errors then it is likely that you have not resisted the urge to correct the red flags in your editor as you went ahead and implemented the code before writing your test. If you don’t have errors, go back and delete your premature EmceeWareHouse, compile and crash. After crashing on compile create a plain old Obj-C object named EmceeWarehouse and add it only to the library (not the test) target. Compile, run (Cmd+U) and get your first green bar or passing test suite. (Why doesn’t Xcode unit testing feature green bars?) Back in our test method we express our intentions. This is the fun part because we can be as creative as we wish. I like to think of it as programming with the most dynamic language on the planet because you can change the way methods work as you write them without the penalty of recompiling or bug fixing. You’ll see what I mean in a moment.

- (void)testCanGenerateListOfEmcees
{
    id manyEmcees = [self.emceeWarehouse listOfEmcees];

    STAssertTrue([[manyEmcees class] isSubclassOfClass:[NSArray class]],
                 @"Expecting an instance of NSArray but got %@", [[manyEmcees class] description]);
}

Add the logic above to your test and compile, run and crash. If you didn’t crash you jumped ahead again. Delete your listOfEmcees implementation in “EmceeWarehouse.m” and start over. Note that the amount of code you delete and add later is directly proportional to the amount of unnecessary code found in projects that do not use TDD. As we iterate between test and code we are looking for the simplest thing that works which is the barest amount of code that can satisfy the most recent test, anything more will absolutely degrade the quality of your project. This will make more sense after a few iterations. Let’s look back at our test. It doesn’t quite fit what we are after. We are looking to get many different emcees from the warehouse, possibly all with varying skill levels. Lets change the test to make it more indicative of that.

- (void)testCanAskForManyDifferentEmcees
{
    id manyDifferentEmcees = [self.emceeWarehouse manyDifferentEmcees];

    STAssertTrue([[manyDifferentEmcees class] isSubclassOfClass:[NSArray class]],
                 @"Expecting an instance of NSArray but got %@", [[manyDifferentEmcees class] description]);
}

This contrived example illustrates an important point. Making changes to your tests should cost little if anything which highlights another valuable concept. Making changes to your product’s requirements should cost very little. In TDD, a test should be the direct result of a discussion of some product requirement and should closely follow or even echo a given requirement. Requirements change frequently because they cannot be completely understood until your product ages a little, so formalizing the requirements in test code is important. Also, if you are being penalized for changing your requirements then you will be less likely to make the necessary changes in your requirements thus suffocating your product. Now lets implement our warehouse just a little.

//  EmceeWarehouse.h
#import

@interface EmceeWarehouse : NSObject

-(id) manyDifferentEmcees;

@end

//  EmceeWarehouse.m
#import "EmceeWarehouse.h"

@implementation EmceeWarehouse

-(id)manyDifferentEmcees
{
    return nil;
}

@end

Cmd+U and crash! It’s like stumbling through a dark room with your hands extended reaching for the wall or nearby objects. We want to carefully approach our optimal solution without stepping passed it. The less code we use to solve a problem or requirement, the more power/flexibility we have to change existing requirements or add new ones. We need to make one minor change in “EmceeWarehouse.m” before we can move on.


-(id)manyDifferentEmcees
{
    return [NSArray array];
}

Now that we pass we can commit. Committing after every passing test is a good idea because it leaves a nice audit trail of how you grew your solution. One thing to note now is the return type of our method. Even though our test eventually compared the manyDifferentEmcees to an NSArray we didn’t formalize the return type in the method declaration. That optimization must be done after we go over the test a few times and get our initial pass because it allows us the time to mentally settle on the appropriate types. Once again, the barest amount of code to satisfy the requirement is what’s important. Then you go back and refine the requirements and finally the implementation. Looking back at our test we can ask ourselves, do we really want an NSArray or should it be an NSSet? Should we try to use an NSMutableArray? We’ll stay with NSArray since we probably want to go through emcees in a predictable order and also since each emcee will probably want to listen to the one before him. We’ll forgo the use of NSMutableArray externally because we don’t have a need to change the order or members of the array. That decision is difficult for some people because, as engineers, we like to expound on what we believe the optimal solution to be rather than allowing proper iteration to guide us. That is, we love to make those “experienced educated guesses” at what would most likely solve the problem. Making such assumptions (corruptions) is the actual equivalent of writing bugs into your software or pouring salt into the open wound. Let’s make the NSArray return type formal at this point run our tests to make sure they still pass and commit.

//  EmceeWarehouse.h
#import

@interface EmceeWarehouse : NSObject

-(id) manyDifferentEmcees;

@end

//  EmceeWarehouse.m
#import "EmceeWarehouse.h"

@implementation EmceeWarehouse

-(id)manyDifferentEmcees
{
    return [NSArray array];
}

@end

In our next requirement we explore how many emcees we’re prepared to devour. Recall above that we merely satisfied the requirement of being able to ask for emcees from the warehouse, now we need to count them and make sure we have enough to prove our street credibility. Pay attention to the fact that we are incrementally exploring what our requirements should be and using that to determine what code to write and how it should look. Add the next test.


-(void)testManyDifferentEmceesShouldIncludeMoreThanOne
{
    NSInteger howManyEmcees = [[self.emceeWarehouse manyDifferentEmcees] count];
    STAssertTrue(howManyEmcees > 1, @"Should have more than 1 emcee to prove street credibility. we count %i", howManyEmcees);
}

Compile, test, fail and fix the implementation to the simplest thing that works.


-(NSArray*)manyDifferentEmcees
{
    return [NSArray arrayWithObjects:@"This is not and Emcee",
            @"and neither is this",
            nil];
}

I like to push the needle towards stoopid sometimes as I add code that is obviously wrong. The point here is to force yourself to write the tests (or the “requirements” as I like to think of them) to expose the obviously wrong or missing code. We now have passing tests and an opportunity to commit. Commit the above changes and let’s move on to one of my favorite parts. Now it’s time to define what it means to be an actual “Emcee”. See the next code example.

-(void)testEachOfManyDifferentEmceesShouldBeAnActualEmcee
{
    for (id eachEmcee in [self.emceeWarehouse manyDifferentEmcees]) {
        //What do we do here???
    }
}

A heavy-handed approach would be to compare eachEmcee class against an actual class named “Emcee”. Since we haven’t thought that far in advance lets try something simple yet not so obvious.

    for (id eachEmcee in [self.emceeWarehouse manyDifferentEmcees]) {
        STAssertTrue([eachEmcee conformsToProtocol:@protocol(Emcee)],
                     @"How many emcees wanna be emcees? Never be emcees. Cause they can't emcee!");
    }

Protocols are mere abstractions that don’t need an implementation (similar to Java interfaces) and they are simple enough to allow us to specify our intention while allowing us to move on with developing the warehouse. I hit Cmd+U (you should too) after even the most minute source changes. It is a means of giving you instant feedback of what you did as well as how what you just did impacts the overall project. Our compiler (and our editor both) tells us we need to define the Emcee protocol. Now, towards the top of “EmceeWarehouse.h” add:

@protocol Emcee

@end

Cmd+U exposes the silly behavior in our warehouse. We need something that represents a real emcee so we’ll add the simplest thing that works. Put thins anywhere in your project (I included it at the bottom of “EmceeWarehouse.m”) to allow our test to pass:

@interface NSString(Emcee)
@end

@implementation NSString(Emcee)

@end

This is a category used only from within EmceeWarehouse.m so it does not need to have separate “.m” and “.h” files. I also like to patch up my implementation to reflect the new change:


-(NSArray*)manyDifferentEmcees
{
    return [NSArray arrayWithObjects:@"I wanna be an Emcee!",
            @"Now I'm an Emcee!",
            nil];
}

As you can see, right now it doesn’t take much to be an emcee. Make sure you commit your changes before moving on. Let’s make our warehouse just a little more interesting by including a capacity and making sure it’s always full to capacity.
HowManyEmceesTests.m

@interface HowManyEmceesTests : SenTestCase

@property (nonatomic, retain) EmceeWarehouse *emceeWarehouse;
@property (nonatomic, assign) NSInteger warehouseCapacity;

@end

@implementation HowManyEmceesTests
@synthesize emceeWarehouse;
@synthesize warehouseCapacity;

- (void)setUp
{
    [super setUp];
    self.warehouseCapacity = 100;
    self.emceeWarehouse = [[EmceeWarehouse alloc] initWithCapacity:self.warehouseCapacity];
}

Cmd+U crash with unrecognized selector “initWithCapacity:” sent to instance.
EmceeWarehouse.h

@interface EmceeWarehouse : NSObject

- (id)initWithCapacity:(NSInteger)aCapacity;
-(NSArray*) manyDifferentEmcees;

@end

EmceeWarehouse.m


- (id)initWithCapacity:(NSInteger)aCapacity /*we don't wanna do anything with the capacity yet!!!*/
{
    self = [super init];
    if (self) {
        //don't touch this part yet!!!
    }
    return self;
}

Cmd+U, pass, commit! Now we need to make sure we’re always full to capacity.
HowManyEmceesTests.m


-(void)testWarehouseIsFullToCapacity
{
    STAssertEquals((NSInteger)[[self.emceeWarehouse manyDifferentEmcees] count], self.warehouseCapacity,
                   @"EmceeWarehaouse should be full to warehouseCapacity");
}

Cmd+U fail, and fix:
EmceeWarehouse.h

@interface EmceeWarehouse : NSObject

- (id)initWithCapacity:(NSInteger)aCapacity;
-(NSArray*) manyDifferentEmcees;

@property(nonatomic, assign) NSInteger capacity;

@end

EmceeWarehouse.m

@implementation EmceeWarehouse
@synthesize capacity;

- (id)initWithCapacity:(NSInteger)aCapacity
{
    self = [super init];
    if (self) {
        self.capacity = aCapacity;
    }
    return self;
}

-(NSArray*)manyDifferentEmcees
{
    NSMutableArray *soManyDifferentEmcees = [NSMutableArray array];
    for (int countOfEmcees = 0; countOfEmcees < self.capacity; countOfEmcees++) {
        [soManyDifferentEmcees addObject:@"I wanna be an emcee!!"];
    }
    return soManyDifferentEmcees;
}

@end

Now when you have so many different emcees there’s bound to be a sucka in the mix! To be specific, a sucka emcee is the one that will cop out in the midst of a challenge. He’s the one that has no heart and is afraid to battle- the one emcee that’ll say “Don’t mess with Cliff”, thus terminating what eventually become an infinite loop, or never ending round of battles. Many people don’t understand what exactly does it mean to be an emcee. Our next round of tests will explain it very clearly. At the very bottom of “HowmanyEmceesTests.m” we’ll add:

#pragma mark - EmceeTests

@interface EmceeTests : SenTestCase

@property (nonatomic, retain) id theEmcee;
@end

@implementation EmceeTests
@synthesize theEmcee;

-(void)setUp
{
    [super setUp];
}

-(void)tearDown
{
    self.theEmcee = nil;
    [super tearDown];
}

@end

It’s more common to use different test case files but for our purposes we can stuff everything in one file. Hit Cmd+U and verify both test case classes show as being executed. (You can commit here as well.) Add our first definition of a real emcee:
HowManyEmceesTests.m

-(void)testAnEmceeCanBeASucka
{
    self.theEmcee.isSucka;
}

Cmd+U (after every little change, remember?) forces us to go add a property that will expose the true heart of each emcee, showing if he’s hardcore or not. (Yeah, yeah, I know! Our emcee could be a “she” as well! and she could also be hardcore.) Let’s define that property.
EmceeWarehouse.h

@protocol Emcee

@property (nonatomic, readonly) BOOL isSucka;

@end

Adding the following to the NSString category in “EmceeWarehouse.m” will eventually give us a warehouse full of sucka emcees:
EmceeWarehouse.h

@implementation NSString(Emcee)
@dynamic isSucka;

-(BOOL)isSucka
{
    return YES;
}

Cmd+U, pass and commit. We’re at a point where we should break out two different classes of emcees. Enter ChampionEmcee and SuckaEmcee, both of these will probably extend the base class of Emcee, right? Before we get ahead of ourselves let’s start from the tests since we have some cleanup to do. First create an empty file named EmceeWarehouse.m and cut/paste the following from “HowManyEmceesTests.m” (copy the imports of course but cut everything else):
HowManyEmceesTests.m

#import
#import "EmceeWarehouse.h"

#pragma mark - EmceeTests

@interface EmceeTests : SenTestCase

@property (nonatomic, retain) id theEmcee;
@end

@implementation EmceeTests
@synthesize theEmcee;

-(void)setUp
{
    [super setUp];
}

-(void)tearDown
{
    self.theEmcee = nil;
    [super tearDown];
}

-(void)testAnEmceeCanBeASucka
{
    self.theEmcee.isSucka;
}

@end

Commit after verifying that this new test case is associated with the tests target and its tests are still being executed. (In my case I believe it defatted to the test target since that was the active target.) Change #import "EmceeWarehouse.h" to #import "Emcee.h". Compile (Cmd+U), crash, and know that you now need to create and Emcee Objective-C file. Pay attention to how we always use the Cmd+U sequence to let either the compiler or the runtime let us know when we need to add more code. It is a difficult habit to build, breaking out of the “I know I need to do X” mentality. The more frequently you use Cmd+U the more you get used to seeing what doesn’t work while familiarizing with all the different errors that would otherwise confuse you. Add the new “Emcee” class and Cmd+U again to learn that you now need to move the protocol definition out of “EmceeWharehouse.h”.
EmceeWharehouse.h

#import "Emcee.h"
@protocol Emcee

@property (nonatomic, readonly) BOOL isSucka;

@end

Change the setUp to make sure we are exercising the Emcee class:

-(void)setUp
{
    self.theEmcee = [[[Emcee alloc] init] autorelease];
    [super setUp];
}

Cmd+U will show failure since we never declared/synthesized the isSucka property. Make the Emcee class follow the Emcee protocol and synthesize the isSucka property.

@interface Emcee : NSObject <Emcee>

@end

@implementation Emcee
@synthesize isSucka;

@end

Test (Cmd+U), pass and commit. Change the EmceeWarehouse manyDifferentEmcees method to use our new class and remove the ad-hoc category on NSString.

-(id<Emcee>)anyOldEmcee
{
    return [[[Emcee alloc] init] autorelease];
}

-(NSArray*)manyDifferentEmcees
{
    NSMutableArray *soManyDifferentEmcees = [NSMutableArray array];
    for (int countOfEmcees = 0; countOfEmcees < self.capacity; countOfEmcees++) {
        [soManyDifferentEmcees addObject:[self anyOldEmcee]];
    }
    return soManyDifferentEmcees;
}

Cmd+U, pass, commit. Now add the following to the bottom of the EmceeTests file:

@interface SuckaEmceeTests : EmceeTests

@end

@implementation SuckaEmceeTests

-(void)setUp
{
    [super setUp];
    self.theEmcee = [[[SuckaEmcee alloc] init] autorelease];
}

-(void)testASuckaEmceeWillAlwaysBeASucka
{
    STAssertTrue(self.theEmcee.isSucka, @"A sucka emcee will always be a sucka!");
}

@end

Hitting Cmd+U makes our toolchain inform us that we need to define a SuckaEmcee:
Emcee.h

@interface SuckaEmcee : Emcee

@end

Emcee.m

@implementation SuckaEmcee

@end

Hitting Cmd+U once more reminds us that a sucka emcee will always be a sucka. We must code our new class this way.
Emcee.m

@implementation SuckaEmcee

-(BOOL)isSucka
{
    return YES;
}

@end

Cmd+U, pass, and commit. Back in our EmceeTests class. We need to make our Emcees spit a lil’ sumn sumn.

-(void)testAnEmceeCanSpitSomething
{
    NSString *aLilSumnSumn = [self.theEmcee spitSomething];
    STAssertNotNil(aLilSumnSumn, @"aLilSumnSumn should never be nil because that's just not John Blaze. Y'know?");
}

Cmd+U makes us add the following:

@protocol Emcee <NSObject>

@property (nonatomic, readonly) BOOL isSucka;

-(NSString *)spitSomething;

@end

//And in our base class
@implementation Emcee
@synthesize isSucka;

-(NSString *)spitSomething
{
    return nil;
}

@end

Cmd+U shows two errors for the one test. This is important to pay attention to since we’ve added the expectation to the base test case for emcee it will apply to all Emcees, even the suckas. Add the simplest thing that works:

-(NSString *)spitSomething
{
    return @"I'll battle any sex or any race. You beating me is like Billy Crystal playing Scarface.";
}

That’s not necessarily the simplest thing but it’s colorful enough to get the point across. Now let’s see what happens when one Emcee spits something at another.

-(void)testAnEmceeCanSpitSomethingAtAnother
{
    id<Emcee> anotherEmcee = [[[Emcee alloc] init] autorelease];
    NSString *aLilSumnSumn = [self.theEmcee spitSomething:anotherEmcee];
    STAssertNotNil(aLilSumnSumn, @"aLilSumnSumn should never be nil because that's just not John Blaze. Y'know?");
}

Editor and compiler errors tell us we need to do something, something simple.

-(NSString *)spitSomething:(id<Emcee>)anotherEmcee
{
    return nil;
}

Cmd+U runs and shows us where we’re not so John Blaze. A simple fix would be to make the new spitSomething: work like the other.

-(NSString *)spitSomething:(id<Emcee>)anotherEmcee
{
    return [self spitSomething];
}

Now we’re going to see an Emcee just getting dissed.

-(void) testAnEmceeJustGotDissed
{
    [[[[Emcee alloc] init] autorelease] spitSomething:self.theEmcee];
    self.theEmcee.justGotDissed;
}

Cmd+U compile error tells us to add the missing method.
Emcee.h

@protocol Emcee <NSObject>

@property (nonatomic, readonly) BOOL isSucka;
@property (nonatomic, assign) BOOL justGotDissed;

Emcee.m

@implementation Emcee
@synthesize isSucka;
@synthesize justGotDissed;

Now add our expectation to our test case.

-(void) testAnEmceeJustGotDissed
{
    [[[[Emcee alloc] init] autorelease] spitSomething:self.theEmcee];
    STAssertTrue(self.theEmcee.justGotDissed, @"The Emcee just got dissed. Property check should confirm this.");
}

The simplest solution:

-(BOOL)justGotDissed
{
    return YES;
}

Of course it shouldn’t make sense. We want to write another test that explains why tour current solution is less than optimal:

-(void)testAnEmceeDidNotJustGetDissed
{
    STAssertFalse(self.theEmcee.justGotDissed, @"Nobody spit anything at the emcee. He did not just get dissed");
}

All along we are adding documentation along side our new software components. This is the best kind of documentation because it is executable and always up to date. When something breaks we have documentation explaining how we expect things to work and where the breakage is. Removing the formal definition from our implementation will cause it to fall back on the synthesized definition which will always return NO when we asked if we just got dissed. That will fix our latest test but break our earlier test. We are forced to change the state of the other emcee as we spit something at another emcee.

-(NSString *)spitSomething:(id<Emcee>)anotherEmcee
{
    anotherEmcee.justGotDissed = YES;
    return [self spitSomething];
}

//Remove/delete this...
//-(BOOL)justGotDissed
//{
//    return NO;
//}

Cmd+U to validate our above changes then feel free to delete the commented code. Cmd+U can be used to confirm our refactoring did not alter behavior prior to commiting. Congratulations! We have demonstrated how an emcee just got dissed. We’re almost there! A couple more changes are in order. First we need to elaborate on the SuckaEmcee. You see, a SuckaEmcee should say “Don’t mess with Cliff!” after he just got dissed because he’s soft. We need to add a test to document and demonstrate the idea. At the bottom of EmceeTests.m inside our SuckEmceeTests add the following:
EmceeTests.m

-(void) testASuckaEmceeJustGotDissed
{
    [[[[Emcee alloc] init] autorelease] spitSomething:self.theEmcee];
    STAssertEqualObjects([self.theEmcee spitSomething], @"Don't mess with Cliff!",
                   @"We expect the SuckaEmcee to be soft and tell others 'Don't mess with Cliff'.");
}

Notice how we really don’t need comments to explain what’s happening. Our expectations are inlined as code and our logic echoes our use cases. We can use the simplest thing that works here. At the bottom of Emcee.m in the @implementation for SuckaEmcee, we add this:

-(NSString *)spitSomething
{
    return @"Don't mess with Cliff!";
}

The SuckaEmcee feels slightly incomplete. We want our sucka to try to spit lil’ something on occasion, because he is an Emcee after all. The best way to demonstrate this is in our definition of an Emcee in the EmceeTests. We add a new test.

-(void) testAnEmceeWhoHasNotJustGotDissedWillNotShowFear
{
    STAssertFalse(self.theEmcee.justGotDissed, @"Given an Emcee that has not yet been dissed...(sanity check.)");
    STAssertFalse([[self.theEmcee spitSomething] isEqualToString:@"Don't mess with Cliff!"],
                  @"Any emcee will try to spit something before being dissed.");
}

Our test is showing us how our SuckaEmcee is not really behaving as an Emcee should. In plain slanglish, our current emcee is always punking out. We have to fix this since our sucka has “Emcee” in it’s class name and in it’s class hierarchy. In our SuckaEmcee @implementation we make it try to spit something before getting dissed:

-(NSString *)spitSomething
{
    if (self.justGotDissed) {
        return @"Don't mess with Cliff!";
    } else {
        return [super spitSomething];
    }
}

Cmd+U pass, and commit. Now there’s still an issue with the each Emcee in our EmceeWarehouse. Among every group of Emcees you’re bound to find a sucka. Lets add one more test to our HowManyEmceesTests to make sure.

-(void)testThereShouldBeASuckaEmceeInTheWarehouse
{
    NSUInteger locationOfSucka = [[self.emceeWarehouse manyDifferentEmcees] indexOfObjectPassingTest:^BOOL(id eachEmcee, NSUInteger eachIndex, BOOL *stop){
        return eachEmcee.isSucka;
    }];
    STAssertFalse(locationOfSucka == NSNotFound,@"Location of our SuckaEmcee should NOT be NotFound.");
}

Cmd+U and we see a new but expected failure from the assert we just coded. We need to change the implementation of our manyDifferentEmcees method using the most simplest approach:

-(NSArray*)manyDifferentEmcees
{
    NSMutableArray *soManyDifferentEmcees = [NSMutableArray array];
    for (int countOfEmcees = 0; countOfEmcees &lt; self.capacity; countOfEmcees++) {
        [soManyDifferentEmcees addObject:[self anyOldEmcee]];
    }
    [soManyDifferentEmcees addObject:[[[SuckaEmcee alloc] init] autorelease]]; //tack on a SuckaEmcee
    return soManyDifferentEmcees;
}

Cmd+U and guess what? We fixed our test and broke another. Our TestCases just deposited a few dollars into our development account! Our test, testWarehouseIsFullToCapacity, complains that our warehouse must be flu to capacity. We cannot just add a sucka on the end because he won't fit. For now we just tweak the manyDifferentEmcees method once again to make room.

-(NSArray*)manyDifferentEmcees
{
    NSMutableArray *soManyDifferentEmcees = [NSMutableArray array];
    for (int countOfEmcees = 0; countOfEmcees &lt; self.capacity - 1/* Leave room for desert, the last Emcee is gonna get ate!*/; countOfEmcees++) {
        [soManyDifferentEmcees addObject:[self anyOldEmcee]];
    }
    [soManyDifferentEmcees addObject:[[[SuckaEmcee alloc] init] autorelease]]; //tack on a SuckaEmcee
    return soManyDifferentEmcees;
}

At this point we've built enough infrastructure to answer our original question but this solution is a little boring and completely predictable since we always fill our warehouse with a sucka on the end. We have tests to cover our next move, refactor! We want to take a different approach to making sure there's a sucka emcee in the crowd. First restore our manyDifferentEmcees method to it's original form. Revert the EmceeWarehouse.m file so it looks like this:

-(NSArray*)manyDifferentEmcees
{
NSMutableArray *soManyDifferentEmcees = [NSMutableArray array];
for (int countOfEmcees = 0; countOfEmcees &lt; self.capacity; countOfEmcees++) {
[soManyDifferentEmcees addObject:[self anyOldEmcee]];
}
return soManyDifferentEmcees;
}

Cmd+U and fail on the original assert failure. Next we change the anyOldEmcee method to return either an Emcee or a sucka based on a random value:

-(id)anyOldEmcee
{
if ((arc4random() % 100) &gt; 95) {
return [[[SuckaEmcee alloc] init] autorelease];
} else {
return [[[Emcee alloc] init] autorelease];
}
}

That should give us a rough distribution of 5% sucka Emcees in our warehouse. We can adjust the percentage to our liking as our needs mature. For now this will do. Our last bit of code is intended to test each emcee. Create the following test case:

-(void)testHowManyEmceesMustGetDissed
{
    id cliff = [[[Emcee alloc] init] autorelease];
    NSUInteger locationOfEmceeThatJustGotDissed = [[self.emceeWarehouse manyDifferentEmcees] indexOfObjectPassingTest:^BOOL(id eachEmcee, NSUInteger eachIndex, BOOL *stop){
        [cliff spitSomething:eachEmcee];
        *stop = [[eachEmcee spitSomething] isEqualToString:@"Don't mess with Cliff!"];
        return *stop;
    }];
    STAssertEquals(locationOfEmceeThatJustGotDissed, (NSUInteger)0,@"%i emcees just got dissed", locationOfEmceeThatJustGotDissed + 1);
}

You may want to run this test more than once. It illustrates an important technique I often use when doing TDD. It’s what I call the discovery test. Whenever I have an API call that produces an unknown (or in this case variable) value that I want to discover, I write a failing test which outputs the value of the API call as part of the assert description. In the above example we finally discover how many emcees just got dissed, before somebody says, “don’t mess with Cliff!” I leave you to mull over it for a while. Leave comments if you will. G’night.

Speex On iPhone Explained Part II


*Update*
From part I I neglected to point out that you should un comment #define _USE_SSE in the config.h as mentioned below. This preproc directive will allow you to run on device. It was also mentioned that you could get more speed out of Speex if you #define FIXED_POINT instead of FLOATING_POINT. I have not verified this and Speex runs acceptable in my implementation without it but its worth mentioning.
*Update*

You have a lot of vocal audio data. Maybe it needs to be stored on an iPhone. Maybe it needs to glide effortlessly over the network like a slice of dental floss blowing in the wind. Whatever the case, you need a good compressor and Speex is a great solution. Hi, I’m Cliff. You’re here because you’re looking for an answer to your audio compression needs. I’m here to deliver the secrets to decompressing audio with the Speex codec. That, for what it’s worth, is the only reason I’m still hanging around here. In any other event you’d probably find me on South Street sharing a soda with a cat. I digress . . .

In part I of this series I explained how to get Speex to compile. Today we’ll try to import the OGG container format into our project and move onto Speex decompression. Because not everyone may be aware, a brief explanation on codecs and containers is in order. Audio encoding is typically made of two distinct pieces. You would usually have a container format and an encoding. The audio container holds the meta data, or descriptive information, for the actual audio file. This meta or descriptive information includes things like how many channels are in the audio data, what sample rate it is recorded at, and the endianness (not Indianness) of the audio data. There are other potential data held in the container format depending on the type of encoding you use. Finally, the descriptive (meta) data will have the location (offset) of the actual audio data in the file. The encoding is the actual raw audio data that is to be delivered directly to the output device or speakers. The encoding can be a direct digital dump (that is the actual audio samples taken over time as the audio was recorded) or it can be a compressed variant of the raw samples. It’s important to note that the encoding and the container are not usually dependent upon one another. That mean you can mix and match Speex encoding with a wave container format just the same as you can put raw uncompressed samples in an OGG container. It’s just more common to find uncompressed data in a wave container and Speex compressed audio in an OGG container.

Let’s take a step back and try some TDD. Following best practices, we need to create a need for the Speex codec and the OGG container. I realize this is cart before the horse style since we’ve already imported Speex but bear with me as I’m doing this tutorial on my time off. Also up until now I’ve been completely out of the TDD habit for a while as I strive to work closely with others who are uncomfortable with the style. We start by creating a “Unit Test Bundle” target in the project. Create a new objective C class named “CCCSpeexDecoderTest” using the “New File…” dialog and do not choose (unselect) the “also create .h file” option. Include the following in your new Objective-C class file.

//
//  CCCSpeexDecoderTest.m
//  SpeexLib
//
//  Created by Clifton Craig on 11/13/10.
//  Copyright 2010 Craig Corporation. All rights reserved.
//
#include &lt;SenTestingKit/SenTestingKit.h&gt;

@interface CCCSpeexDecoderTest : SenTestCase
{
	NSString* wavFile;
	NSString* speexFile;
}
@end

@implementation CCCSpeexDecoderTest

-(void) setUp
{
	wavFile = [[NSBundle bundleForClass:[self class]] pathForResource:@&quot;sample&quot; ofType:@&quot;wav&quot;];
	speexFile = [[NSBundle bundleForClass:[self class]] pathForResource:@&quot;sample&quot; ofType:@&quot;spx&quot;];
}

-(void) testFirstTest
{
	STAssertNotNil(wavFile,@&quot;A sample wav file is required to test speex decoding.&quot;);
	STAssertNotNil(speexFile,@&quot;A sample speex file is required to test speex decoding.&quot;);
}

@end

Running this tells us that we’re going to need some speex data to operate on. (I’ve taken the liberty to generate a wav file using the “say” command and converted it to a Speex encoded file using the JSpeex API via Groovy. I’ll include both in a download of the project for this lesson.) Next we’ll create a structure to hold our unit tests and test resources. We will be following the “golden copy” testing pattern. You later learn that using the pattern here is rather fragile, however a more purist approach would take us through an exercise of re-writing the entire Speex project which is outside the scope of my tutorial. Using Finder, I created a “Tests” and a “Resources” folder under my src folder in my project. Drag/drop these folders into XCode to create the corresponding groups. Then drag/drop the sample wave and sample speex files (named “sample.wav” and “sample.spx” respectively) into the “Resources” group in XCode. Running the test will now pass.

We now work our way through creating the decoder. I’ll spare the individual steps in TDD as it would make this text overly verbose and I’ll try to summarize instead. We need an actual decoder instance which we’ll be importing. TDD suggests we import what we don’t have so add the import for a CCCSpeexDecoder type which does not exist. Build and fail. (The failure is important as it formalizes the class or feature you are about to add/change/delete.) We also need to be able to create this type and give it some audio to decode. It will also need a place to send the decoded audio data. I’m going to define an abstraction for providing/receiving the audio data so that we don’t necessarily need a file system so I’m adding a test to demonstrate/document the need for an audio source, a test to demonstrate/document the need for an audio sink, and one other test that formalizes how we plug these two abstractions into the decoder.

#import &quot;CCCSpeexDecoder.h&quot;

@interface CCCSpeexDecoderTest : SenTestCase &lt;CCCSpeexAudioSource, CCCSpeexAudioSink&gt;
{
	NSString* wavFile;
	NSString* speexFile;
	CCCSpeexDecoder *decoder;
}
@end

@implementation CCCSpeexDecoderTest

//...

-(void) testAudioSourceIsDefined
{
	id&lt;CCCSpeexAudioSource&gt; anAudioSource = self;
}

-(void) testAudioSinkIsDefined
{
	id&lt;CCCSpeexAudioSink&gt; anAudioSink = self;
}

-(void) testCanCreateDecoder
{
	[[CCCSpeexDecoder alloc] initWithAudioSource:self andAudioSink:self];
}

And this calls for the additional CCCSpeexDecoder class which defines the abstractions…

#import &lt;Foundation/Foundation.h&gt;

@protocol CCCSpeexAudioSource

@end

@protocol CCCSpeexAudioSink

@end

@interface CCCSpeexDecoder : NSObject {

}

- (id) initWithAudioSource:(id&lt;CCCSpeexAudioSource&gt;) anAudioSource andAudioSink:(id&lt;CCCSpeexAudioSink&gt;) anAudioSink;

@end

#import &quot;CCCSpeexDecoder.h&quot;

@implementation CCCSpeexDecoder

- (id) initWithAudioSource:(id&lt;CCCSpeexAudioSource&gt;) anAudioSource andAudioSink:(id&lt;CCCSpeexAudioSink&gt;) anAudioSink
{
	self = [super init];
	if (self != nil) {

	}
	return self;
}

@end

Now we go back and add one more test that explains what we’re after.

-(void) testCanDecode
{
	[decoder decodeAudio];
}

Build and fail so that we know to define the method.

-(void) decodeAudio
{
}

We now have defined the ability to decode audio. We have to set our expectation for this method. (Test first begins with declaring or expressing a need for a feature or function then setting an expectation for its behavior.) After invoking decodeAudio we would expect to have collected the decoded audio bytes somewhere. I’ll add a mutable data fieldin the test for this.

@interface CCCSpeexDecoderTest : SenTestCase &lt;CCCSpeexAudioSource, CCCSpeexAudioSink&gt;
{
	NSString* wavFile;
	NSString* speexFile;
	CCCSpeexDecoder *decoder;
	NSMutableData *decodedAudio;
}
@end

@implementation CCCSpeexDecoderTest

-(void) setUp
{
	wavFile = [[NSBundle bundleForClass:[self class]] pathForResource:@&quot;sample&quot; ofType:@&quot;wav&quot;];
	speexFile = [[NSBundle bundleForClass:[self class]] pathForResource:@&quot;sample&quot; ofType:@&quot;spx&quot;];
	decoder = [[CCCSpeexDecoder alloc] init];
	decodedAudio = [[NSMutableData alloc] init];
}

And we add a test to exercise the method and document/verify our expectation:

-(void) testDecodeAudioFillsDecodedAudio
{
	STAssertTrue([decodedAudio length] == 0, @&quot;Should NOT have accumulated data&quot;);
	[decoder decodeAudio];
	STAssertTrue([decodedAudio length] &gt; 0, @&quot;Should have accumulated data&quot;);
}

Here’s the Oogly part. We are calling a method with no return value. We’ve defined an abstraction around collecting data (an audio sink) and we’ve made our test case adopt the protocol for this abstraction. The protocol defines no methods. The test calls for data to magically arrive in the mutable data field. Indirectly, our test is stating that given a source and a sink, when the decodeAudio message is sent we should have accumulated data in the sink. running the test fails because we haven’t added the functionality. We step into the decodeAudio implementation and fill in the simplest thing that works.

-(void) decodeAudio
{
	NSString *pretendData = @&quot;pretendData&quot;;
	[audioSink audioWasDecoded:
		[NSData dataWithBytes:[pretendData cStringUsingEncoding:NSUTF8StringEncoding] length:[pretendData length]]
	 ];
}

You see we are talking to an audioSink object here. Because we don’t really have an audiosink object in scope (I just made it up b/c it felt right) we need to declare it.

@interface CCCSpeexDecoder : NSObject {
	id&lt;CCCSpeexAudioSink&gt; audioSink;
}

If we run we still won’t get satisfaction because we haven’t ensured that the audiosink given in the constructor is the one we talk to when we decode audio. So we revisit the init method.

- (id) initWithAudioSource:(id&lt;CCCSpeexAudioSource&gt;) anAudioSource andAudioSink:(id&lt;CCCSpeexAudioSink&gt;) anAudioSink
{
	self = [super init];
	if (self != nil) {
		audioSink = [anAudioSink retain];
	}
	return self;
}

We also need to release in our dealloc.

- (void) dealloc
{
	[audioSink release];
	[super dealloc];
}

Let’s be more specific. When decoding audio we will want to discover the meta data or attributes of the audio. This information is usually the first group of bytes in a file and it explains what the rest of the file contains. We’ll declare an expectation to receive a callback in our sink which contains the meta data in an easily navigable NSDictionary.

-(void) testDecodeAudioReturnsHeaderInfoToSink
{
	STAssertNil(headerInfo, @&quot;We should start with no header info.&quot;);
	[decoder decodeAudio];
	STAssertNotNil(headerInfo, @&quot;We should now have header info.&quot;);
}

and we need to add an NSDictionary field to our test to record the header info.

@interface CCCSpeexDecoderTest : SenTestCase &lt;CCCSpeexAudioSource, CCCSpeexAudioSink&gt;
{
        //Other fields...
	NSDictionary *headerInfo;
}
@end

we add the simplest thing that will work.

-(void) decodeAudio
{
	NSString *pretendData = @&quot;pretendData&quot;;
	[audioSink headerWasDecoded:[NSDictionary dictionary]];
	[audioSink audioWasDecoded:
		[NSData dataWithBytes:[pretendData cStringUsingEncoding:NSUTF8StringEncoding] length:[pretendData length]]
	 ];
}

…And this calls for an additional method in our AudioSink protocol.

@protocol CCCSpeexAudioSink &lt;NSObject&gt;

-(void) audioWasDecoded:(NSData*) someDecodedAudio;
-(void) headerWasDecoded:(NSDictionary*) theAudioAttributes;
@end

Which bleed back into the test where we store the attibutes as our header info. Add the following to the test case.

-(void) headerWasDecoded:(NSDictionary*) theAudioAttributes
{
	headerInfo = theAudioAttributes;
}

Now we’ll look at individual attributes given to the sink during the parse. We set some expectations for numeric values mapped to specific keys in the header info.

-(void) testDecodeAudioHeaderInfoIncludesSpecificValues
{
	[decoder decodeAudio];
	NSNumber *value = [headerInfo valueForKey:@&quot;sampleRate&quot;];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
	value = [headerInfo valueForKey:@&quot;frameSize&quot;];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
	value = [headerInfo valueForKey:@&quot;numberOfChannels&quot;];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
	value = [headerInfo valueForKey:@&quot;decodeBlockSize&quot;];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
	value = [headerInfo valueForKey:@&quot;framesPerPacket&quot;];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
}

And as you’ll note a pattern here we should do some refactoring.

-(void) assertNumericValueInDictionary:(NSDictionary*)aDictionary atKey:(NSString*)aKey
{
	NSNumber *value = [headerInfo valueForKey:aKey];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
}

-(void) testDecodeAudioHeaderInfoIncludesSpecificValues
{
	[decoder decodeAudio];
	[self assertNumericValueInDictionary:headerInfo atKey:@&quot;sampleRate&quot;];
	[self assertNumericValueInDictionary:headerInfo atKey:@&quot;frameSize&quot;];
	[self assertNumericValueInDictionary:headerInfo atKey:@&quot;numberOfChannels&quot;];
	[self assertNumericValueInDictionary:headerInfo atKey:@&quot;decodeBlockSize&quot;];
	[self assertNumericValueInDictionary:headerInfo atKey:@&quot;framesPerPacket&quot;];
}

Because I forget the attributes of the file provided I’m going to use a discovery test technique. With this technique we use a dummy expected value in our assert and allow the assertion error message tell us what the actual value is. I wouldn’t do this in normal testing. It’s only because I already have working code that I’m plugging in and because this tutorial is getting wordy that I’m going to take the cheap way out.

-(void) assertIntValue:(int)anInt isInDictionary:(NSDictionary*)aDictionary atKey:(NSString*)aKey
{
	NSNumber *value = [headerInfo valueForKey:aKey];
	STAssertNotNil(value, @&quot;Should have returned a number&quot;);
	STAssertEquals([value intValue], anInt, @&quot;Integer value %i should exist for key %@&quot;, anInt, aKey);
}

-(void) testDecodeAudioHeaderInfoIncludesSpecificValues
{
	[decoder decodeAudio];
	[self assertIntValue:-999 isInDictionary:headerInfo atKey:@&quot;sampleRate&quot;];
	[self assertIntValue:-999 isInDictionary:headerInfo atKey:@&quot;frameSize&quot;];
	[self assertIntValue:-999 isInDictionary:headerInfo atKey:@&quot;numberOfChannels&quot;];
	[self assertIntValue:-999 isInDictionary:headerInfo atKey:@&quot;decodeBlockSize&quot;];
	[self assertIntValue:-999 isInDictionary:headerInfo atKey:@&quot;framesPerPacket&quot;];
}

Once we implement the actual parsing logic we will start to see the actual values reported in the assertion errors. (I am adapting existing working code rather than developing the code from test cases.) We will pull the values from the errors back into the asserts to make the test pass and document what our expectations actually are.

Now we need to actually start pulling audio from our audio source abstraction. Because we used protocols, our test can pose (using the self-shunt pattern) as the audio source and provide data for the decoder. We step into the decoder and start doing some actual parsing.

-(void) decodeHeader
{
	[audioSink headerWasDecoded:[NSDictionary dictionary]];
}

-(void) decodeAudio
{
	NSString *pretendData = @&quot;pretendData&quot;;
	[self decodeHeader];
	[audioSink audioWasDecoded:
		[NSData dataWithBytes:[pretendData cStringUsingEncoding:NSUTF8StringEncoding] length:[pretendData length]]
	 ];
}

Importing OGG

At this point we have to import OGG for decoding the container so we can read the file meta data. Download and unpack libogg (not liboggz) from the Xiph.org download site.

We need to add the ogg header files to the header search path, so drag/drop the ogg folder from the include folder in the root of the unpacked directory into your XCode project. (/path/to/libogg-1.2.1/include/ogg) Choose to Copy the files from the dialog and select your static lib target before accepting the dialog. Delete the config_types.h.in and makefile.am and Makefile.in from this folder and group. (Also move them to trash.) Double click the project icon in the left tree pane and select the “Build” tab. Type “header search” in the search box at the top to narrow the options to the header search path. You need to add, “$(SRCROOT)” as one of your header search path values here. Create an XCode group for the ogg source code and drag/drop the “bitwise.c” and “framing.c” files from the unpacked libogg source folder. (/path/to/libogg-1.2.1/src).

At this point building unit test target should leave you with errors from the latest round of header info asserts which we will fix in the next part of the series. We have a fully configured project with access to both the speex and ogg encoding/decoding APIs which is exciting. In the next part of the series we will tackle calling into these APIs to decode the data. I’m going to upload my part II example project to my box account so it will be in the right and pane for your downloading pleasure. Until next time…

(Some of you will have noticed I accidentally published this post the other day before finishing it. This is why I’m publishing it half baked tonight. There’s alot here and a lot more to cover. Keep checking back for updates!)

XCode 3.2.4 Bug!


Just a quick note to those of you working with XCode 3.2.4 and trying to get any sort of unit testing working. There is a known bug/issue in XCode that causes unit test builds to crash. As it is written here (and here), “some part of the reporting code not respecting timezone issues. The output is tagged as ending before it began, so gets very confused and chokes.” The solution is to edit the Run Script step of the unit test target and make it look like this:

"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests" 1> /tmp/RunUnitTests.out 

Works for me!

Speex On iPhone Explained


*Update*
I neglected to point out that you should un comment #define _USE_SSE in the config.h as mentioned below. This preproc directive will allow you to run on device. It was also mentioned that you could get more speed out of Speex if you #define FIXED_POINT instead of FLOATING_POINT. I have not verified this and Speex runs acceptable in my implementation without it but its worth mentioning.
*Update*

I get a lot of questions on how I implemented Speex on iPhone. So I’m going to take this time to do a quick tutorial series. This is part 1, which will show you how to import the speex source into XCode and get a clean compile.

First download and explode the Speex source to any location. Run “./configure” in the exploded folder and create an iPhone subfolder within the speex in this same location. Now we’ll begin creating an XCode project inside the iPhone subfolder. I use a static lib project so that I can reused my work in several other projects, but if you’re new to XCode and iPhone you may forego static libs and just create a typical view based project. I start out being anal about my project structure. I prefer to have only the project folder and a single src folder at my project root. I realize this is non standard iPhone but it makes perfect sense from a build perspective. (I see: build description + src = build output) So a little refactoring and adjusting my target settings to find the new location of the plist and pch files.

  • Drag/drop the libspeex and include/speex folders into your XCode project.
  • Drag/drop the config.h file from the unpackaged speex tar into your project.
  • Add the include folder to your header search path
  • Double click the project in the left hand tree and add the following user defined setting: GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H
  • (User defined settings can be added by clicking the little wrench in the lower left corner.)
  • Finally, you need to take “libspeex/echo_diagnostic.m” out of the compile loop. Either uncheck the target membership box next to the left hand “Groups & Files” tree pane on the left or open and drill into your Application (or static lib) target and select the “Compile Sources” branch. Find the file under there and delete it.

By now your compiles should be squeaky clean. Stay tuned to the next parts of the series where I’ll discuss how to import ogg and wave container formats into XCode and perform Speex decompression in an app. I’ve upoaded my source (SpeexLib) to my box.net account so you can click here to download it or find it in the Box widget to the right of this post.

Objective-C Gotchas


You’re working in Objective-C land trying to get a product out the door and into the Apple iTunes Store, right? (Don’t argue with me I’m just setting the stage.) You’re feeling the second cup of coffee seep into your bloodstream which creates a certain euphoric sensation as the last 3 times you mashed Cmd+B turned up no errors. Yes, that’s what’s happening in your copy of XCode right now. You then Cmd+Tilde to toggle the other XCode window active (Cmd+Tilde is a nifty Apple shortcut for switching active windows in the current app) and Cmd+B once again when a red flag on the play pops up in some code that had been just fine moments ago? What happened? Hi, I’m Cliff. You’re here because XCode got’cha and you’re not quite sure how/why/where. I’m here because I wanna list as many of these got’chas before I forget them.

Property accessor notation in Earlier SDKs
Here’s one weird gotcha that I just hit again for the first time. If you have a variable typed as a protocol and that protocol has a setter, which takes another protocol type defined then you may get an error when using dot notation in SDKs earlier than 3.0. That is a definition like this:

@protocol MyCoolAbstractType <NSObject>
-(void) setNetworkDataProvider:(id<MyNetworkDataProvider>)aNetworkDataProvider;
@end

…should be coded like this:

@protocol MyCoolAbstractType <NSObject>
@property (nonatomic, retain) id<MyNetworkDataProvider> networkDataProvider;
@end

…before you can do this:

id<MyCoolAbstractType> myObj = //create object from factory
myObj.networkDataProvider = [[MyConcreteNetworkDataProvider alloc] init];

Evidently the “Discover setter is a property” feature is something new Santa delivered with 3.0 and never told me about. Here I thought I had that toy from 2 years ago!

Unit Tests Can’t Be Signed
I added a unit test dependency to my “Application” target the other week in order to streamline my dev cycles. The idea was to ensure any changes I made to satisfy the integrated application bundle did not impact behaviors outlined in my test cases. (I use mini applications to perform my integration testing.) The problem here is that, even though this works well for simulator builds, an on-device build will fail as XCode attempts to sign your unit test target output. I haven’t discovered a work-around for this one yet so I’m gonna just punt and remove the test dependency from any targets meant to run on device.

I’ll trow up more as I find them…