Design Tip: Never Use Black by Ian Storm Taylor

by Tom Bennett

But I must have been thinking the same thing, because one of those days in art class Mrs. Zamula came in with a blue light bulb to prove it. She screwed the bulb into a clamp-light, plugged the light in and clamped it to a stool. Then she got a pure-white ball from her cabinet full of pure-white things (that she kept for figure drawing exercises) and placed it on a pure-white pedestal, under the light. And sure enough, when she turned on the blue light, the shadow cast by the ball was an orange tint, not black.

Thoughts on RestKit

by Tom Bennett

I had the opportunity to use RestKit recently, and wanted to quickly post my thoughts.

RestKit is a handy framework to easily convert JSON or XML data obtained from a REST endpoint (the ease of use can be seen in this tutorial. In addition to converting a JSON response into actual objects, the framework offers caching via CoreData. Really great stuff. There's one catch though: RestKit relies on old version of AFNetworking, version 1.3.3 or so. As a result, using RestKit prevents an app from taking advantage of AFNetworking 2.0. I think for many this would flat out be a dealbreaker. While the developers are supposedly working on this, I haven't really heard anything regarding their current progress, so I wouldn't bet on seeing it emerge any time soon.

In summary, RestKit is a great means of transforming a REST response into actual objects you can use in code; but if you plan on using AFNetworking 2.0 (and if you're considering RestKit, you probably should), the dev lag makes this a non-starter.


Balancing Line Length And Font Size In Responsive Web Design

by Tom Bennett

Interesting piece discussing making written content legible on the web, with a particular focus on scaling on mobile devices (the same advice can easily be extended to apps). The article touches on something that is too easily ignored: line length.

If a casual reader gets tired of reading a long horizontal line, then they’re more likely to skim the left edge of the text. If an engaged reader gets tired of reading a long horizontal line, then they’re more likely to accidentally read the same line of text twice (a phenomenon known as “doubling”).

65 characters (2.5 times the Roman alphabet) is often referred to as the perfect measure. Derived from this number is the ideal range that all designers should strive for: 45 to 75 characters (including spaces and punctuation) per line for print. Many web designers (including me) apply that rule directly to the web.

Basic advice: optimize the font size for legibility, then fine tune the line measure. Bonus tip: keep line height at 150% the font size.

Swift has reached 1.0

by Tom Bennett

Swift version 1.0 is now GM.

You can now submit your apps that use Swift to the App Store. Whether your app uses Swift for a small feature or a complete application, now is the time to share your app with the world. It’s your turn to excite everyone with your new creations.

Android Performance Tips

by Tom Bennett

While getting ready to write a new Android app, I decided to see if there might be any neat tips and tricks in the Best Practices section on the Android developer site. Boy was I not disappointed! I've only reviewed 2 sections so far, those on Performance and Memory Management, but I'm eager to tackle the rest. The following are some choice tidbits from each.

Note that these tips are specific to Android, and might not be ideal in other environments (due to differences in the JVM or platform considerations).

Performance Tips

Prefer static over virtual methods

If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster.

Use static final for constants

The optimization itself applies only to primitives and Strings, although it's generally best practice to make constants as such.

Getters / setters

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter. Note that if you're using ProGuard, you can have the best of both worlds because ProGuard can inline accessors for you.

For loops

This one really surprised me:

With an ArrayList, a hand-written counted loop is about 3x faster (with or without JIT), but for other collections the enhanced for loop syntax will be exactly equivalent to explicit iterator usage.

In the following code, "the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop":

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;

Be mindful of private access with private inner classes

To summarize, when a private inner class tries to access the private member variables of the containing class, the compiler generates some synthetic, static methods to wrap member access. This is because, while legal, the VM considers one class assessing another class' private members to be illegal. As mentioned earlier, using a getter / setter can be 3x - 7x slower than direct member access.

Managing Memory

Release memory when your user interface is hidden

To be notified when the user exits your UI, implement the onTrimMemory() callback in your Activity classes. You should use this method to listen for the TRIM_MEMORY_UI_HIDDEN level, which indicates your UI is now hidden from view and you should free resources that only your UI uses.

Notice that your app receives the onTrimMemory() callback with TRIM_MEMORY_UI_HIDDEN only when all the UI components of your app process become hidden from the user. This is distinct from the onStop() callback, which is called when an Activity instance becomes hidden, which occurs even when the user moves to another activity in your app.

Use optimized data containers

Take advantage of optimized containers in the Android framework, such as SparseArray, SparseBooleanArray, and LongSparseArray.

Be aware of memory overhead

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android. Every class in Java (including anonymous inner classes) uses about 500 bytes of code. Every class instance has 12-16 bytes of RAM overhead.


Markdown has a standard

by Tom Bennett

Interesting to see that 10 years after John Gruber came up with Markdown, there's only now any sort of standardization. Standard Markdown was just announced today. As someone who uses Markdown for just about everything (notes, presentations, blogs), I'm definitely glad to see this happening.

Edit: It looks like this was done without the blessing of John Gruber. Until things clear out, I'm removing any links to "Standard Markdown." I'm also fixing my earlier mistake of not linking to either John's site, Daring Fireball (which I read religiously), or his page dedicated to Markdown.

In depth piece on data theft

by Tom Bennett

Nik Cubrilovic has a great, in depth piece on celebrity data theft. Considering how much data everyone stores online these days, it's probably a worthwhile read for everyone. Of particular note how these accounts are compromised:

  1. Users who scour Facebook and other social media looking for targets and collecting as much information as possible. Data collection includes utilizing public record services and purchasing credit reports. Obtaining data on a target includes setting up fake profiles, friending or following friends of the target, being persistent with extracting information that might help answer secret questions, approaching male friends of the target, etc.
  2. Users who use the target data to retrieve passwords or authentication keys. There are numerous methods here and most have tutorials available online. The most common are RATs, phishing, password recovery and password reset. RATs are simply remote access tools that the user is either tricked into installing via private messages or in an email (link or an attachment) or that someone close to the target will install on their phone or computer with physical access. Phishing is sending the target an email with a password reminder or reset that tricks the user into entering their password into a site or form the attacker controls. Password reminder is gaining access to the users email account (again using secret questions or another technique) and then having a reminder link sent to access the cloud storage. Password reset is answering the date of birth and security question challenges (often easy to break using publicly available data – birthdays and favorite sports teams, etc. are often not secrets).

It's not simple brute force and phishing, but also a system built upon social engineering. Recall that password reset was how Sarah Palin's email was broken into years ago. It's fairly trivial, especially given how often those "password secrets" can be answered by a quick look at someone's Facebook profile.

I guess take this incident as a reason to consider how much personal data you're putting out there, and if it could be used against you. I know I immediately went to Facebook to double check some privacy settings and outright remove some data.

Mike Ash on interesting Swift features

by Tom Bennett

Mike Ash posted a few weeks ago on Interesting Swift Features. If you haven't been paying too much attention to what's going on with Swift, this is a good overview of what's unique about the language. While not much is truly novel in Swift, many of the language features will be new to someone coming from a pure Objective-C, Java, or C background. Moreover I think it's rather unique to see all of these features in one language.

In his post, Mike touches on:

  • Explicit Optionals
  • Generics
  • Tuples
  • Type Inference
  • Trailing Closures

Trailing closures certainly help improve the legibility of code, and I'm excited to finally work in a language that allows for multiple return types. However, I'm most interested in seeing how optionals play out. At a surface level I think they're a great idea, and I'm very happy to see optional chaining is a thing since you can't simply pass a message to nil.

The next year or two will certainly be an interesting one for iOS developers, that's for sure.


by Tom Bennett

I've been brushing up on my Objective-C lately, and want to share some really valuable resources I've come across.

First, I highly recommend users new to the platform read Objective-C Programming: The Big Nerd Ranch Guide. Despite dabbling with the platform for years now, I still learned quite a lot.

Build Settings

  • Enable Analyze During Build
  • Make sure to treat all Warnings as Errors

Blogs, Podcasts, etc

Coding Style

Again, be sure to read this if you're new to the platform. Are you prefixing your classes to avoid namespace clashing?

Personal Finance

by Tom Bennett

Last year was the first time I seriously took a look into how I was spending money. Considering I was 26 and working professionally for 3 years, it was a pretty sad state of affairs. Something so rudimentary should certainly be taught in high school, particularly since timing can be so crucial when planning for retirement, college, wedding, etc. Anyway, I wanted to take some time to distill what I learned in case someone else finds themselves in the position I was in.

Probably the most important thing to consider is retirement. It's easy to neglect retirement when you're young, but compound interest and the volatility of the stock market really favors long term growth. Saving for retirement might seem like a daunting task, but it doesn't have to be. 

If your employer offers a 401(k) plan with a match, at the very least make sure to meet that. Otherwise you are literally walking away from free money. Once you have that met (or if your employer doesn't offer such a plan), focus on maxing out a Roth IRA. You can open up a Roth through the same company that handles your 401(k), or you can shop around (I'm personally a fan of Vanguard). The key difference between a Roth IRA and a 401(k) is that a Roth grows interest free. In other words, the interest you earn in a 401(k) will be taxed when you withdraw it in retirement, whereas interest from a Roth is not. I should also mention that 401(k) contributions are made pre-tax, while Roth contributions occur after taxes are taken out. 

Once you have money in a retirement plan, you need to make sure to invest it! The easiest approach is to invest in a lifetime fund, which automatically adjusts asset distribution (percentage of stock, bonds, international stock, etc) over time. Lifetime funds are generally named after the year targeted for retirement (for example, I use the Vanguard 2050 since I expect to retire around 2050 at the age of 65). It might sound silly, but in college I let the money from an internship sit in a money market fund, which means it wasn't really making anything at all! You are free to come up with your own asset allocation you can tweak, but a lifetime fund is by far the easiest to setup and maintain.

Of course, retirement is only one of many expensive events in a persons life, and it's important to save for those too. I've always been far removed from the idea of marriage or purchasing a house, but once those events become real, it's already too late to save. Consider that the average wedding costs $28,000, or that a house generally requires 20% deposit. I've found it far better to save monthly for these events so that I'll be ready if and when they happen, rather than end up in a lot of debt. Worst case, I end up with a lot of extra money that I could use to retire early, start a business, tour the world, etc. 

The sort of funds to invest in for these sorts of goals is tricky though, since the timeline can vary wildly. If you're already in a long term relationship and marriage seems like a possibility in a year or two, stocks aren't really a viable option due to volatility. But if you're like me and don't have firm plans on when to buy a house, then you can be a bit risker and work around stock market fluctuations. The key thing is to make sure that you're saving monthly; what specifically you invest in can be determined later.

While the goals I've mentioned up until now have been fairly long term, you should still consider short term goals as well. My favorite savings goal is $5,000 a year for an international vacation. Since the event is such short time, I put all of those funds into a savings account dedicated toward that goal. This way I can easily see the progress I'm making, and those funds are separated from my emergency fund and checking account. 

Now for some closing notes. Make sure you have an emergency fund! This should be about three to six months of expenses that you can rely on in case something unpredictable happens, like losing a job or necessary car repairs. Don't use this for items that you're aware of ahead of time, those you should be saving for! 

Note that I mentioned that your emergency fund should consist of your expenses and not salary; this implies that you should have a budget and should be living within it. If you aren't already using Mint to track your spending habits, I highly suggest you start doing so now. It's a painless way to track spending, and it even allows you to construct a budget based on your historical spending habits. If the idea of saving so much money seems impossible, I really recommend using Mint to inspect your current spending habits and see if there are some easy wins. Perhaps you're spending more than you expected at the bar, or your car is a bigger percentage of your take home pay than you thought.

When it comes to investing, I advise against individual stocks, and highly recommend index funds. While individual stocks seem like the best way to make a lot of money, you really only should invest in them if you're very familiar with the company, its competition, and its future economic prospects. You should be investing long term; otherwise you'll need to spend a lot of time and effort staying abreast of new information and developments. Comparatively, an index fund requires little management from the individual investor since its tied to the stock market. Trying to beat the market is difficult and costly, while a solid index fund with low fees can still reap rewards. 

Recommended Reading: