iPhone 5 Scuff Remover

Removes unsightly scratches, dings and scuffs IN MERE SECONDS! *

Get yours NOW!

And we think you’re going to love it.

* black iPhones only

Retina for Masochists

Today we released an update for xScope that supports the Retina display. As I alluded to on Episode 14 of The Talk Show, this update was harder than most. The 68k to PowerPC, Carbon to Cocoa, and PowerPC to Intel transitions were no walk in the park, but this update really kicked my butt. Here’s hoping that sharing some of the things I learned along the way will help you with your own Retina work.

For most developers who are working strictly in window points, an update for the Retina display is a fairly straightforward process. xScope, however, does a lot of work with both pixels and points. And that’s where the fun begins…

Mouse Input

The first gotcha I encountered while doing the Retina update was with mouse input using NSEvent’s +mouseLocation. The team at Apple has done some amazing work making sure output looks stunning on the Retina display, but being able to get high-resolution input is definitely lacking.

There are two problems at play here. The first is that mouse coordinates can be reported for coordinates that do not exist on any attached screen. The second is that the NSPoint does not contain enough resolution to address every pixel on screen.

To deal with the first problem, I used an NSEvent category that clamps +mouseLocation results to valid coordinates.

For the second problem, the only workable solution was to capture the +mouseLocation and then track -keyDown: events so the arrow keys can home in on the destination pixel. Yes, kids, that’s what we call a painful fricken’ hack.

Window Positioning

The next big headache was caused because you can’t set a window’s frame using non-integral points.

xScope does this a lot. The best example is with the Ruler tool: the origin of the ruler can be positioned to both even and odd pixels on screen. The red position indicators are also small windows that point to individual pixels in the ruler window.

The workaround is to make an NSWindow that’s larger than you need and then adjust the bounds origin of the NSViews it contains. The pain here is that it immediately introduces a dependency between windows and views. For example, the position indicator windows need to know if the view they’re hovering over has had its bounds origin shifted.

Pixel Alignment

There are many cases where xScope has to align to a pixel boundary. I found myself using this pattern many times throughout NSView -drawRect: code:

CGFloat backingScaleFactor = [self.window backingScaleFactor];
CGFloat pixelWidth = 1.0 / backingScaleFactor;
CGFloat pointOffset = lineWidth / 2.0;

The pixelWidth tells you how wide a single pixel is in points, while the pointOffset can be used to align a coordinate so that it straddles the Quartz drawing point:

NSBezierPath *line = [NSBezierPath bezierPath];
[line setLineWidth:pixelWidth];
[line moveToPoint:NSMakePoint(point.x + pointOffset, 0.0);
[line lineToPoint:NSMakePoint(point.x + pointOffset, 100.0);
[line stroke];

Another common pattern was to use the backingScaleFactor to align a coordinate to the nearest pixel in the view:

NSPoint point;
point.x = floor(x * backingScaleFactor) / backingScaleFactor;
point.y = floor(y * backingScaleFactor) / backingScaleFactor;

Of course you can do much the same thing with NSView’s -centerScanRect:, but in my experience it’s much more common to need aligned NSPoint values when you’re doing custom drawing. Creating an NSRect just to align the origin is a pain.

Flipped Coordinates

As Cocoa developers, we’re used to the pain and suffering caused by flipped view coordinates. Retina support can add a new dimension to this headache when you’re dealing with pixel coordinates.

Say you have a flipped NSView with an origin of 0,0 and dimensions of 1440 x 900 (e.g it covers the entire Retina screen in points.) Y coordinates on the screen can range in value from 0.0 to 899.5. When those coordinates are flipped, the range of values then become 0.5 to 900.0: which is off by a pixel (half point) if you’re trying to address the full range of view coordinates. The solution is to adjust the flipped coordinates like this:

NSRect windowRect = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 0.0, 0.0)];
NSPoint viewPoint = [self convertPoint:windowRect.origin fromView:nil];
	
CGFloat backingScaleFactor = [self.window backingScaleFactor];
CGFloat pixelWidth = 1.0 / backingScaleFactor;
viewPoint.y -= pixelWidth;

I’ve always wondered why there’s this odd note in the +mouseLocation documentation:

Note: The y coordinate of the returned point will never be less than 1.

Even though it’s a lie, the extra pixel does make the coordinate flip work correctly—and now you have to take care because that pixel can be a fractional point.

Summary

Hopefully my trials and tribulations will help you in your own development. The good news is that the beautiful results on the Retina display make all this hard work worthwhile.

The First Apple Channel

Dear Tech Media,

While you’re looking for meaning in the shadows of an Apple press invite, you’re missing something important: Apple is producing content for its own distribution channel.

For the month of September, Apple is letting customers view live shows through a combination of apps, the web, and Apple TV. It’s the fourth year of the iTunes Festival in London, but this is the first year that it’s been broadcast via iTunes.

Why is this important? Let’s look at what this means for the various players involved:

Artists

As an app developer, I know what it’s like to be featured by Apple in one of its promotions. It sells a lot of product. And that, in turn, funds our creative efforts.

I’m sure the featured artists will gain fans as a result of their performances. I’ve watched a few shows and have already seen some bands that I’ll be keeping my eye on.

A lot of these artists are also probably working with Apple for the first time and getting a feel for what a more direct relationship with a distributor feels like.

Customers

As a customer, I’m all too familiar with the hassles and restrictions on digital content. It’s an eye opener to be able to play this content wherever and however I want. No crap, just good shows.

Tickets for the events are also free: seeing your favorite band in a small venue where all you have to buy are the drinks? Sign me up!

Apple has chosen the artists wisely. I couldn’t care less about some of the bands, but you should have seen my niece’s eyes light up when I told her that she could watch a free One Direction show on September 20th. Talk about keeping your customers happy!

Media Industry

The iTunes Festival shows everyone above what a world without a middle man would be like. We’re loving it: they’re fearing it.

Apple

You need an iTunes account to view these shows. If you didn’t have one already, you’ll certainly get one to see your favorite band.

The best viewing experience for these shows is on a $99 Apple TV. That’s less than the cost of a couple of tickets to see the big name acts. The drinks aren’t watered down, either.

It also sets a precedent for the future. Could this be akin to HBO creating premium content for it’s subscribers? Or Netflix producing its own shows to make it’s streaming service more desirable?

Apple first got its feet wet in the content business with music in iTunes. What we’re seeing here may be the company’s first effort in the video business.

Updated September 6th, 2012: I’ve heard from several sources that last year’s iTunes Festival was an iPad-only app (with AirPlay capabilities.) Apple has taken small, calculated steps with the Apple TV platform and this is another example of that approach.