Creating StoryWorth for iOS 1.0

I’m really excited to announce that a new app I’ve been working on for several months has come out today. The app is called StoryWorth, and you can download it now. It’s a companion to the website of the company I work for. StoryWorth lets you collect and share (with recipients you choose) your family stories. To get started, you invite a storyteller (mom, dad, grandma, etc), and then we start sending them questions. They can answer through the app, email, or on the website with text, images, or audio. Once you’ve collected some stories, we can print them up in a nice book (you can pay to have audio transcribed) you can put on a shelf and keep forever, regardless of what happens to us. I should mention too that StoryWorth is a paid service. We’re not interested in showing you ads or selling your information.

Oh, also, we have an app now. It looks like this:

HomeStorytellerStory

Design

For the design, a big focus was accessibility. We have users as old as one hundred, so we could be pretty sure some of the people using the app would have limited mobility or vision. The default sizes for text in the app tends to be a little on the large size, but I also did my best to support Dynamic Type so that users who needed to could turn up the font size. I’m looking forward to taking the accessibility stuff even further in future versions.

Aesthetically, we wanted to go for sort of a book feel, while still looking cool and app-like. We did that mostly by focusing on typography and restricting the color palette so that the content and actions really stand out from each other. We use a sans-serif font (Lato) in our primary red color (except in navigation and toolbars) for actions, and a serif font (Merriweather) for most content and long form text entry. Overall I’m really happy with how the design of the app turned out.

When choosing what features the app would have, our goal for 1.0 was to get parity on the most important things (writing, reading) with the website. It’s not completely one for one yet, but it’s an awful lot of it. Having a solid basis of a native app is also going to let us do things that the website can’t do easily when it comes to things like recording audio, offline reading.

Technical

StoryWorth is the first app I’ve shipped that’s entirely written in Swift. In the beginning, learning Swift while writing the app probably slowed me down a little bit, but it didn’t take me very long to become productive. At this point I feel completely comfortable in Swift and think I made the right decision. Swift still has some rough edges, but there’s enough good there to make it an overall win. Mostly the problems I run into have to do with using it with the iOS frameworks, storyboards, and other things that came around before Swift existed.

Speaking of storyboards: I don’t know, man. I used them, and I guess they made things easier, but I also sort of want to tear them out half the time. I hate how they’re stringly typed, I hate prepareForSegue:, and I hate how using them pretty much precludes being able to use non-optional properties in my view controllers. On the upside, they’ve improved a bit over time. Storyboard references make it easier to break up a big monolithic storyboard into many smaller ones. Setting up child view controllers is really easy in a storyboard too. I only used a static table view in one place, and it ended up needing some cells to show or hide conditionally, so that wasn’t especially useful. As cool as that is, it turns out I never end up having more than one or two static table views in an app.

Going back to Dynamic Type, there’s a couple of things I did to implement that. The first was to create UILabel subclass which listens for content size category notifications and adjusts itself as needed. This worked pretty well for pretty much anywhere I had labels, but not for some other things. Dynamically sizing table view rows were also a godsend, since all I had to do was set up my constraints and the table view would do the right thing if the font of it’s contained labels got bigger. Overall, I found working with Dynamic Type sort of a pain when it comes to native views. I’d like to come up a better solution in the future that will make it easy for me to support it in the places I didn’t get to in 1.0.

I do use web views in a couple places in the app though, and it turns out supporting Dynamic Type in those is crazy easy. All you have to do is use one of the -apple-system styles for your CSS font property, set font-family and font-size (in em) to whatever you want. Make your controller listen for UIContentSizeCategoryDidChangeNotification, and whenever a notification comes in, reload the web view. Easy. There’s a good post about it on the official WebKit blog.

Grab Bag

  • UIStackView is rad.
  • Protocol extensions are neat and useful.
  • The new Swift selector syntax doesn’t like nil targeted actions.
  • Carthage breaks much less than CocoaPods for me.
  • I love universal assets.
  • I don’t know if I’m going to stick with Core Data.
  • Color spaces are confusing.
  • App review remains a magical experience.

Conclusion

I took a job at StoryWorth because I wanted to work with nice people on something that’s actually useful, whose business model I understood, and where I could have a big impact. It’s been a while now, and I really like it still. I’m excited to improve the app over the next several months. Please download the app and invite your family. There’s a free trial, and if you decide to subscribe it helps us a lot. Getting to know your family and having something to hold onto forever is something you’ll thank yourself for.