With the 7-day forecast and home screen more or less set, I focused on implementing the details of the secondary view. As detailed in Sketched Views, I decided to combine the screen that showed current conditions and the one that showed hourly conditions into one view.
I landed on a double tap as the best way to access it. Mainly due to my beginners lack of knowledge on how to implement any other way.
When you transition to the new view, the “header” area of current city, region and temperature remains the same. This provides an anchor of sort as you transition from one view to another.1
I had toyed with having a text summary of the current conditions mixed with the current chance of precipitation as the lead-in sentence for the view, but in practice that proved to be less than interesting. The current conditions summaries were usually very simple; which makes sense, how would you describe outside right now? Exactly. And then most of the time it’s 0% precipitation unless it’s raining, or about to rain.
Still I liked the aesthetics of the text summary as a lead-in to the daily details, so I changed it from the current conditions to that day’s summary. And as you might expect this turned out to be much more helpful and interesting to boot. (Forecast.io does a good job with their text descriptions.) I combined the precipitation chances and anticipated highs and lows as a natural language summary alongside the daily conditions summary for one lead paragraph. Later, I realized this summary was useless when viewed in the evening, so I changed the code to where after 9pm it switches to the next day’s summary and adds a “Tomorrow:” label in front of the text summary.
This single paragraph took care of the daily summary.2 I then turned my attention to the hourly data. And a quick break in the narrative to say that as orderly as this perhaps sounds, the actual process – for me anyways – is much messier. It’s a lot of going back and forth, implementing something and living with it for a few days, seeing it not work in practice and redoing it to something else. I just take all this mess and clean it up a bit to present something a little more orderly on the blog. If this were a true step by step it would just be a lot of me writing out mumbles and stray thoughts. Anyways, back to it.
A challenge for the hourly information is there is usually little change in the hour by hour sequence. Ergo, the presentation and data is not very interesting.
You can graph it, and that looks nice, but I find the mental processing needed to parse a value from a graph to be unhelpful. If the goal is to communicate specificity quickly, a graph fails. You can use the hourly data to present a macro view of the day, but that’s what the text summary did. And really unless there’s a precipitation event, or severe conditions, the weather follows a predictable pattern. If each day’s graph looks more or less the same, what use is it?
I latched on to this because of reading about Claude Shannon’s work with information theory as described in The Information. Here’s a sample:
“The more inherent order exists in a sample … the more predictability there is, and … the less information is conveyed by each subsequent [item].”
Take this Dribbble shot for example:
This is a mess of communication. An early draft, of course, but even when polished you can imagine how it’s still not going to be that helpful.
So taking a step back there is the question of why even have hourly data? What use is it? With myself as subject, the only time I really care about hourly data is when I want to see what the weather conditions will be like around a certain hour of the day. Perhaps we’re going out to dinner or going
for a run to get donuts. The circumstances for that moment in time are special and have necessitated a special weather report for that moment. This was the conceptual job I defined to create the design approach for the hourly view.3 The details of which I will go through in the next post.
- I’m changing this transition to a slide left to reveal, which changes the dynamic enough to where I must reconsider this approach of repeating the header data. Yet to be determined at the moment though.
- Full disclosure: having had the paragraph summary in place for a couple months now I am considering simplifying the language for the high and low temperature and extracting it from the paragraph form into something closer related to a list.
- For more on the idea of jobs in the context of product design see Ryan Singer’s excellent article, Vital Elements of the Product Design Process
Wendell Berry is a prolific author who lives about an hour northeast of Louisville. His writings are critical and prophetic of the way we live and their consequences. Mr. Berry writes beautifully about what he’s for as well: “sustainable agriculture, a connection to place, the miracle of life, and the interconnectedness of all things.”¹
The above excerpt is at the end of an essay about the specialization of poetry (written in 1974) and is one of the most elegant and true descriptions of the balance between work and life that I’ve ever read.
- Quote from the publisher — Counterpoint Press.
The weather app I’ve been working on, Everyday Weather, is now available in the app store. I’m happy with the end result and I think you will be too.
I will continue to add entries to the app journal until it’s finished. The pace of writing couldn’t match the development, but I didn’t want to wait for the journal to catch up before launching the app because with some other commitments beginning I’m not sure when it will be complete. I have 30 planned entries total to write, and right now I’m at 17.
For readers of this blog who don’t have the app, or if you just happened to stumble across this page, I’ve generated 30 promo codes to get it for free. They are listed below. And if you don’t know how to use promo codes it’s very easy, just go to the Featured tab in the App Store app and scroll to the bottom. There you’ll find a Redeem button that you can tap and enter the promo code manually. You may have to try a few as I don’t know when they’ve been used and there’s no official way to track their use.
I knew version 1.0 of this app was going to be pretty bare-bones — the essentials if you will. But one feature I felt it would be arrogant to leave out is the ability to view temperatures in degrees Celsius. Being from the U.S. I take my temperatures in degrees Fahrenheit, but most of the world does not. I like how the default weather app handles switching between the two, and if I had the programming chops I would have done it the same way. But alas I do not, so I went with the more heavy-handed approach of adding an entry for Everyday Weather in the Settings app. Within this entry is a toggle option to choose between Fahrenheit and Celsius, with Fahrenheit being the default option.Keep reading
When I first started sketching the weather app idea, the name I had in mind was Forecast. For all intents and purposes this was the perfect name. It described exactly what the app did and, to my utter surprise, it seemed like it wasn’t being used in the app store.
There was one problem though – the API I was using was also called Forecast. This is a legal problem because it would not be clear to customers that the app was separate from the API, and therefore would imply an affiliation when of course there was not one.Keep reading
Part of Forecast’s API includes weather alerts from the National Weather Service. I decided that this should be a core feature of the app and therefore included as part of the 1.0 release.
I broke it into two parts. The first is a UIButton that is created if weather alerts are present in the returned API. Though “button” is a bit of a misnomer, it’s more of a banner that tells you weather alerts are available and how many.Keep reading
This is just a quick note to let everyone know I’m still working on the app, just a bit delayed. My original plan was to submit the weather app before Brooklyn Beta started but a few things came up in the month prior that put me off schedule by about two weeks. And polishing the macro experience is taking a bit longer than anticipated. Not a huge deal, I’m hoping to submit by the end of this month.
Speaking of Brooklyn Beta, it was a fun time. I’ll be looking to attend next year as well. The overarching takeaway from the conference — I think — is do work that matters. For me, the quotable quote came from Tim O’Reilly’s talk: Create more value than you capture. That’s an area lacking in my work lately and something I want to rectify.
For an evening past there were two things on the todo list for the app: (1) anchor the current date label at the bottom of the screen no matter the dimensions (either 480 pt or 568 pt tall), and (2) style the date label to where the day name is all-caps and bold and the rest of the date is regular weight with no text transformation.
For the first step all I needed to do was programmatically set the main view’s height relative to the screen’s bounds. I had already done this for the root view and the scroll view, see the gist at the end of Day 11.
I didn’t do it for the main view because I had copied the code over from the details view, and in that view I had left the set height in the XIB as the default height. So when I ported this code to the main view controller, it used the 568pt height of the XIB’s 4” screen layout. Even when I changed the Simulated Metrics Size drop down to be None the XIB still had the measured height of 568pt because that was its view dimensions.Keep reading
One key need for the app was the ability to refresh the data. The Objective-C wrapper I’m using to connect to Forecast’s API automatically caches data, which is great. But that means if you pull the app up an hour later it’s likely you’ll still see the same data from before. But really I don’t have to explain this to you. Pull to refresh has become a de facto design pattern for any app that displays timely data.
Long ago I starred Sam Soffes’ SSPullToRefresh on GitHub as a hopeful resource one day. Well the time finally came. Like many other unknown Objective-C tasks, I expected frustration and many lost hours and as such I approached with dread. To my surprise it took me a little over an hour to implement it. This was highly encouraging. Progress!
As a whole I feel like I’m starting to finally get a grip on things. Opening up Xcode each night no longer feels like groping around in the dark. Patterns are emerging, Stack Overflow answers are making more and more sense, and I’m starting to tackle little code problems on my own. In a sense I feel like I’m starting to understand the language.
There are so many resources out there now for learning Objective-C, for every problem I’ve encountered, no matter how obscure — and trust me they have pushed the bounds of obscurity, I was copying and pasting native C code at one point to fix a bug — there’s been a helping hand somewhere.
Not to mention the level of sophistication for code support that exists. I used CocoaPods to install the supporting frameworks I needed to connect to the weather service with an ease that should be illegal. The API and Objective-C wrapper (and AFNetworking) were so well done I basically just pasted my API key in there and was delivered a mountain of structured, polished data.
I’m not finished yet, nor am I anywhere near the level to where I can blaze through making apps, but I am at a point where I can encourage you to jump in and learn it because I did and I know you can too.
One thing I did not anticipate — and perhaps couldn’t have until I saw an implemented prototype — is the double tap doesn’t work well on the scroll view.
I had imagined each part of the app as a non-scrolling screen, so practicing the double taps with a phantom app was easy. But when you add scrolling there’s a delay as you wait for the screen to stop moving before you can double tap. The apprehension that arises as you wait is unnatural and I don’t like it. Either it’s back to the non-moving screens or perhaps a different gesture to activate the screen — a swipe perhaps.
However, now that the data is connected and the underlying structure implemented, completing the rest of the daily detail view is just a matter of nailing down the design and a factor of the time it takes to write the parsing code. (And I’m sure there will be some Autolayout optimizing!)
As mentioned in the previous post, as I prepared for building the transition from one view to another, I was worried about pushing data between the two. That ended up being easy. The hard part it turns out was implementing a scrollview. Objective-C is full of surprises!
I couldn’t figure out the right setup to have a view with content “below” the iPhone window that you could scroll to see. After an hour of hammering stack overflow with questions and trying different answers, flipping through the Big Nerd Ranch Guide, and reading through Apple’s documentation and other tutorials on the web, Jeff Jackson answered my question with a single text message. It was quick, to the point, and worked on the first try.Keep reading
Now that views were connected and the transition in place, I needed a way to send the data from one view to another. This ended up being very simple. I loaded the view controller that needed the data passed to it:
OtherViewController *ovc = [[OtherViewController alloc] init];. And then I just assigned the data to a variable, like this:
ovc.hourly = hourly;.
A few things happened behind the scenes: the view controller that was receiving the data already existed (see Presenting & Presented) and the receiving variables, like
hourly above, were already set up in that view controller’s .h file.
Once that was in place the connection was complete. I could call another view, transition to that view and pass data to it. Now all it needed was the visual design.Keep reading
After the views were connected I needed to choose the transition animation. There are three defaults for modal transitions: slide up, flip horizontally or cross-dissolve.
I tested the slide and flip but they didn’t quite convey the experience I wanted. Apple mentions them specifically for use when you want “to interrupt the current workflow to gather information” or briefly “change the work mode of your app,” respectively. I just wanted to show more data, an experience of “diving into the details” if you will.Keep reading
Design is a second order activity. At the base (or zero) level you have physics, thermodynamics, etc. The basic governing laws of the universe. The sun will always rise. The apple will always fall. For every action there’s an equal and opposite reaction.
The first order consists of foundation materials that exist in the world. These can be natural or man-made and I keep a loose categorization with them. It could be the wood you make a chair out of, the ingredients used to make a meal, all the way to the single pixel that can be any color on the screen.
Design—the second order—is shaping these “raw” materials into a discernible, useful and beautiful form. Then beyond design is the user experience layer, or the culture that forms around these designed objects. Distilled further, design is something no one needs, but something we can’t live without.
The object-oriented Objective-C is an entirely new notion. Coming into this project I understood the very basics conceptually, but when it was time to implement the technical details my conceptual understanding wasn’t much of a down payment.Keep reading
Elements in software have technical centers and visual centers. Most of the time they’re the same. When they’re not it’s a minor optical issue that can be sorted with some extra nudging. And when you’re dealing with more than a few instances, it’s absolutely something you have to pay attention to — like when I started sprinkling the app with temperature labels.
Allow me to illustrate.Keep reading
Today I roughed a quick fog icon because I was in the city and there were two blank spots in the app and I didn’t want them to be there.
I’ve been busy with a few other things so I had to skip working on the weather app yesterday. I didn’t have much time tonight either but I wanted to work on it a little to keep the momentum going and make sure what I learned about View Controllers on Sunday didn’t fade any further.
The good news is I hooked up a separate view and got it to load based on a specific gesture — what I had tried to do and failed at multiple times this past Saturday. The bad news is I did it via
UINavigationController which has added a nav bar at the top of the app. But I feel like I’m on the right path — logically I understand what’s happening with the underlying code and why. Tonight has been one of the good ones. Celebrate those. Me? I’m celebrating by going to bed.