Rapture In Venice, LLC

:: Freelance iOS Development & Team Augmentation

Task List Pro now FREE — Here’s Why

Today, I made a few decisions with the small, but proud, set of apps that Rapture In Venice calls its very own on the App Store.

First, and most importantly, Task List Pro is now free. Free as in beer. The reason why I’m doing this is because (A) I don’t market, advertise, or rely on sales of the app and (B) I feel it’s the best task list app on the App Store and I want everyone to use it. I’m proud of the decision to finally make this great app free, and based on the download numbers from yesterday it looks like a lot of you are taking advantage!

Next, as a logical followup to this move, I’ve removed Task List from the store. This makes sense because the Pro version has all the same features — plus more. I have no plans to update Task List, nor do I see any logical reason for anyone to download it in lieu of the Pro version…so there we go, it’s gone. :-)

So there we go. Download Task List Pro for FREE.

Finally, I made the decision to make Smart Stacks, our excellent flash card app for kids and adults alike, free. Again, free as in beer. For this app, sales have never been strong as it is left to compete in a competitive kids’ entertainment category that sees apps backed my millions of dollars. Again, as with Task List Pro, I don’t market or advertise this app and, therefore, I’d rather see people use it than not.

Download Smart Stacks for FREE.

  • Print
  • Facebook
  • Twitter

, , , ,

Tutorial: Using RaptureXML Like A Pro!

In a world with evolving data formats such as YAML and JSON, it’s remarkable how much we still use XML, but what’s even more remarkable is just how bad the XML parser offerings are for iOS. Whether you use the native NSXMLParser stuff or any of the many third-party frameworks, you’re forced to write a ton of XML boilerplate just to get access to the data you need. Coming from an ActionScript background, I missed E4X, and that’s why I wrote RaptureXML.

What is RaptureXML?

RaptureXML, born in September, 2011, and written by Rapture In Venice, makes XML parsing so ridiculously easy it’ll make you cry for all the time you used KissXML or the Google toolkit. (No offense, guys.)

Originally, RaptureXML was an API wrapper over TBXML. This was done because it was a quicker path to completion and was needed for an enterprise app being worked on at the time. After reading and writing pages of boilerplate XML code that obscured the code’s real intent, I decided there had to be a better way. The idea was to use blocks as a way of pushing the boilerplate into the framework code and the result, I hope, has made XML parsing child’s play for iOS developers worldwide.

Since its early days, RaptureXML has shed its dependence on TBXML and works directly with libxml2, a powerful (albeit cryptic) library supported by iOS. The result of the conversion is faster performance and only one class you need to add to your code!

Configuring RaptureXML in XCode

Configuration is a breeze. You can grab the latest version of RaptureXML here. Setup is as follows:

  • Copy or add the RXMLElement.h and RXMLElement.m files to your project any way you like.
  • Import RXMLElement.h wherever you’ll use it or add it to your PCH file for global use.
  • Link the libz and libxml2 frameworks into your project.
  • In your build settings, for the key “Header Search Paths”, add “$(SDK_DIR)”/usr/include/libxml2

That should do it. Ready to use it now?

RaptureXML In Action!

I’ll demonstrate how to use RaptureXML by using this (faux) XML sales data for all of our examples:

<sales published="2012-05-29">
    <app name="Rigatoni Fighter" for_iphone="0" for_ipad="1">
        <category>Fighter</category>
        <year>2009</year>
        <support>
            <representative type="product">
                <first_name>Kerr</first_name>
                <last_name>Jerry</last_name>
            </representative>
            
            <representative type="pr">
                <first_name>John</first_name>
                <last_name>Lane</last_name>
            </representative>
        </support>
    </app>

    <app name="Mall Balls" for_iphone="1" for_ipad="1">
        <category>Puzzle</category>
        <year>2010</year>
        <support>
            <representative type="product">
                <first_name>Steve</first_name>
                <last_name>Farmer</last_name>
            </representative>
        </support>
    </app>

    <app name="Number Kruncher" for_iphone="0" for_ipad="1">
        <category>Spreadsheet</category>
        <year>2011</year>
        <support>
            <representative type="product">
                <first_name>Kerr</first_name>
                <last_name>Jerry</last_name>
            </representative>
            
            <representative type="ads">
                <first_name>Kelly</first_name>
                <last_name>Mackerie</last_name>
            </representative>

            <representative type="pr">
                <first_name>Tom</first_name>
                <last_name>Johnson</last_name>
            </representative>
        </support>
    </app>

    <app name="Kill Tower" for_iphone="1" for_ipad="0">
        <category>FPS</category>
        <year>2011</year>
        <support>
            <representative type="product">
                <first_name>Zach</first_name>
                <last_name>Parise</last_name>
            </representative>
            
            <representative type="ads">
                <first_name>Kelly</first_name>
                <last_name>Mackerie</last_name>
            </representative>
        </support>
    </app>
</sales>

If you’re coding alongside this tutorial, I recommend cut and pasting this into a file called data.xml and include it in your project.

Loading the XML

Our first step will be to load this XML. How do we do that? Very simple:

    RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"data.xml"];

Well, that was easy. You’re done! From here, everything is just picking out specific data from the XML you loaded. Also, there’s a lot of ways to load XML, and you can do it over the network, NSData, or from a whole bunch of other sources. Just autocomplete after element and you’ll find something that suits you. :-)

Anyway, the important thing to know is that the rxml variable holds your XML starting at the top level tag: sales. Now, let’s look into pulling out the data.

Attributes

Pulling attributes is simple (as is everything), and RaptureXML can even do some conversions for you. First, let’s pull the date the data was published:

    NSString *publishedTimestamp = [rxml attribute:@"published"];

Remember, the rxml variable represents the top-level tag, so we can pull the attribute straight from it. See it in the XML? Make sense? Good, let’s move on. How about we grab the version number?

    NSInteger version = [rxml attributeAsInt:@"version"];

RaptureXML handles the conversion for you, but just make sure it’s an integer you’re grabbing or you’ll get an exception. You can convert to double as well.

Tag Content

Aside from attributes, tags also have text content. In RaptureXML, all text is merged for a tag, but you probably don’t need to know that. Just know you can access the text of a tag with:

    NSLog(@"TAG TEXT: %@", element.text);

Just like with attributes, you can have the text automatically converted by accessing it with element.textAsInt or element.textAsDouble.

Oh, and if you want the name of the tag, that’s easy, too:

    NSLog(@"TAG NAME: %@", rxml.tag);

Child Tags

The real power in RaptureXML becomes evident when you want to process the child tags. That is, crawling through your XML tree in search of the data you need.

With other XML frameworks, this entails a lot of code that involves string comparisons, subclassing, and/or looping unnecessarily over children you don’t care about while obscuring your business logic. With RaptureXML, the syntax is so direct and clear, your code practically documents itself.

Let’s say you wanted to access all your app tags and print out the name of each app. Here’s how you do it:

    [rxml iterate:@"app" usingBlock:^(RXMLElement *element) {
        NSString *name = [element attribute:@"name"];
        NSLog(@"APP NAME: %@", name);
    }];

The key to this code is the iteration query, a simple map to the tags you’re looking for and a block that processes each element that matches. Yet, looking for children one level deep doesn’t demonstrate the true power of the syntax, so let’s pretend we want to print the years that each app was made instead:

    [rxml iterate:@"*.year" usingBlock:^(RXMLElement *element) {
        NSInteger year = [element textAsInt];
        NSLog(@"YEAR OF RELEASE: %i", year);
    }];

Whoa, what is that? What the query string there is saying that we look at all child tags and then grab the year tag (should there be one). This might take 6-8 lines of boilerplate alone, but it takes no more lines then we needed for even a simple access before.

Note, in the query syntax, that child tag names are divide by periods (.) and the last one specified can result in multiple matches. If previous child tags have multiple matches, only the first is chosen. Using an asterisk will choose all. You can also use an asterisk as the last child tag to select them all.

