Blog

The Street Busker Approach To Objective-C Memory Management

July 22nd, 2010 0 Comments

In my line of work I get to talk to a lot of iPhone developers who are new to Objective-C. And no matter how much experience said developer has in other languages, one problem they always face in the beginning is understanding and debugging Objective-C’s memory management scheme. But don’t fret young Skywalker! Everything you need to know about Objective-C memory management can be learned from a street busker (aka performer).

Read More

Lauren Graham Gets Stachetastic with Ellen!

March 3rd, 2010 0 Comments

Thanks for the ’stachetastic love Lauren!!!

Run your startup like a Pawn Shop

January 12th, 2010 0 Comments

I was working late last night and needed some noise in the background, so I flipped on the TV in my office and channel surfed for a few moments. Eventually I came upon a little gem of a show called “Pawn Stars” on the History Channel. Pawn Stars follows real-life Vegas pawn store owners Richard and Rick Harrison as they wheel and deal in everything from vintage Playboy magazines to extremely rare continental currency. At first I thought this show was going to be a bit of mindless entertainment (perfect for background noise), but after a few minutes of watching I was hooked as I realized this was no “Dog The Bounty Hunter”. I actually learned a hell of a lot. I realized very quickly that these guys were no dummies and many of the things that are second nature to them would be valuable lessons to anyone who owns a business or is starting one up. So what are these lessons?

1. Know Your Shit

If you don’t know your shit, people will take advantage of you. You may not think of a pawn shop owner as the smartest person in the world, but the Harrisons have an almost encyclopedic knowledge of history and objects that have helped shape it. In the show, a wealthy customer who collects rare cufflinks walks out of the pawn shop after making a purchase for $200, and says, “In most pawn shops I would have been able to pick these up for $30, but these guys obviously know their stuff.” Being extremely knowledgeable about what your selling and knowing its value will allow you to sell for $200 what your competitor sells for $30.

2. Know Your Market

Since pawn shop owners only make money when they actually sell the items in their shops, it would stand to reason that the successful ones really understand what people will want to buy. Ricks son Corey has a bit to learn in this department as was evident when he paid $38,000 for a used hot-air balloon. The balloon was probably worth $50,000 and could technically be sold at a profit, but as Rick explained to his “idiot” son in an incredulous tone, “How many people do you know in the market to buy a 12 person hot air balloon?” Just because your product or idea is valuable doesn’t mean anyone will buy it. ‘Nuff said.

3. Know Your Limitations

A guy walks in the shop with what he says is a 1960 Gibson Les Paul Custom guitar. These guitars have fetched over $400,000 at auction, so Rick was certainly excited. Rick has bought and sold many vintage guitars and to him it appeared legit, but was it really the highly sought after 1960 model? Unfortunately in the 60’s Gibson was really bad at keeping their serial numbers straight, so a serial number that appeared as if it was from the 60’s could really be from the 70’s at a difference of hundreds of thousands of dollars in value. Rick knew that his knowledge on this particular subject was limited, and brought in an expert. It turns out that there were extremely small clues (which only an expert could identify), that placed the guitar at a 1971 vintage and a value of a few thousand dollars, not the $25,000 the man wanted for it. Rick realizes that there is no way you can be an expert in everything, and that tricking yourself into thinking you are can lead to big trouble. He has assembled a crack team of advisors ranging in expertise from colonial period maps to rare handcuffs. Know your limitations and build a team of people who can help you overcome them.

4. Tell a Great Story

A couple walks into the shop and says they are interested in buying a clock that is set up high behind the counter. Rick says, “You mean the Death Clock?” The couple is instantly captivated. Rick goes on to tell the story behind the clock in that the process of casting the gold plated exterior in the 18th century required the clockmaker to evaporate mercury. The mercury vapors would cause insanity and eventually death. Many clockmakers died making these types of clocks, thus their moniker. The simple act of knowing and telling the great story behind the clock instantly made it more valuable in the customers eyes (I suppose in this case you could say as valuable as a persons life). Having a great story behind your products and ideas can instantly add value and give your customers something they can relate to.

