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.
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.
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!
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! :-)