Here’s how we print the names of all the app representatives.

    [rxml iterate:@"*.support" usingBlock:^(RXMLElement *supportElement) {
        [supportElement iterate:@"representative" usingBlock:^(RXMLElement *repElement) {
            NSString *firstName = [repElement child:@"first_name"].text;
            NSString *lastName = [repElement child:@"last_name"].text;
            
            NSString *name = [NSString stringWithFormat:@"%@, %@", lastName, firstName];
            NSLog(@"REP NAME: %@", name);
        }];
    }];

Here we nested a couple queries to keep the code more specific.

Alternative Ways To Get Child Tags

Aside from the core iteration technique, you can access children a couple other ways. One, and you’ll use it a lot, is to grab children directly from an existing element:

    RXMLElement *categoryElement = [appElement child:@"category"];
    NSLog(@"CATEGORY: %@", categoryElement);

Notice something strange? The description method of RXMLElement has been overridden to return the tag text, so you can drop the .text when logging, but be sure to specify text explicitly in other cases:

    RXMLElement *categoryElement = [appElement child:@"category"];
    NSString *category = categoryElement.text;

Another way you can examine children is to retrieve them as an NSArray and then, well, do whatever you want with them. Here’s another way to print categories:

    NSArray *apps = [rxml children:@"app"];
    [rxml iterateElements:apps usingBlock:^(RXMLElement *appElement) {
        NSLog(@"CATEGORY: %@", [appElement child:@"category"].text);
    }];

You can write this in any number of ways. An RXMLElement is an RXMLElement. So you can use a simple for/in if you like, too.

Using XPath

The query iteration is nice, but there are some things you might want to do that require more power. This is where XPath comes in. Let’s say we want all the representatives for apps made in 2011:

    [rxml iterateWithRootXPath:@"//app[year=2011]/support/representative" usingBlock:^(RXMLElement *repElement) {
        ...
    }];

There’s a lot of power in XPath, definitely take a look.

One key thing to know about XPath and how it integrates with RaptureXML is that all of your queries are from the original root of the XML tree. Each element maintains it, so you can use any child tag (RXMLElement) you want. But, keep it in mind.

Summary

RaptureXML is a powerful tool for processing XML. Use it to keep clear business logic in, and ugly boilerplate out. Use it for the iteration query, XPath, or traverse the XML yourself.

Just use it.

  • Print
  • Facebook
  • Twitter

, ,

Pragmas Aren’t Just For Marks

Ask an iOS developer what a #pragma is and more times than not they’ll tell you, “It’s a directive that lets you group your functions in XCode’s method index thingy.” OK, I confess, that’s what my answer would’ve been not too long ago!

The truth is, there are plenty of #pragma usages out there and some of the more low-level minded developers use them quite a bit! In many cases, they can be abused and make reading source code a real downer, but let’s review some of the more useful ones and embiggen ourselves. :-)

NOTE: This blog will only refer to the Clang compiler (LLVM) and not GCC, though some of it still applies. Since I don’t see any reason to be using GCC anymore, I’m not going to explicitly talk about it.

Explicit warnings and errors

The compiler is a robot; it will mark what’s wrong with your code using a set of rules that’ve been defined by Clang. But, every so often you’re smarter than it. Often, you might find some offending code that you know will lead to problems but, for whatever reason, can’t fix yourself at the moment. You can explicitly signal errors like this:

- (NSInteger)divide:(NSInteger)dividend by:(NSInteger)divisor {
    #error Whoa, buddy, you need to check for zero here!
    return (dividend / divisor);
}

You can signal warnings similarly:

- (float)divide:(float)dividend by:(float)divisor {
    #warning Dude, don't compare floating point numbers like this!
    if (divisor != 0.0) {
        return (dividend / divisor);
    } else {
        return NAN;
    }
}

These warnings and errors will show up in XCode’s Issue Navigator like any other warning and error:


The alternative is running a git blame and emailing the developer, but it might take too much time and it’s nicer to signal the issue right where the code is. I’ve even seen developers mark these warnings when writing their own code as a reminded to change the code later. Use it however it’s most useful to you and your team.