5. Love What You Do

A man walks into the pawn shop and presents an exquisite example of continental currency designed and printed by none-other than Benjamin Franklin. Rick is instantly aware of the significance and value of the artifact and must have it. After haggling for a few minutes, the man agrees to a price and sells it to Rick. Rick then goes on to say, “This is the type of thing that I’ll put a ridiculously high price on, so that no one will buy it.”  You start to realize after watching a few episodes that Rick is a history buff first and a pawn shop owner second. It’s clear that he uses his pawn shop as way to fuel his passion for history and the objects that helped shape it. This guy makes money on something he lives for. If you love what you do, other people will follow suit.

It’s always fun to find lessons in unexpected places. Bravo Pawn Stars for putting these lessons to work in the real world.

Cheers,

-jim

’stachetastic featured in Esquire Magazine!

December 28th, 2009 0 Comments

Thanks Esquire! Here’s a link to the online version of the article.

http://www.esquire.com/blogs/endorsement/new-iphone-apps-122809

Launch an iTunes LinkSynergy Affiliate Link Directly into iTunes

December 14th, 2009 0 Comments

If you develop iPhone apps that allow users to buy music from iTunes or other apps from the App Store, then most likely you are using an iTunes Affiliate LinkSynergy link to make sure you’re getting a little cut of the action. If you aren’t doing this, then you’re missing out on $0.05 of every dollar you sell through your app!

While it’s fairly easy to create and launch an iTunes Affiliate link through LinkSynergy, an annoying side-effect is that the iPhone will launch the LinkSynergy link in Mobile Safari first before the user is sent to iTunes or the App Store. Not only does this add time and confusion to the process, but it just looks unprofessional.

So how do we skip the unsightly Mobile Safari redirect step and put the user directly into iTunes? In this case we do the work for Mobile Safari by creating a hidden UIWebView and handling the redirect ourselves. Let’s take a look.

The first piece of code is actually the part where we create our affiliate link. While you could generate each link yourself through the iTunes Affiliate link maker, I prefer to generate them on the fly using a standard iTunes/App Store link using the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// This function takes in a non affiliate link (like http://itunes.apple.com/us/app/stachetastic-ultimate/id320854704?mt=8) and converts it into an affiliate link
-(NSString*)getItunesPurchaseURL:(NSString*)urlString
{
    // If the link is set itunes.apple.com, mobile safari will actually launch yet ANOTHER url before it goes to iTunes. If we set this to phobos.apple.com, the iPhone will launch iTunes directly
    NSString* formattedUrl = [urlString stringByReplacingOccurrencesOfString:@"itunes" withString:@"phobos"];

    // Who knows why, but the affiliate URL link requires that the ampersand symbol be escaped twice
    formattedUrl = [formattedUrl stringByReplacingOccurrencesOfString:@"&" withString:@"%2526"];
    formattedUrl = [TextUtilities urlEncodeString:formattedUrl];
   
    // The id, offerid, type, and tmpid values will differ for your account. Copy these values from an affiliate link you've created before
    NSString* finalUrl = [NSString stringWithFormat:@"http://click.linksynergy.com/fs-bin/click?id=bBvzpyg5uQ0&subid=&offerid=146261.1&type=10&tmpid=3909&RD_PARM1=%@", formattedUrl];
   
    return finalUrl;
}

// urlEncodeString for your reference.
+(NSString *)urlEncodeString: (NSString *) urlString
{
    NSArray *escapeChars = [NSArray arrayWithObjects:@";" , @"/" , @"?" , @":" ,
                            @"@" , @"&" , @"=" , @"+" ,
                            @"$" , @"," , @"[" , @"]",
                            @"#", @"!", @"'", @"(",
                            @")", @"*", @" ", nil];
   
    NSArray *replaceChars = [NSArray arrayWithObjects:@"%3B" , @"%2F" , @"%3F" ,
                             @"%3A" , @"%40" , @"%26" ,
                             @"%3D" , @"%2B" , @"%24" ,
                             @"%2C" , @"%5B" , @"%5D",
                             @"%23", @"%21", @"%27",
                             @"%28", @"%29", @"%2A", @"+", nil];
   
    int len = [escapeChars count];
   
    NSMutableString *temp = [urlString mutableCopy];
   
    int i;
    for(i = 0; i < len; i++)
    {
       
        [temp replaceOccurrencesOfString: [escapeChars objectAtIndex:i]
                              withString:[replaceChars objectAtIndex:i]
                                 options:NSLiteralSearch
                                   range:NSMakeRange(0, [temp length])];
    }
   
    NSString *out = [NSString stringWithString: temp];
   
    [temp release];
   
    return out;
}

