Dark Sky — Some Constructive Criticism for Today’s Update
Dark Sky has managed the impossible task of standing out in an App Store teeming with me-too weather apps. It has two amazing features: astonishingly accurate local rainfall predictions and colorful weather visualizations. Today its developers released a significant update to both the iPhone and iPad versions of the app. I don’t use Dark Sky on my iPad, so I’ll restrict my observations to the iPhone version.
Today’s update appears to be a complete rewrite of the user interface. The previous version had an admittedly awkward mix of chunky black, yellow, and blue controls on its primary view, with a gorgeous radar view hidden offscreen. The new version adds a three-panel view of week’s worth of a weather, all housed in a blurred container that is superimposed in front of a three-dimensional projection the Earth. This globe is painted with Dark Sky’s astounding animated weather radar and is interactive. It’s a significant improvement over the previous two-dimensional view.
Since the rainfall predictions are a transient feature — they’re experienced through push notifications — the most important visual elements in the new version of the app are the animated globe and the wavy prediction graphs. In my opinion, all of Dark Sky’s aesthetic choices should follow the design cues suggested by the nature of these features.
Contrary to what you might think from looking at most iOS 7 app redesigns, a white background color is not a foolproof way to elevate content above navigation. White isn’t a free color. It comes with baggage. It has its own personality like any other color. White is paper. White is an empty screen. It’s broadsheet for news articles and text boxes for blog posts. White is a dry erase marker board.
If you put ten people in a room and asked them each to name a predominant background color — the first color to come to mind — for a heat-mapped weather radar view, I would expect white not to appear on their list. The colors that are most often put to the task are pure black and dark gray. The participants’ likelihood of choosing black or gray would grow even stronger if you also told them that the name of the app in question is “Dark Sky.”
Color associations matter. Colors provide immediate, visceral clues. As Thoreau wrote, “some circumstantial evidence is strong, such as finding a trout in the milk.” Dark Sky’s new white theme points first-time users in the wrong direction. It drains the app of its vigor. The desaturated colors make the globe and the prediction graphs look like watermarks instead of category-defining innovations. White suggests that the text-based elements are more important. Newspapers and novels are monochromatic. Weather should be colorful. A dark theme with a palette of vibrant accent colors would evoke meteorological data on every screen, strengthening the association between the name of the app and its purpose. I would rather Dark Sky resemble the iOS 7 Compass app.
The raw idea for the redesign is good; the three-panel view with a side panel for the globe is an interesting riff on two established navigation patterns. But the execution is sloppy. It lacks clarity. It fails to shape the data into visually coherent elements. Titles are indistinguishable from content.
Of the three panels — current conditions, Next 24 Hours, and the week view — only the middle panel has a title, but in context the title is easily confused for a subhead. It took deliberate focus while preparing this post for me to recognize the purpose of all three tabs. I suspect a casual user will not undertake that much effort.
On the first panel, the cloud cover and temperature are rendered in a large black circle, for no discernible reason other than that circles are trendy. It looks more like a user profile than a weather summary. It is a shape without purpose. The circle does not add meaning to the data. It undermines the content-first ethos of the rest of the app.
On the second panel, the 24 hour temperature graph doesn’t have any bounding guides or axes to give the graph meaning. It’s just a line meandering through negative space. Graphs need axes to be legible.
On both the first and the second panels, all the individual sections are difficult to distinguish from one another. Whenever there are two or more things on the same screen, those things need boundaries. Boundaries, like button borders, can be real or implied. The only elements with adequate implied borders are found on the third panel, the week view. Each row in the week view resembles its neighbors above and below. This creates a consistent visual rhythm. The sections on the first two panels don’t have any rhythm, so they have no implied border. Without a real or implied border, each area of content melts into an amorphous blob. It’s disorienting and hard to read.
The third panel is not wholly exempt from criticism, however. Because the individual rows can be swiped open, they compete for the same panning gestures used to navigate between panels. The conflict between these gestures (and the lack of visual distinction between static and interactive content) makes me feel uneasy touching the app at all — a sin for an iOS app.
I’m still a huge fan of Dark Sky as a technical achievement. Its predictions are still thrillingly accurate. Our whole family depends upon them. I hope they reconsider some of the decisions unveiled today.
The Philosophy of Unread, my Forthcoming RSS App
I still love RSS. It’s the best way for thoughtful, independent writers to be read widely and carefully, despite how much the design of a typical RSS app may get in the way of their words.
RSS is an unadorned medium. It’s just plain text and a little markup. This simplicity is a call to write well. There’s no web design wizardry to hide behind. The writer’s words stand naked and raw. RSS is also a call to read well. Good writing deserves attentive readers. With RSS, there’s nothing between you and a writer’s words except a piece of glass. Or at least that’s how it should be.
Most RSS apps are patterned after email. Noisy parades of dots, dates, and tags trample over their screens. Their source lists look like overflowing inboxes instead of stately tables of contents. Toolbars bristling with options obscure the text. Putting it bluntly, using these apps feels like work.
I’m a paper subscriber of The New Yorker magazine. I like to read it in a comfortable chair with the magazine folded down to a single visible column. When held that way, it looks remarkably similar to a screenful of clean RSS paragraphs. Reading on an iPhone should feel just as satisfying.
I made Unread because I wanted to get back to a more deliberate style of reading. I designed it for times of quiet focus. With warm typography and a sparse interface, it invites me to return to the way I used to read before I fell into the bad habit of skimming and forgetting.
If you’re anything like me, you’ve subscribed to more websites than you have time or attention to read. I was paranoid that I was missing out on important writing. The irony is that the more subscriptions I had, the less I read. All too often, my “unread” articles remained exactly that.
Does Unread do all the things you expect from a typical RSS reader? Sure. But you won’t find a feature list here. Features don’t nourish your mind. I suggest that you don’t buy Unread if you aren’t interested in pruning your reading lists. Unread can handle dozens of feeds and thousands of articles with ease, but why would you want it to?
Let Unread be an opportunity to break away from your old reading habits. Let Twitter or App.net be the place for loud, busy feeds. Let RSS be the place where great independent writing thrives. Choose your favorite writers and read them closely. If you’re also a writer, write as if you were writing directly to just such a reader, the way Kierkegaard always wrote for:
… that single individual whom I with joy and gratitude call my reader…
This was written for the Unread home page. While Unread waits for App Store review, I thought it was worth reposting this here. ~ JTS.
Unread — Release Candidate 1.0
I started Unread in the summer of 2013. I’m happy to announce that — 1,659 git commits, 276 images, 273 classes, several dozen protocols, 19.9 megabytes of IPA, and one open-source sharing library later — I’ve just sent out the first release candidate of Unread to the beta testers. If all goes well, I will submit Unread for App Store review in the next several days.
Weak Referencing Dictionary
Kolin Krewinkel, the talented developer behind the App.net client Stream, shared an interesting article on NSMapTable tonight. In the article, Charles Parnot subjects NSMapTable to a battery of tests to see if it performs as promised. The results were surprisingly disappointing.
For those not familiar, NSMapTable is best described as a mutable dictionary with weak referencing capabilities. Typically, you use a map table when you need a collection of objects in which each object persists as long at least one other object in your app has a strong reference to the it.1 For example, if you were writing an App.net client, you might want to store a local cache of user objects in a map table. As long as at least one post or profile view controller keeps a strong reference to a given user, the map table will keep a reference to the user, too. In short, it’s a way to keep things around as long as you need them, without having to manually keep track of when you no longer need them.
The problems that Parnot uncovered are related to what happens after all other objects have released an object that is a member of a map table. The expected behavior is that both keys and values for these objects will be released. In practice, the results are unpredictable. Often, only half of such objects actually get removed from the collection. The rest are just hanging around and may never get purged in a non-garbage-collected environment like iOS.
On a whim last year, I tried writing an alternative to NSMapTable that would perform the same function, but that would be able to run on iOS 5 (NSMapTable is only available on iOS 6 or later). I put the result up on Github. It’s a funny little thing. It was written before my morning coffee, so I don’t recommend using it in a production app unless you absolutely need to. Nonetheless it worked as expected in my limited tests. Here’s how it was put together:
JTSWeakReferencingDictionary
The technique begins by adding an object via a category method on NSMutableDictionary, jts_setWeakReferencedObject:forKey: You add the object you want to be weakly referenced with this method instead of using the standard method.2.
This method does not add the object to the dictionary directly, but instead wraps the object in an NSValue using valueWithNonretainedObject. Later on, this plays a crucial role.
Just before adding the NSValue from step 2 to itself, the dictionary sets a custom property on the object passed into step 1 (the object we want to weakly reference). This is accomplished via associated objects, a form of voodoo too supernatural to cover here. The custom property is a strong reference to an instance of JTSDeallocNotifier, a subclass of NSObject that notifies a delegate whenever it is about to be deallocated. The mutable dictionary sets itself as the delegate of the dealloc notifier.
So at this point, each object passed into step 1 is given a JTSDeallocNotifier and wrapped in a weak-referencing NSValue. The NSValue is then added to the mutable dictionary.
As long as at least one other object in your app retains the weak-referenced object, it will persist via the NSValue as a member of the dictionary.
When all strong references to the object are broken, the NSValue’s weak reference will be zeroed, and ARC will begin the process of deallocating the object and cleaning up the object’s own references. During this process, the object’s JTSDeallocNotifier is also deallocated since no other object retains it.
Inside of JTSDeallocNotifier’s dealloc implementation, it notifies its delegate that it is about to be deallocated.
The mutable dictionary receives the message from the dealloc notifier. The dealloc notifier has a key that is a copy of the key passed in step 1 when the original caller added the weak-referenced object to the dictionary. Using this key, the dictionary knows which NSValue it should remove from itself.
The dictionary removes the NSValue for the key from step 8.
At this point, ARC finishes its deallocation steps, and the weak-referenced object, its dealloc notifier, and the NSValue are all released.
I ran brief tests of this technique with collections of 10 to 20 objects, using GCD and blocks to experiment with timing. Everything worked as expected.
Open Letter to OmniGroup About the iOS 7 Redesign of OmniFocus for iPhone
Dear OmniGroup Designers & Developers,
I’ve been a huge fan of OmniFocus, both Mac and iOS, for years. You guys helped me graduate college, become an ICU nurse, start a family, and change careers to become an indie iOS developer.
I’m writing to say that I’m very disappointed by the iOS 7 redesign of OmniFocus for iPhone. I’ve been using it since it came out, hoping that I would adjust to it, but it just hasn’t happened. Instead, I’m often reverting to a plain text list in a note-taking app for quick notes about the day’s tasks. I’m only using OmniFocus on my Mac now.
I’m not complaining about the flatness of the iOS redesign. Go with the current, by all means.
Instead, I’m disappointed by the underwhelming airiness of the whole app. It is excessively understated to the point of being hard to use. Navigation looks indistinguishable from content. I have trouble seeing the logical hierarchy of information. My fingers hesitate before tapping anything because I’m never entirely sure that I’m tapping the right thing. The inconsistent use of transition animations — some are standard push/pop transitions, others are the custom vertical split — act like speed bumps, preventing the use of muscle memory. The light weight fonts feel fragile and make quick, accurate reading almost impossible.
In short, the new design slows me down. I can’t build safe muscle memories. I can’t quickly navigate the app without constant tension. The design is driving me away from OmniFocus, and I don’t want that to happen.
Here’s what I wish you would change, at a minimum:
Consistent Navigation. Use one, consistent navigation paradigm throughout the app, even if it’s just the standard UIKit push/pop transition. Help me build power-user reflexes that speed up my work.
Distinguish Navigation From Content. Make navigation tonally distinct from content. I suggest using white text on a solid color background for toolbars and nav bars, and dark text on a white background for content. You could even use context-specific background colors for the navigation bars. The color cues from the dashboard screen would be even more resonant this way.
Use Readable Fonts. Don’t use light weight fonts. Don’t rely on the Settings.app text accessibility preferences, either, because what looks good in OmniFocus might look bad in another app. Make the out-of-the-box fonts easy to read.
Make the App Logically Obvious At A Glance. Short of jumping into Photoshop myself and showing you what I mean, I will say this: the task editing screen should be redesigned with a more obvious logical hierarchy. The current design’s closest analog from the real world is a tax form: a dizzying grid of equally-important boxes. The task editing screen is complex for a good reason. All the features are necessary. Rather than hide the complexity with understated controls, take the opposite approach. Make them easily understood even at a glance. The tabs should look like tabs if that’s how they function. A good test would be to see how accurately a new user remembers the content of a task after being shown the screen for a brief interval, say 2-3 seconds.
Thanks for all your hard work over the years. I entrust so much of my life to your software. I want to continue to be a loyal customer and fan.
Cheers,
Jared Sinclair | @jaredsinclair