Oh, and strictly speaking, this isn’t a #pragma, but it’s in the same family and #pragma message behaves the same way as #warning.

Temporarily disable a compiler behavior

While most iOS developers don’t futz around much with compiler options, it’s these options which control how strictly to check (or not check) your code for errors. Sometimes, though, you want to make an exception…just once. The best way to do this to put your offending code on an island with no law.

Here’s something I ran into with InnerBand: When you use ARC, the compiler inserts memory-management calls for you. There are cases, though, where it can get confused. One such case is when you use NSSelectorFromString to have a dynamically-named selector called. Since ARC can’t know what the method will be and what kind of memory management to use, you’ll be warned with something like, “performSelector may cause a leak because its selector is unknown”.

If you know your code won’t leak, you can suppress the warning for just this instance by wrapping it like this:

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                            
    [myObj performSelector:mySelector withObject:name];
    
    #pragma clang diagnostic pop						

Note how we disable the -Warc-performSelector-leaks check by pushing and popping the change around our code. This assures us we don’t disable it globally, which would be a huge mistake.

There’s a large number of options you can disable if need be, but you’ll have to consult The Clang User’s Manual to learn about all of them.

Suppressing warnings for unused variables

It’s useful to be told that a variable you’ve defined is going unused. In most cases, you want to remove these references to improve performance (however slightly), but sometimes you want to keep them. Why? Perhaps they have a future usage or the functionality is only temporarily removed. Either way, you can suppress the warning with #pragma unused:

- (void)giveMeFive {
    NSString *foo;
    #pragma unused (foo)

    return 5;
}

Now you can keep your code in place without the compiler complaining about it. And yes, that pragma needs to go below the offending code.

Conclusion

Pragma are there to help you, but don’t abuse them. Looking at code loaded up with preprocessing code and pragmas is like reading code with gotos, a total headache. Use them appropriately!

  • Print
  • Facebook
  • Twitter

InnerBand Tutorial Part 3: The Magical Message Center

This is the third part of a multi-part series on the InnerBand Framework. Previously, in InnerBand Tutorial Part 2: Core Data Quick and Easy!, I reviewed the Core Data Store and how it makes working with Core Data actually…kinda fun!

From the community of InnerBand developers, I’ve heard nothing but compliments and happiness about what it does for them. They love the macros and functions that keep their code concise, the category methods that are so useful they can’t imagine living without them, the Core Data Store which brings them sanity, and then classes like IBAlertView which demonstrate why blocks are so darn awesome. I love that they love InnerBand, but there’s one piece of it that they never seem to mention: Message Center.

I can’t blame them. For one thing, it’s never been documented. Second, if any enterprising developer did read analyze the code, they would likely be left with no motivation to use it. Is that assessment fair? NO.

So, what does it do then?

What Is the Message Center?

On the face of it, the Message Center is very similar to the NSNotificationCenter provided by Apple. It allows objects to listen for notifications (dispatch messages) from other objects, send them, include message-specific information by way of an NSDictionary, and stop listening as well. The familiarity is intentional so that other iOS developers would pick up on it quickly.

Let’s see how the basics work. As an example, let’s presume we have two objects, myWeatherWidget and myWeatherReporter. When myWeatherReporter updates the weather forecast, it notifies its listeners. When myWetherWidget gets the notification, it updates its UI to reflect the new information. Got it?

Here’s the most basic way myWeatherReporter can notify its listeners:

[MessageCenter sendGlobalMessageNamed:MSG_FORECAST_UPDATED];

The MessageCenter is used in static form; no need to access a singleton or defaultCenter. This particular code dispatches a global message so that you only need to provide the name, but you can provide the source object so listeners can be more discriminating. Everything else is done for you. If you were using the NSNotificationCenter, you’d of had to specify the source object as nil to get the “global” behavior. Note, also, that MSG_FORECAST_UPDATE is any arbitrary, unique string (Personally, I tender to define it as the same name as the constant).

If we want to pass along the weather information along with the message, we’d do it like this:

