My name is Jake Marsh.
I'm a developer, designer, and writer.

Subscribed via Push Notifications. You can also subscribe via RSS or Twitter.

Subscribe via RSS or Twitter.

Subscribe via Push Notifications, RSS or Twitter.

▸ IRIS 9000 Voice Control Module for Siri

Oh man.

Iris 9000

Simply place your iPhone into the Iris 9000 cradle and use the included micro remote to trigger Siri up to 50 feet away. Just tap the Iris 9000 remote button once, listen for the Siri chime, and speak your command. The built in mic on the Iris 9000 picks up your voice from across the room and the embedded speaker amplifies Siri's spoken responses.

Can't wait to get one of these, says they're coming in 2012.


What If Apple Made a TV?

 •  12 minutes to read

Let me just say that I'm still rather undecided as to whether or not Apple will in fact bring their own television set to market. I did, however, find it a really fun challenge to try to imagine what a true Apple TV might be a like. Take from it what you will.

First off let's assume a few things. Let's just assume, for the sake of this article, that Apple is unrestrained in terms of having to bend to the whims of the content owners, cable companies and "traditional" television business practices. We all know this antiquated business is clinging on to their archaic business plans with a death grip of what I like to call future-blindness. What I'm going to describe is what an Apple TV might be like in a world where these problems had been solved or surpassed somehow.

The Hardware

Form Factor

Simple. 3 sizes. 30 inch, 40 inch, and 50 inch screen models. Each with a 7 millimeter black bezel around the edge. No Apple logo on the front.

Input & Output Ports

2 HDMI inputs. 1 ethernet port. Built-In 802.11n WiFi. iMac style removable power cord. 1 optical out port. 1 Thunderbolt port allowing you to use the TV as a monitor, or to connect an external hard drive, or many other peripherals.

The Remote

An iPod Touch. In the box, included with the purchase of the TV. Comes pre-installed with new version of the official Remote app. This new version of Remote.app uses Apple's Bonjour technology to automatically find the TV and begin guiding you through the setup process (more on that later). It has features that allow labeling and selecting of your 2 HDMI inputs, with pre-made beautiful icons for Xbox 360, PS3, Blu-ray players, etc. Much in the same way that Mac OS X displays beautifully renderred icons for most printers you connect to. Switch between the devices and your main TV with a simple scroll view control (similar to your iPhone's homescreen).

Software and Content

This is the fun part. Forget the entirety of the current Apple TV interface.

Muggles & Luddites

Apple makes products to serve the masses. The current Apple TV (the hockey puck shaped one) is awesome for geeks like you (assuming most reading this would consider themselves, at least in part, a geek). It does not however, serve the muggles and luddites out there who want to come home after a long day of work, flip on the TV, instantly be seeing some content, kick back, have a brewsky and take a load off. The hockey puck's software serves those of us who want to watch specific things at specific times very well, but doesn't even try to accomodate what I would call the "average" viewer.

How do we solve this problem without also removing the power of the on-demand style viewing? You do both at once. Here's how it could work:

You turn on the TV, it's instantly on, I'm talking no more than a second. There are channels, just like your current TV. They correspond to each of broadcast and cable networks. So there's an NBC channel, there's a Discovery channel, there's an ABC, a CBS, a Sci-Fi, a Food Network, etc, etc. Sound familiar? What is this channel showing? Well it's showing whatever would currently be on that channel at that time if you were watching a "regular" TV. Instead it's coming to you over the internet. The tech behind this is that Apple already has every single episode of all the shows they offer in iTunes. The networks and content providers often upload the whole season to Apple's servers ahead of time with scheduled release dates and times. So what Apple does is simply stream each of these episodes on their respective channels at their respective times. No commercials, for one monthly price (more on that later).

I know what you're thinking, "But Jake! What about my live content?! News? Sports?" Don't worry, Apple has you covered, they've arranged deals with the major networks (again we're ignoring the difficulty of signing such deals) to simulcast these sorts of programs on their respective channels at their specific times. There's a CNN that is basically the same CNN you're used to seeing now. They even broadcast things like sports games, breaking news and "special extreme car-chase coverage" events in such a way that the viewer could choose, for example, to instead of watching that ball game that somehow has gone into 6 extra innings, watch tonight's epsiode of "Conan", which normally would have been pre-empted. Thanks to the Apple TV software, the viewer can choose to watch the ball game stream on TBS, or switch to the "regularly" scheduled program of "Conan". The remote simply displays a screenshot of both possible peices of content on that "channel" and the user can switch back and forth between them.

The user can obviously now pause, rewind, and even fast-forward almost anything they are watching, no matter what. No more DVRs, no more scheduling, no more hassle. It all just works.

