InnerBand Tutorial Part 1: Introduction and Functions
Over the course of developing many iOS-based apps for a variety of customers such as Sports Authority, Navy Federal Credit Union, Fuzz Alert, Map My Fitness, and more, you begin to sense a pattern with how you use the iOS SDK and what your coding practices are in Objective-C. An overwhelming sensation that you’re doing a lot of the same things over and over again — in about the most verbose way possible. Let’s face it, Objective-C is not only an ugly language, but the SDK is missing a lot of very basic functionality to get your job done more concisely.
That’s why I built and maintain the InnerBand Framework. It’s a small module that serves as a sidekick of sorts to your normal development. The idea came to me (and its original co-developer, Sean Christmann) following a series of projects where we were using the Three20 framework. The promise of Three20 was that it gave you the tools and added functions that you need to save time architecting your app so that you can focus on the business logic.
So much for promises, right?
Three20 suffers from the taint that many open-source projects can’t shake: It’s practically undocumented and it’s got bugs. What this means is that you’ll spend hours trying to figure out how it works, and when you do, you’ll spend many more hours either fixing it or making it do what you think it’s supposed to do. That’s not saving time.
To make matters worse, Three20 takes the traditional SDK. If you use it to all its abilities, you’ll be building your navigation without using UITabBar or UINavigationController, you won’t be using the table view framework anymore, you’ll be lost to change your status bar color and you’ll be locked into an unwieldy styling framework. Then, when iOS 5 comes out, you need to wait for a whole new slew of updates.
So, after three projects’ worth of using it, I’d gained a ton of experience and knew how to use it pretty well, but found I’d use it less and less the more I knew. I’d scrapped the styling framework, it just didn’t win me enough to overcome all I was losing. I dropped the new table view framework because individual styling of cells became an absolute nightmare. (I yelled out loud once in the office over it.) By the third project, I was having so many crashing issues using modal views (due to added constraints of simultaneously opening and closing them) that I was practically reduced to tears.
And so I wrote InnerBand.
InnerBand is Born
The goals of InnerBand are simple:
- Build a library that complements the iOS SDK rather than override it.
- Make it so simple and integrated that the new functionality feels native.
- Make it quick and easy to install in your project!
When you import InnerBand into your project, you are receiving a set of classes, categories, and macros that augment your daily development in a way that speeds it up without hiding the SDK from you. You can exercise every aspect of it or nothing at all. If you’re using the new Core Data methods to make access easier, you can use the standard methods at any time, too. It’s your choice.
It’s also 100% unit tested. It uses GHUnit to make sure everything that gets added to InnerBand works and won’t fail you. My hope is that InnerBand will speed up your development, not require to become a low-level expert on it’s code to be able to use correctly.
Installation is Simple!
The InnerBand Framework is hosted on github and offers a unique installation method once you’ve downloaded it. You install a minification of InnerBand that encapsulates the entire library into a single .h/.m pair!
Run the minifier with the following commands:
cd InnerBand/InnerBand
../minifier/minify.sh all
This creates a minification that includes the complete InnerBand system. If you don’t care to use the UI components, you can also run this instead:
cd InnerBand/InnerBand
../minifier/minify.sh core
The minified source is copied to your Desktop. Just copy it to your project and import it where needed. I recommend adding the import to your PCH file so you don’t have to worry about doing it everywhere.
You’ll need to add the CoreData framework to your project as well, and then that’s it. Now let’s check out what you’ve gained!
Getting Started
The first thing you’ll want to check out in InnerBand are the functions and macros. If you want to browse these, they are in Macros.h and Functions.h. Here are some highlights.
Boxing and Unboxing Numbers
Gone are the days of bulky NSNumber wrapping! You can convert your primitives to NSNumber with BOX_BOOL(x), BOX_INT(x), BOX_SHORT(x), BOX_LONG(x), BOX_UINT(x), BOX_FLOAT(x), and BOX_DOUBLE(x). Conversely, you can unwrap NSNumber objects with UNBOX_BOOL(x), UNBOX_INT(x), UNBOX_SHORT(x), UNBOX_LONG(x), UNBOX_UINT(x), UNBOX_FLOAT(x), and UNBOX_DOUBLE(x).
These functions are not only quicker to type, they are easier to read and understand when reading the code. Semantics! They are named for what they do and they stand out, which is why they’re among my personal favorites.
Rectangle Magic!
Rectangle manipulation can require some bulky code. For example, the standard procedure for changing a View’s size is to copy the frame, change some part(s) of it, and then reassign back to the View. That’s 3 or more lines of code and is re-written so often it begs to be cleaned up. These functions make it much easier.
Want to shrink up your rectangle? RECT_WITH_WIDTH_HEIGHT(myView.frame, 10.0, 10.0).
Want to move your rectangle? RECT_WITH_X_Y(myView.frame, 20.0, 20.0).
Want to create a series of rectangles, perhaps positioning a set of buttons one on top of another? RECT_STACKED_OFFSET_BY_Y(prevButton.frame, 10.0).
Let’s explain that last one. The function call duplicates a CGRect and then offsets it in the Y direction. In other words, if you’re laying out a set of 3 UIButtons in a vertical stack (ala LinearLayout in Android), you could write code like this:
UIButton *a = ...create my button somewhere...;
UIButton *b = ...create new button...'
RECT_STACKED_OFFSET_BY_Y(a.frame, 10.0);
UIButton *c = ...create new button...'
RECT_STACKED_OFFSET_BY_Y(b.frame, 10.0);
This results in three buttons flowing top to bottom with 10-pixel gaps between them.
Math Helpers
These are intended to solve some common maths for you. Here’s a sample:
- DEG_TO_RAD(180.0)
- RAD_TO_DEG(1.0)
- RGB256_TO_COL(224)
- COL_TO_RGB256(0.7)
One of the most common idioms, forcing a number to be constrained between a minimum and maximum, is especially cumbersome because your code might do it with something that looks like MIN(MAX(myNum, 0), 100). It’s a little backwards to write, can easily have a bug in it, and certainly is going to make the next developer take quite a bit of time to decipher. Want to constrain between 0 and 100 in InnerBand. Try this:
- CONSTRAINED_INT_VALUE(myNum, 0, 100)
- CONSTRAINED_DOUBLE_VALUE(myNum, 0.0, 100.0)
Done deal. Their use should be clear. :-)
Where Do We Go From Here?
Well, that was only a very small part of the macros and functions InnerBand provides. They’re always being added, so explore the current codebase for yourself! In Part 2: Core Data Quick and Easy! I’ll review the Core Data Store, a handy set of methods that make using Core Data much easier!
Coding Kata Exercises
Coding Kata are simple problems you can solve using TDD techniques to help you practice unit testing and development with various platforms and languages as well as to “sharpen” you up for the day. Get the brain working. The fingers moving. You know. :-)
I’m compiling a list of Kata to practice with here. Give one a try:
- Convert Arabic Numbers to Roman Numerals
- Fizz Buzz
- Calculator
- ROT13 Encoder
- Logic Gates
- Fibonacci
- Prime Numbers
- Time is Relative
- A Better Array (iOS-specific)
My Hero, Heroku
A friend and co-worker of mine, Tony Hillerson, was once scheduled to rebuild a backend system for a client of ours. His idea was to replace our tiny little PHP friend with a Heroku implementation. He described it as Rails on a cloud and I kept it in mind cause I loves me my Rails. Amiright?
About 8 months later, a customer project came about and I felt Rails would be the perfect solution for the services and web site he needed. (Full disclosure: it always is.) I decided to look into Heroku and, let me tell you, what a success the project has been!
Heroku, despite being a cloud service, is the most transparent cloud service imaginable. To use it, you simply create your rails project and then connect it to Heroku with a couple simple commands. Heroku dynamically generates a name for your site. Now, just push your site to Heroku and all of your migrations and restarts happen automatically! (Heroku is married to git in order to do this, which is fine, because I love git, too!) It’s truly magical. You get your web site on the cloud with no catches.
AND IT’S FREE! (YES, FREE!)
Well, OK, it’s free if you don’t need any extra power. Heroku uses the concepts of web dynos (processing power) and worker dynos (increased capacity). You can buy extras of these for $36. For $0, you still get good performance and, in the best interest of developers, you won’t have to pay anything while you’re building things out.
Once the project is over, you can leave it to the customer to decide if they want to increase the Heroku power behind their site. In my first case, there was no need. The site runs for free because the server needs are low. In other cases, a few dynos cost next to nothing but have a drastic effect.
Mmmmm, scaling…starting at free.
I’m certainly spoiled by Heroku. You should get spoiled, too. Give it a try!
Introducing WebImageView
As a big fan of SDWebImage, I was both shocked and dismayed that the Android world had no such component. If you’re not familiar, SDWebImage is an iOS UIImageView extension that lets you set Web URL’s and have them automatically loaded and cached for better performance later.
Often, a developer can get away with their own loading if a single screen has a single graphic to display. Not so for table views, which not only require a lot more concurrent loading but need to be able to properly handle cancelations efficiently as items scroll onto and off the screen.
So, Rapture In Venice has authored the URL-loading, caching WebImageView for Android developers and it’s available for free on GitHub. Documentation included.
Enjoy. :-)