[MessageCenter sendGlobalMessageNamed:MSG_FORECAST_UPDATED withObjectsAndKeys:weatherInfo, @"info", nil];

There are actually several versions of the above you could use depending on your style preference, such as with sendGlobalMessageNamed:withUserInfoKey:andValue:, but they all do the same thing which is to package data in the message’s userInfo property.

For an object to receive the message, it must register itself as a listener and provide a method:

- (void)viewDidLoad {
    [super viewDidLoad];
    [MessageCenter addGlobalMessageListener:MSG_FORECAST_UPDATED target:self action:SEL(forecastUpdated:)];
}

- (void)forecastUpdated:(DispatchMessage *)msg {
    NSDictionary *userInfo = msg.userInfo;
    ...
}

Self-explanatory. Again, you don’t have to make these global messages if you want to be more specific. Also, you don’t have to accept the DispatchMessage argument if you don’t need it. Remember, too, that your objects should remove themselves as a listener before being deallocated. I tend to make the object add itself as a listener in viewDidLoad and unregister accordingly:

- (void)viewDidLoad {
    [super viewDidLoad];
    [MessageCenter addGlobalMessageListener:MSG_FORECAST_UPDATED target:self action:SEL(forecastUpdated:)];
}

- (void)viewDidUnload {
    [MessageCenter removeMessageListenersForTarget:self];    
    [super viewDidUnload];
}

- (void)dealloc {
    [MessageCenter removeMessageListenersForTarget:self];    
}

In 99% of cases, when you unregister a listener you mean to unregister for everything the object is listening to (i.e., the object is going away). If you want to stop listening to just one type of message, there are plenty of methods for handling that case such as removeMessageListener:target:action:.

This is the basic Observer pattern as Message Center implements it. Minus a little more conciseness, you already have that with NSNotificationCenter. Now, let’s see why you’ll never want to use NSNotificationCenter ever again!

What Makes Message Center Awesome?!

What makes Message Center superior to NSNotificationCenter is that it helps you get your real-world work done much faster. For this example, I’ll be referencing the Movie Poster Fetcher which you can download and use as inspiration. What this little app does is let you enter in the name of your favorite movie and it will display the movie poster and some other information. Seems simple enough, but keep in mind that an app like this has a few components you’d normally have to deal with:

  • You need to construct the GET request to get the movie poster information.
  • You need to create handlers for receiving the response as well as the streaming data.
  • You need to spin a thread that will process the response.
  • You need to handle errors.
  • You need to notify listeners that you have the new data ready.
  • You need to display that information.

Everyone, and I mean everyone, writes this code differently. If you like to use NSNotificationCenter, you might notify once when the data comes in and then that listener will notify a second time when it’s done processing it. You might use an asynchronous NSURLRequest, NSOperationQueue, dispatch queues, ASIHTTP, SVHTTPRequest, or any number of other methods. It really makes for a great interview challenge, eh?

Here’s how you would do it with the Message Center:

- (void)requestMoviePosterForTitle:(NSString *)title {
    NSString *url = @"http://www.imdbapi.com/?i=&t=[TITLE]&r=XML";
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:title, @"TITLE", nil];

    __block HTTPGetRequestMessage *get = [HTTPGetRequestMessage messageWithName:MSG_POSTER_RECEIVED userInfo:userInfo url:url processBlock:^(NSData *stream, NSInteger httpResponse) {
        if (httpResponse == 200) {
            RXMLElement *rxml = [RXMLElement elementFromXMLData:stream];

            // process xml and supply it to the listeners
            if ([rxml isValid]) {
                RXMLElement *movieElement = [rxml child:@"movie"];
                
                [get setUserInfoValue:[movieElement attribute:@"title"] forKey:@"title"];
                [get setUserInfoValue:[movieElement attribute:@"poster"] forKey:@"poster"];
            }
        }
    }];
    
    // dispatch
    [MessageCenter sendGlobalMessage:get];
}