Now that we’ve got our affiliate link, let’s launch it. First thing we’ll do is create a hidden UIWebView and launch our affiliate link.

1
2
3
4
5
6
7
8
9
10
-(void)launchItunesPurchaseURL:(NSString*)affiliateURLString
{
    // Create a hidden webview to launch our affiliate URL
    UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectZero];
    webView.alpha = 0.0;
    webView.delegate = self;
    [[UIApplication sharedApplication].keyWindow addSubview:webView];
   
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:affiliateURLString]]];
}

Now all that’s left to do is wait for the UIWebView to notify us that the affiliate URL has been loaded and let us know where we should redirect the user. This redirect URL is important in that Apple uses it to tie any purchases to your affiliate account. To do this, we simply implement the shouldStartLoadWithRequest method from UIWebViewDelegate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // Only handle itunes links
    if (navigationType == UIWebViewNavigationTypeLinkClicked || navigationType == UIWebViewNavigationTypeOther)
    {
        NSURL *url = [request URL];
        if ([[url host] hasPrefix:@"phobos.apple.com"] || [[url host] hasPrefix:@"itunes.apple.com"])
        {
            // Launching our URL should open iTunes or the App Store directly
            [[UIApplication sharedApplication] openURL:url];
            [webView autorelease];
            return NO;
        }
    }

    return YES;
}

With any luck your app should now launch directly into iTunes (after a slight delay while the redirect URL loads up) while that sweet-sweet commission check launches directly into your bank account.

Enjoy!

Update – Someone pointed out to me that there is a different (preferred) way of doing this as per Apple. Check out http://developer.apple.com/iphone/library/qa/qa2008/qa1629.html

Star Wars producer Rick McCallum looking great with ’stachetastic!

December 10th, 2009 0 Comments Star Wars producer Rick McCallum looking great with ’stachetastic!

http://img158.yfrog.com/i/nbx.jpg/

AT&T Thinks I’m an Idiot

December 9th, 2009 0 Comments

As if AT&T’s poor network quality weren’t enough, now they are calling me an idiot. They’re calling you an idiot too.

What I’m referring to is their new ad campaign with Luke Wilson, aimed at fighting off Verizon’s ads claiming it has a vastly larger 3G network (which incidentally, it does). The Verizon ads must be working, because it’s definitely rattled AT&T’s cage. I’m proof it’s working because recently when I needed to buy a 3G card for my laptop to use it on the road during a recent trip, I chose getting a brand new Verizon account over adding it to my existing AT&T account.

So how you ask is AT&T calling me an idiot? It “thinks” that I may be “confused” and “tricked” by Verizon’s commercials into thinking that it doesn’t have standard mobile coverage in most areas. So it’s spending a ton of money on ads making sure I understand that AT&T has a HUGE network. The problem is, Verizon never claimed that AT&T’s general network coverage was smaller. Verizon’s claims that AT&T’s 3G network is paltry when compared to its own (which it is).

I get it, AT&T. You don’t think I’m smart enough to understand the difference between a mobile connection and a 3G connection. But here’s an idea. Rather than spending all that money on fighting a fight that no one actually started, why not put that money into building new 3G towers? Mmmmmm’kay? The cost of a single prime-time spot with Luke Wilson would probably cover the cost of one.

In the spirit of the season I’m starting to think, “every time a Luke Wilson AT&T commercial is shown, an angel loses its 3G connection”…