Content is available to watch as soon as it would have broadcasted to "regular" TV. Movies are available to be viewed as soon as they are released in theaters. Think kicking back and watching "The Dark Knight Rises" at midnight on release night. (Again suspend your disbelief and pessimism about how insanenly difficult it would be to get board-room types to agree to this, we're into pie-in-the-sky, in-a-perfect-world type stuff here.)

On-Demand

Like I said before, many users would likely still want to pick and choose a show or movie at random to watch at their leisure. No problem, simply switch the "Browse" vs. "Live" toggle at the top of the app to "Browse", and instantly the app lets you browse through a beautifully redesigned iTunes store-like view to find a peice of content to watch. See something interesting? Drill in to read a full synopsis, see reviews, etc. Tap one button to watch a preview of any content you find, it will begin playing on your TV. Like what you see? Just tap "Start Watching Now" to start the full version of that piece of content from the beginning. Change your mind? Flip the "Browse" switch back to "Live" and you're controlling live TV again, the app never loses your place or stops playing.

Other Content

What about YouTube? Vimeo? They're gone. These are apps that are meant to live on the iPod Touch that came with your TV. All of these "external" sources of content are gone from this Apple TV.

The Interface

Almost non-existant. Almost everything happens on your Remote app on the screen of the included iPod Touch. The TV itself will display things like whether or not the TV is muted or not muted, or identifying information when the current program, channel, or input source changes (only for a brief moment of course).

Under The Hood

It's running iOS. It does not have an App Store. This is done purposefully to encourage developers to deliver content by using AirPlay. In Apple's world, The Twit.tv's and Revision3's should make apps for the phone or tablet platforms that offer rich content browsing expieriences, with a simple AirPlay mechanism to "sling" it up to the TV, much as they encourage content providers to do today, with iOS 5 and the hockey puck model. It does support iCloud and can instantly browse through your photos, movies, etc.

Pricing & Plans

The Device Itself

The new Apple TV starts at $999 for the 30 inch model, $1499 for the 40 inch, and $1999 for the 50 inch model.

The Content

This one is the key. Apple is going to replace your cable company, your Netflix, your Hulu, everything. One plan, one signup, one monthly bill. The price? $49 USD a month. High enough to pay the content providers enough to make them happy, low enough to entice most people to make the switch. For your money, you get everything I've described above, all the content, all the movies, all the TV shows, anytime, all the time. No more buying single episodes, no more renting or buying movies. It's all right at your fingertips.

Conclusion

I hope you've enjoyed this hypothetical trip into the proverbial chocolate factory that is Apple's design studio. Just so we're clear, I do want Apple to make a TV. I'm sure it would be awesome, otherwise they wouldn't waste their time making it. I'd love to see some of the ideas I've described here in some form or fashion show up in that final product, but even if they don't, I'm sure it would still be something pretty great.


▸ Grove Bamboo MacBook Backs

Received my Grove Bamboo Back for my Macbook Pro today. Here's my quick review:

Here's a hipster shot of what it looks like on my 15" Macbook Pro:

Macbook Bamboo Back

The guys over at http://grovemade.com are an awesome little company, they make some neat stuff, check them out if you get a chance.


▸ The Metaphors Breaking The Future

Calendar, Notes and Contacts are all explainable — they reference real world things (even if they shouldn’t). My Mum likes that her calendar looks more like a Filofax than Outlook 2003. Fair enough. A Filofax is a thing. I get it. And the Compass app is based on a compass. Another thing.

But I’m pretty sure there’s not a thing in my physical living room called a ‘Find My Friends’. The metaphor is empty. It’s not referring to anything. It’s just a leather texture.

A great piece about skeuomorphic design by Jon Gold


Show TODO's And FIXME's As Warnings In Xcode

Here's a neat little snippet for Xcode 4 that will cause all of your //TODO: and //FIXME: comments in your code to appear as compiler warnings when you build. Here's how to use it:

Instructions

Now just build and you'll see all your //TODO: and //FIXME: comments have become warnings. I love this technique, it might not be right for everyone, but hope it helps someone.

Bash Script For "Run Script" Build Phase

KEYWORDS="TODO:|FIXME:|\?\?\?:|\!\!\!:"
find "${SRCROOT}" \( -name "*.h" -or -name "*.m" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($KEYWORDS).*\$" | perl -p -e "s/($KEYWORDS)/ warning: \$1/"

You'll also be able to click on each of the warnings in the issue navigator to go right to the file and point in your code where you left the original //TODO: or //FIXME:

Extra pro tip: Make sure you're using phrases to describe your //TODO: comments like //TODO: Handle this error gracefully, and things like that. The phrases will show up in the issues list beside each warning.

Credit for the little tidbit should go to "Tim" on the Cocos2D forums, (found after Googling for a bit), I believe his solution originally was intended for Xcode 3 and didn't work if you had spaces in your path name, my script here doesn't have those restrictions, still he should get full credit here's his original post.


Save Time and Code With JMWhenTapped

I've just released a new little helper library for iOS development. It's called JMWhenTapped. It's is a simple little syntactical-sugar addition to all UIView objects, as well as any class that inherits from UIView. It allows you to assign touch-up, touch-down, and tapped (touched down then up) actions to a UIView object using a convenient blocks-style syntax.

Installation

Clone the repo. Add the JMWhenTapped folder to your iOS 4 project. #import "JMWhenTapped.h" wherever you'd like to use the syntax.

Examples & Usage

Use it like this:

[myView whenTapped:^{
    NSLog(@"I was tapped!");
}];

Or like this:

[myView whenTouchedDown:^{
    NSLog(@"I was touched down!");
}];

And also like this:

[myView whenTouchedUp:^{
    NSLog(@"I was touched up!");        
}];

The Different Actions

The whenTapped: method should be used in cases where you simply want something to happen when the user taps on a view (i.e. you are concerned with performing some action when their finger is down then up, like changing to a "pressed" state.)

The whenTouchedDown: method should be used when you want to trigger some action when the user touches down on your view.

The whenTouchedUp: method should be used when you want to trigger some action when the user touches up on your view.

Demo

Included in the repo is a demo Xcode project that illustrates a quick example of how to use JMWhenTapped.


The Art Of The Reveal

 •  11 minutes to read

Ever been so excited for a new app that you just can't wait till you get to download it? I'm going to tell you how to make people feel that way about your app.

The Reveal

What do I mean by "the art of the reveal"?

It's the way you announce your new product. It's the way you release that product. It's even how you structure your business model around that product. The reveal happens every step of the way in software development.

It appears in its most obvious and blatant form in places like the famous Steve Jobs keynote-style addresses. But it also shows up in the "Coming Soon" website for your app, and later in the website you create for announcing and releasing your new app on launch day. It even shows up in the way your company structures its business models and pricing offerings. Let me explain:

The Reveal In Business

Don't release 10 different versions of your app. Don't make your purchase options so confusing and daunting that your customers give up half way through. By all means make money, but think about every tiny detail from the consumer's perspective. This goes for all software. It doesn't matter if your business is building a super simple utility app for iOS, or a full-featured desktop word processing platform. Don't make the user think about how you are selling them something, make them think about what you are selling them.

Price should be a feature. Don't price to sell. Price your app at what you would be willing to pay for it. Pricing your app appropriately also helps solidify your app's place in the market. Don't charge $9.99 for a flashlight app, but don't make a flashlight app that is only worth $0.99. Tweetie (now the official Twitter app for iOS) sold incredibly well at iTunes price tier 3 ($2.99 USD) for years. It did so because it was a fantastic app, which is what I will cover in the next section.

The Reveal In Your Product

Alright, first off: Do not make crap apps. Do not make apps to make a quick buck. Just don't do it. Do make apps that surprise and delight users with their simplicity, ease-of-use, performance, and of course, their look and feel. Okay, now that we have that out of the way:

Your users form their opinions in the first 10 seconds of using your app. Never forget that. Make those first 10 seconds as impressive and delightful as you possibly can.

Take iMovie for iOS. Apple could have faded in from a black screen, and showed you an empty list of your movie projects. They could have made a nice looking list view with thumbnails, titles, movie durations, and it probably would look pretty nice. But no, they chose to make an opening screen that impresses and "wows" the user with the neatest little retro movie theater neon visual (shown above). The lights flickr, the marquee glows and you've even got full sound effects to go along with it.

This is the art of the reveal working at its finest, if you were waiting to form your opinion about the app, this does it. Immediately your user feels gratified, and they feel like they've just made a good purchase. Never skimp on the details. Never underestimate the power of polish.

The Reveal In Announcements

It's all about the build up. Take the time to explain yourself, but be brief. Be direct. Make every sentence a soundbite.

I can't stress that enough. If you are trying to get people both excited and interested in your product or service, do not oversell, just sell. These are clichés and I may just as well have told you to "Always Be Closing!", I know, but the art of the reveal is in making people hang on your every word.

The art doesn't happen when you make a sale, the art happens when people are constantly clicking refresh on your site on launch day just waiting for the "Download Now" button to appear, so they can click it.

Don't use buzz words. Use "because" words. Use words that explain how or why your app should matter to the user. People do not care about how you built your app.

Do not drone on about technical specifications, or how your app downloads RSS feed entries in less than 10 milliseconds because you wrote an awesome multi-threaded subroutine that delays until the next run loop. Instead, tell people about the great auto-discovery feature that "just works." Explain to people why and how your app is going to change their life.

People are selfish. They want to know the answers to a few simple questions:

This stuff is hard. If it were easy, everyone would do it. Know your audience. If possible, be your audience. Try not to build apps that you don't want to use yourself. This way, when it comes time to announce it, you'll know exactly what the coolest features are, and why.

It's up to you whether or not you pre-announce anything about your app, but if you do, follow these rules. If not, read on to the "Releases" section.

Want to see a master at work?

Check out this clip of Steve Jobs announcing some improvements to the iTunes Store's movie offerings from Macworld back in 2008. This is a simple content announcement, but he manages to get screaming cheers and thundering applause from the crowd. How?

He makes it exciting and displays one of the most classic examples of "the art of the reveal" I've ever seen. Check it out:

The Reveal In Releases

The first release of your app should be an event. Don't settle for any less. Pull out all of the stops. Any significant release of your app should be a similar spectacle. Never have a lame release. Take yourself seriously, but not too seriously.

Make your release fun. Make it fun for your potential new users to see a link about your app on Twitter, visit its new release-day website, and then download it. Make discovering and learning about your app for the first time an experience.

Include a video on your release-website. A video. Singular. Do not make users click through 10 demo videos of all your app's features. Boil it down for them. Become a television commercial director. Do not use Flash for playing this video. Check out the promo video for Cultured Code's "Things for iPad" up above. It is a perfect example of what I'm talking about. Beautiful, simple, wonderfully effective.

Make your website look great on all iOS devices, large and small. Make your website look great in all browsers. Again, details. Make them count.

Do not ever settle just to get to market quicker. Don't release early just because you're done. Plan your release. Make it count.

For example, if your app has a free and paid version, and the paid one gets approved into the App Store first, do not simply release it just because you're excited and want to get going. Wait. Release both versions simultaneously. Doing so will help sell your message of what exactly you are offering your users.

You don't want to spoil the surprise when you press the button on release-day and launch your awesome release-day website.

Create an awesome release-day website. It has to look amazing. It has to be visually stunning. It has to grab everyone's attention and make them go "What is that?!" Even for subsequent releases, have a special release splash on your website.

Your release-day website for your app should be something you would link to on Twitter, even if you weren't involved with its creation. Think outside the box. I can't give you specific advice here. Make it fun, add some CSS animations, add some interactivity. Make those clouds at the top of your graphic move. That's the point, do something neat. Do something original. Impress people who stumble upon your little app.

No One More Thing Here

That's it. It can and should be as simple as that. I will likely be putting up more detailed posts on this topic, and user experience in your apps in general. Hope you enjoyed these tips, let me know what you think on Twitter.


Introducing: JMImageCache

 •  4 minutes to read

Today I'm open-sourcing a small project I use to do remote image downloading and caching on iOS called JMImageCache. It uses an NSCache based remote-image caching mechanism that can be easily integrated into any project. It is very light weight and isn't meant to be a replacement for UIImageView or anything like that. Just drop it into your project, grab a reference to it and start using it where ever it makes sense.

How It Works (Logically)

There are three states an image can be in:

If an image is requested from cache, and it has never been cached, it is downloaded, stored on disk, put into memory and returned via a delegate callback.

If an image is requested from cache, and it has been cached, but hasn't been requested this session, it is read from disk, brought into memory and returned immediately.

If an image is requested from cache, and it has been cached and it is already in memory, it is simply returned immediately.

The idea behind JMImageCache is to always return images the fastest way possible, thus the in-memory caching. Reading from disk can be expensive, and should only be done if it has to be.

How It Works (Code)

Request an image like so:

    UIImage *mScott = [[JMImageCache sharedCache] imageForURL:@"http://dundermifflin.com/i/MichaelScott.png" delegate:self];

imageForURL:delegate: will return either a UIImage object, or nil. If it returns nil, then that means the image needs to be downloaded.

If the image needs to be downloaded, you'll be notified via a callback to the delegate object you specified in imageForURL:delegate::

- (void) cache:(JMImageCache *)c didDownloadImage:(UIImage *)i forURL:(NSString *)url {
    NSLog(@"Downloaded (And Cached) Image From URL: %@", url);
}

Clearing The Cache

The beauty of building on top of NSCache is thatJMImageCache handles low memory situations gracefully. It will evict objects on its own when memory gets tight, you don't need to worry about it.

However, if you really need to, clearing the cache manually is this simple:

[[JMImageCache sharedCache] removeAllObjects];

If you'd like to remove a specific image from the cache, you can do this:

[[JMImageCache sharedCache] removeImageForURL:@"http://dundermifflin.com/i/MichaelScott.png"];

Demo App

The Github repository includes a demo project. Just a simple UITableViewController app that loads a few images. It does so by calling imageForURL:delegate: and passing in the UITableViewCell as the JMImageCacheDelegate to respond to when an image is downloaded. Then we simply set the image of the cell's imageView and then call setNeedsLayout on the cell to refresh the view. Nothing too fancy, but it should give you a good idea of a standard usage of JMImageCache.

Using JMImageCache In Your App

All you need to do is copy JMImageCache.h and JMImageCache.m into your project, #import the header where you need it, and start using it.

Notes

JMImageCache purposefully uses NSString objects instead of NSURL's to make things easier and cut down on [NSURL URLWithString:@"..."] bits everywhere. Just something to notice in case you see any strange EXC_BAD_ACCESS exceptions, make sure you're passing in NSString's and not NSURL's.


Custom Sections Title Selectors

Recently, I've been struggling with NSFetchedResultsController. I was trying to get it to section my objects by a "pretty date", but still have them sorted properly.

Thanks to a great post on stackoverflow, I realized the beauty and simplicity of just adding an Objective-C Category to the NSDate property on my model object.

My managed object had a property called scanTimestamp, which was an NSDate. When configuring the NSFetchedResultsController, I was able to simply use @"scanTimestamp.prettySectionHeaderDateSring" as the sectionKeyPath.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"PKScan" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scanTimestamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                                            managedObjectContext:self.managedObjectContext 
                                                                                              sectionNameKeyPath:@"scanTimestamp.prettySectionHeaderDateSring" 
                                                                                                       cacheName:nil];

Then, I just set scanTimestamp to be the sortDescriptor for the NSFetchRequest of the NSFetchedResultsController, and everything worked both smoothly, and correctly.

In the Category, the - (NSString *) prettySectionHeaderDateSring method was declared as returning an NSString and also as a readonly property (either of which would have been sufficient, but it's always nice to have both explicitly declared). Then I simply implemented the prettySectionHeaderDateSring method using some NSDateFormatter magic to transform the ugly "2010-10-13 10:33:12 -0400" NSDate value into a nice and pretty "Wednesday, October 13th" string.

Here's the NSDate category:

#import <Foundation/Foundation.h>

@interface NSDate (PrettySectionHeaderAdditions)

- (NSString *) prettySectionHeaderDateSring;

@end

@implementation NSDate (PrettySectionHeaderAdditions)

- (NSString *) prettySectionHeaderDateSring {
    NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];

    [formatter setDateFormat:@"EEEE, LLLL d"]; //Resolves to: "Wednesday, September 13"
    [formatter setAMSymbol:@"am"];
    [formatter setPMSymbol:@"pm"];

    return [formatter stringFromDate:self];
}

@end

[JMBlog new]

Welcome to Deallocated Objects. This is where I'm writing now. I would like to start writing more, so I've decided to do that here from now on.

[oldBlog release];

JMBlog *newBlog = [[JMBlog alloc] initWithAwesomeLevel:JMAwesomeLevelLegendary];

I've had a website or blog since 1998.

Why Stop Now?

Every few years or so I say "I'm going to start blogging again." and then spend a wealth of time building a great set of code and templates, and designs, etc. to do so and then never seem to keep up with it.

Well, 17th (or so) time's a charm and here's my latest creation. Deallocated Objects will be a stream of my consciousness about Mac, iPhone & iPad application development, interface design, and interaction design. Along the way I'll post code snippets, walk-throughs, as well as tips and tricks on building awesome stuff.

I'll also likely be re-coding this blog in the near future. So there will likely be a series on that process. I wanted to wait until I completed my full vision for this blog before going public, but I've been dying to have a clean place to post this types of things for a long time. I've given tumblr a fair shot and its great for somethings, but for what I want to do it just isn't going to cut it. Right now this site is running on wordpress simply because I wanted something up quickly that I didn't have to think about too much. In the future, however, my plans are to write a custom system with a Rails 3 backend and... wait for it... an Objective-J/Cappuccino front-end. That's right. I'm going to write my website in Cappuccino. I know what you're thinking. But I don't care, it will be awesome.

Thanks for visiting and keep an eye on my twitter as I'll be posting a bunch of other cool stuff soon.