Wait, wait…WHOA, WHOA. Stop right there! I’ve seen that look before. This is the part of the tutorial where you’re disappointed to see all this unfamiliar, fairly bulky code and you just lose confidence that this is the framework you’ve been looking for all your life. Well, no, no, no, you keep reading! Look at the code again! This code does everything. It’s performing the HTTP GET request, it’s checking the response, it’s even processing the XML! (Thanks to RaptureXML!)

Let’s review it line by line:

  • Lines 2 – 3 – We define the URL with parameters that will be substituted automatically. In this case, [TITLE] will be replaced by the title string we provide. In the real world, the URL would be a constant, and this is a cleaner syntax to read than a string formatter. (But you’re free to do it yourself if you like. No biggie.)
  • Line 5 – We define the HTTP GET request. This is the magic! The request is a message itself and it’ll process the request before dispatching to the listeners. Essentially, you’re telling this thing to do the request, and when it’s all done let the listeners know. This is remarkably different from what you usually see which is a message simply having a name and no other utility.
  • Line 6 – This is the processing block. More magic! The idea here is that we’ll process the response immediately when it comes, and only when that’s been done do we notify the listeners. The reason we do it this way is because if we waited for a listener to process the XML, then we could only let one listener handle it. That, or every listener would have to process the XML itself because the order can’t be guaranteed!
  • Lines 7 – 12 – This is RaptureXML doing its thing. It tears apart the XML in a laughably tiny amount of code.
  • Lines 13 – 14 – Here’s where we take the two bits of information we care about (movie title and poster URL) and add them to the user info of the message. Every listener will now get this information! Note that while you can add information anytime you like, you shouldn’t really do it in the listeners themselves because the order can’t be guaranteed. However, in a processing block, it’s perfect! (Obviously, you can store the information in Core Data, too.)
  • Line 20 – This is where we dispatch the message. All the magic happens only after we dispatch. Remember, the processing block is called before the listeners get notified!

Look at this code and really think about it. There’s no wasted space. Everything does it’s job succinctly, efficiently, and clearly. And in this tiny amount of space, we’ve written all the web service integration code we need.

With Message Center, we can do HTTP POST as well. We can also define our own message subclasses, too, that we can re-use over and over again! Dump your JSONKit processing code in a message and have it automatically decoded for you en route to your listeners. Wrap sound effects in messages. Anywhere you take input and produce output you can create a message that will do it for you while you dispatch!

What Else Does Message Center Do?

If that’s all you got from Message Center, trust me, you’re gonna live a happy life. But there’s more, but I’ll offer it with one caveat: you might not ever need it. The reason is that most of this stuff preceded the process block style you see above. (InnerBand itself preceded blocks.) For example, a SequencedMessage lets you chain together a set of messages in such a way that the output of each message is fed into the input of the following message like a human centipede. How is this valuable? Think if you had a message that handled HTTP GET requests and a message that processed JSON. You could chain these together into one SequencedMessage, dispatch, have the HTTP GET request your data, have the JSON message process your data, and only then would all the listeners receive it without any of them having to handle the processing!

Cool, right? But since that’s the prototypical use case, processing blocks blow it away because there’s no need to subclass and all the code stays in one place. Still, the SequencedMessage lets you take advantage of DispatchMessage subclasses that you create and chain them together like high-tech legos. It’s good to be aware of.

While subclassing is great for chaining, also keep in mind that BlockBasedDispatchMessage alleviates even that. By providing your input and output handlers as blocks, you avoid the hassle and bulk of new classes. Be sure to check those out as well!

Summary

The Message Center is a similar, but more powerful, version of the NSNotificationCenter that fundamentally redefines the role of the message. Instead of just being a named thing, it’s a named thing that performs functionality before it dispatches to its listeners, either synchronously or asynchronously. Processing blocks serve as guaranteed, called-first code that empowers you to have multiple listeners without having to split the flow into two parts, one listener processing the response and the other listeners to update based on that new data.

In its most basic form, Message Center lets you loosely couple message sending between components of your application. In its most useful form, Message Center lets you send HTTP requests, process the responses, and then notify listeners of the data in one short, sweet step!