Zoom MKMapView To Fit Annotations

November 10th, 2009 19 Comments

I thought I would share a handy little piece of code that enables you to zoom the MKMapView control on the iPhone to contain all the annotations that it holds. This should hopefully cut down on your users having to pinch-zoom and scroll to find annotations scattered throughout the map!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView
{
    if([mapView.annotations count] == 0)
        return;
   
    CLLocationCoordinate2D topLeftCoord;
    topLeftCoord.latitude = -90;
    topLeftCoord.longitude = 180;
   
    CLLocationCoordinate2D bottomRightCoord;
    bottomRightCoord.latitude = 90;
    bottomRightCoord.longitude = -180;
   
    for(MapAnnotation* annotation in mapView.annotations)
    {
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
       
        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
    }
   
    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
   
    region = [mapView regionThatFits:region];
    [mapView setRegion:region animated:YES];
}

’stachetastic is an iTunes Staff Favorite!

November 10th, 2009 0 Comments ’stachetastic is an iTunes Staff Favorite!

Thanks iTunes staff for choosing ’stachetastic as one of your favorites!

Read More

You Probably Suck at Interviewing Developers

November 9th, 2009 1 Comments You Probably Suck at Interviewing Developers

If you interview developers for job positions, chances are you suck at it. Did I get your attention? Good.

I don’t like to make sweeping generalizations, because some of you are probably pretty good at it, but I find more and more that people who interview developers are completely missing the point. As I am about to hire new developers myself, I’ve begun to reflect on what I think is important in hiring good engineers. But before I talk about what is important, let’s talk about what I think is unimportant.

Brickmakers

The next time you are in an interview and the interviewer says, “Please write me a function that sorts these values from…”, politely tell them that this is not the right position for you and leave. An interviewer that asks this type of question (and a lot of them do) is invariably someone who has no concept of the bigger picture of modern software development. This question does nothing more than to prove that you can solve a really insignificant problem. Seriously, when was the last time you wrote a sorting algorithm at your job? If you have written one recently then you are either a) not taking advantage of the power of your language or b) really bad at using Google to find code.

Functions and algorithms are bricks, and interviewers that ask these types of questions are looking for Brickmakers (and are usually Brickmakers themselves). Brickmakers are those who can build the most beautiful bricks in the quickest and most elegant way– bricks that look like a million bucks sitting on a shelf all alone. Brickmakers believe that everyone should be well versed in brick making because; well because EVERYONE should know how to make a brick, right? They also believe that if you can’t build a simple little brick, then you really can’t be that smart.

Bricklayers

Frank Lloyd Wright was a pretty bright guy, and as far as I know he never built a brick in his life. Modern software projects are becoming too large and complex to waste valuable time building bricks! A good modern developer is someone who can see the big picture, make sense of complexity and assemble little pieces into something substantial and meaningful. I call these people Bricklayers.

Bricklayers don’t get bogged down in the minutiae. At the end of the day Bricklayers don’t sit back and admire the beauty in the bricks. They see the beauty in the finished product. A good Bricklayer developer will understand the importance of good class organization, structure and overall design. They understand that most projects fail because of large scale and systemic problems rather than a less-than-optimally written function.

To put it simply: Bricklayers are people know how to design and build finished products, not commodities.

Interviewing Brick Layers

So how do I find and interview brick layers? I find that the best way to interview brick layers is not to interview them at all. I treat developers like artists. I would never ask an artist to prove themselves by painting a picture on the spot, and I would never ask a developer to do likewise. In my world, a good portfolio is king. If your portfolio is top-notch, then I only need to establish two things during the “interview”:

1) Do you comprehend what you built? Or in more simple terms, did you really build it yourself?
2) Are you a person I would enjoy working with?

So remember the next time you interview a developer to ask yourself– am I hiring Brickmakers or Bricklayers? I’ll spend my money on a master Bricklayer and buy my bricks at Home Depot.

Cheers,

-jim

P.S. Josh, in case you’re wondering, this does not apply to you : )