Again, take a look at the Movie Poster Fetcher and see the magic for yourself!

  • Print
  • Facebook
  • Twitter

, , ,

I Have An Idea for an App! Now What?!

It’s 10:00 AM, you’re in your office (or better yet, at home on your couch) dreaming up million-dollar app ideas when — BAM! — like a bolt of lightning it hits you. EUREKA! You have conceived of The Next Big Thing™: an app that will change the world, or at the very least provide your company a hefty income boost (and for you a big, fat bonus). You call up your boss and tell her your brilliant idea and she concurs, “Make it happen, fast!”

And now. All you need to do. Is find someone who can build. Your app…………..huh.

Well, how the heck do you go about doing that? The Internet is a horrifying place after all. You start with a quick google “i want to create an app” and find App Cooker. Hey, an app to make an app! This’ll be easy, maybe you can do it yourself, too! You read through it a little bit and then, meh, your excitement dwindles. It’s just another development environment. You’ll still need to hire someone to do it for you.

(It’s also worth noting that you not only still have to write the app, but you’ll be doing it with App Cooker instead of the Apple SDK, thereby giving you only a small fraction of the talent pool to draw upon when hiring.)

Stiff upper lip! Undeterred, you google “iphone app developer”. Better! Hmmm, Apple link, Apple link…ah! Here’s iPhoneAppQuotes.com. Let’s see, you give your contact info and…yadda yadda yadda…a company will contact you. What company? Where are they located? Where can you find some all-important examples of their work? I mean, are you willing to spend an hour or more of your precious time talking to some company you’d never want to work with anyway?

Take a closer look at the site. The top quote from the site (as I read it right now) is for Count Trackula. Sounds like the developer they were paired up with did a good job. Let’s take a look at the app:

Wait, it’s spelled Count Tracula? They didn’t even spell it right? And whoa! Look at that app, it’s horrible looking! Apparently some iPhone novice signed up to get quotes and won the bid! Do you want to be showing an app like that to your boss?

That product isn’t going to change the world. It may not even get downloaded much at all.

Alright, alright, don’t be depressed. Cheer up! You won’t get an app that looks like that unless you make a seriously bad choice in who you entrust your app to. But what choice should you make? Well, you can’t decide on who should create your app until you have an idea of the types of options you have.

So, let’s talk about the three kinds of app makers you’ll find out there: The Big Firm, The Lone Consultant, and the Streamlined Mobile Shop.

The Big Firm

The Big Firm is a very common first destination for most people who’re looking to build an app. Why? Because these companies have huge budgets for marketing and PR and you’ll find a seemingly endless supply of uninteresting press releases flooding the search engines.

You can’t help but find them, but does that make them the best choice?

These big firms mask a dirty little secret. Behind their polished façade, you’ll often find a technical company with a high turnover rate, low-balled proposals that stress their development teams, and a large number of sub-contractors who are the ones working on your app. In other words, they’re publicized middle men.

As a member of one of these Big Firms, I once saw an entire 8-man team filled almost entirely by consultants hired in a matter of 2 days. None of them knew each other or were associated with the Big Firm in any way. In other words, the client could have had the same development team at half the cost if they’d just interviewed and found the team itself!

This probably isn’t what you want. These Big Firms work out better for much larger clients who aren’t always looking for the best team for the job but rather tangible accountability. Someone that they can sue if things don’t go exactly how they want. If your company restricts the use of open source applications because it requires support agreements with its software vendors, then this is the choice for you.

Cost can also be quite prohibitive. Hourly rates for the Big Firms range from $125 to $175. And you’re paying for everybody who works on the app: developers, designers, project managers, testers, and sub-contractors. Just one meeting alone with them can reasonably cost you $5,000. Wow.

It’s not all bad, though. The Big Firms often carry some sway in the industry. It can be beneficial to have your app linked to one of these companies. They’ll help promote your app, too, and since they have so many resources at their disposal you’ll never be abandoned. There’ll always be someone available to work on your app.

It’s a big cost for a big team and a quality result, but if a six-figure iPhone app isn’t your cup of tea, is there a cheaper option to go with?

The Lone Consultant

Affordable, available, and offering the most direct communication possible, the Lone Consultant is the best choice for the truly small budget.

Here’s the truth about the Lone Consultant that the Big Firms don’t want you to know: the Lone Consultant used to work for the Big Firms. Me included. In general, your typical Big Firm will pay an employee approximately 25-35% of the hourly rate they are billing to you, the client. And so one day that employee, realizing that they’re the ones who are creating the apps for the Big Firms’ clients, decides to go independent and leave.

Yes, they’ll have to go out and find their own clients now, but they’ll be paid more handsomely for the same work they were doing before. Remember when I said middle man? The Lone Consultant will charge an hourly rate between $50 and $100. Why can they charge a lot less? Because you’re paying them directly. They’re making more; you’re paying less. Everyone wins!

Additionally, you can talk to the Lone Consultant directly. This saves you time not having to negotiate project details through a Project Manager, whom you’ll be talking to with the Big Firm.

The Lone Consultant is a fine choice, but there are some pitfalls to be mindful of. First, they’re going to be a developer, so you need to make sure you have an understanding of where the design talent will come from — if any. You might be responsible for finding that talent on your own, too, which leads to the biggest problem: you get to play Project Manager!

In some cases, this may be what you want, but most likely you’re looking for someone to create your app because you have no idea how to do it yourself. Managing a technical project isn’t easy, especially if you have hard deadlines. What will you do if the developer quits the contract? Can you find someone willing to take over an abandoned codebase? Is the designer overcharging on their hours? How would you even tell if they were?

If you’re willing to take on the responsibility, the Lone Consultant is the most cost-effective option. But, if the Big Firm is too bloated and the Lone Consultant requires too much micro-management on your part, what is the reasonable alternative?

The Streamlined Mobile Shop

The Streamlined Mobile Shop combines the team effort of the Big Firm with the more efficient communication of the Lone Consultant. Hourly rates range between $75 and $125 and fixed bids are common as well. The Streamlined Mobile Shop is employed by a handful of people, likely all designers and developers, so there’s no expensive overhead you’ll have to pay for. They’ll manage your project for you and give you better quality work per dollar than the Big Firm can.

My favorite aspect of the Streamlined Mobile Shop is that it’s made up of some of the most dedicated people. These groups are already stocked with great talent, but since the group is kept small, there’s great camaraderie. And the good mood will make for a better working relationship for you, too.

Let’s Break It Down, Then

Now that you have a good idea of who to choose, who’s it gonna be? My recommendation, if your budget allows, is to go with the Streamlined Mobile Shop because you’ll get the best service at the most reasonable cost. It’s why I’m a part of one. Yet, if you’re organization is too big or too small, it may not be possible to in this direction.

What about cost? The best comparison I’ve heard is that the price to have an app developed is almost exactly the price of a car. Which car? Well, for a small app that does one or two things, it’s a cheap car, around $10,000. It includes a lot of the overhead of a project: architectural development, screen work, and design. From there, price scales up slowly depending on how much you need the app to do. A common component, networking, always requires a lot of edge testing. Fancy UI flourishes take time to design and create flawlessly. A big app, with nice UI, is like a fancy car running you about $60,000. A banking app that has to take security into consideration, along with mission-critical execution, can easily run 6 figures.

So, there you go. You still need to make a choice! What will it be? Let’s summarize everything we’ve talked about now.

  The Lone Consultant The Streamlined Mobile Shop The Big Firm
# of Employees 1 2-25 26-200+
# of Concurrent Projects 1-2 2-3 4-8+
Who You’ll Talk To Developer CTO or Lead Developer Project Manager
Hourly Rate
(per person)
$70 – $125 $85 – $150 $125 – $175
Minimum Budget to Do Business $1,000 $5,000 $25,000

So there we go. Well, good luck with that app. I hope to see it in the App Store soon! :-)

  • Print
  • Facebook
  • Twitter

Previous Posts Next posts