Hello Sense, Allergies, and Better Sleep

As I’ve written about before, going to bed and waking up early has been an ongoing problem for me as long as I can remember. I’ve had more success fixing my sleep issues the past ten days than anything else I’ve ever tried in the past. A lot of that has been due to what I’ve learned using this little ball called Sense that tracks my sleep, monitors room conditions, and has a Sleep Cycle style smart alarm clock. After everything I’ve tried, this feels the most like I’m actually close to solving this problem for myself. It’s a crazy feeling after struggling with sleep my whole life.

Sense and pill

I’d used a FitBit Flex as a sleep tracker in the past, but it wasn’t super helpful. As long as I remembered to tap it when I went to bed it did a good job of tracking how long I slept and how much I moved, but that wasn’t enough. I could see I was taking a long time to fall asleep, sleeping too long, and moving a lot gave me zero hints why I could sleep for twelve hours and wake up tired.

The sleep tracking part of the Sense is similar to the FitBit, but has two things that make it better. First, I don’t have to remember to wear anything or tell it when I’m going to sleep (newer FitBit trackers are also automatic). The Sense has a tracker called the pill that attaches to your pillow and then you never have to think about again except to not accidentally wash it. Second, instead of just time and movement, Sense tracks the room conditions while I’m sleeping. I can use the report it gives me to maybe figure out what was going on during the night and why I’m I slept how I did. It also gives me a sleep score which — while I have no idea how it’s calculated — does usually seem to match up pretty well to how I feel the next day.

Sense sleep log

The report tells me: what time I went to bed, fell asleep, what phase of sleep it thinks I was in, when I was moved around, and if there were any noise disturbances during the night.

It also tracks conditions in my room 24 hours a day and tells me if anything is unideal for sleeping:

Sense room report

I started noticing that there were several “noise disturbances” every night, so that seemed like something to investigate. I downloaded an iOS app called Sleep Talk which records noises while you sleep. I then tried to match up the times the Sense said there was a noise disturbance to the recordings to see what was going on. It would be nice if the Sense did this itself, but the app worked well enough.

What did I hear? Snoring and labored breathing. I was “lucky” that I’d been suffering from especially bad sinus allergies and was even more congested than usual the day I got the Sense. Because of this I was able to see my sleep quality improve over the next few days as my congestion got better. I’ve never been able to breath well through my nose, and I’ve also always had trouble with sleep, but for some reason I’d never considered the two might be connected. I started reading online about breathing, and of course not breathing well affects your sleep. In fact, that’s probably why I could sleep twelve hours and still be tired — it took me that long to get enough quality sleep to be rested.

I decided to do an experiment. I knew that Zicam nasal spray would clear out my sinuses instantly, but that I could only use it for a few days in a row. I used it before going to bed one night to see what would happen. I also read that sleeping on your side is better for breathing and that a pillow between your legs helps you stay off your stomach, so I did that too. The next three days that I took the Zicam before bed I woke up by 8:30am after about eight hours of sleep feeling fine and rested. That’s remarkable for me. I honestly can not remember having a change like this before. My Sense sleep score also went up (from the 70s to the 80s).

Since I couldn’t take Zicam for more than a few days, I also began taking Claritin every morning (as well as D-6, B-12, and a daily multivitamin). The Claritin helps, but not as much as I’d like. After some research, I found out that Flonase is usually better for people with year round allergies, and so I’ve started taking that. It takes a few days to reach full effectiveness, but the initial results are promising.

I don’t want to speak too soon, but I think I may have figured this sleep thing out.

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.

My Weekend With Twilight Princess HD

I spent a good part of the weekend playing The Legend of Zelda: Twilight Princess HD that came out Friday for Wii U. I played the Wii version of Twilight Princess a bit, but bounced off of it because I found the motion controls tedious. This remastered version is based on the GameCube controls, and so it’s all buttons instead of waggling a Wii remote at the screen.

Besides Link glowing in one scene for no apparent reason, the updated graphics look fabulous. While I don’t find the art style quite as appealing as what they did with Wind Waker HD, and the graphical fidelity is nowhere near something like The Witcher 3, I haven’t ever felt like I’m looking at a ten year old game. If anything it’s exceeded my expectations graphically. Some of the controls have aged less well, but nothing that makes playing the game not fun. The two control issues I’ve noticed is that the camera will sometimes do strange things, and getting Epona to turn around is painful.

Anyway — I’m going to be playing more of it this week. If you have a Wii U and like Zelda games, definitely check it out.

Moving From Parse to OneSignal for Push Notifications

Parse is shutting down, and if you want your app to keep working, you’ll need to move to something else. I’d recommend doing it sooner than later. Thankfully our app isn’t out for another few weeks, and since the only thing we were using Parse for was push notifications, it wasn’t more than a couple hours of work to switch over to something new. The thing we found to handle our push notifications was One Signal.

Aside from Parse I’ve also used Urban Airship, Push IO, and a custom push server. Custom was definitely the worst. If I were writing the backend myself, custom might not have been so bad, but since I was always working with other developers, it was always a pain because it required involving someone else to test the thing and there was always something wrong with the certificate setup on the server. Out of all of those OneSignal has been the easiest, followed by Parse. I like OneSignal better than Parse though because it’s just push instead of one part of a larger thing that sort of expects me to be using their whole platform.

Email Validation String Extension

I’ve been using this extension on on String to make checking if a string is a valid email easy. If you know a better place this could live, let me know, but an extension on String felt as good a place as any. I didn’t write the original regex (although I did need to tweak it to make addresses with + in them work), but I’ve tested it and it works well as far as I can tell.

extension String {
    func isValidEmail() -> Bool  {
        if self.isEmpty {
            return false
        }

        guard let regex = try? NSRegularExpression(pattern: "^([a-zA-Z0-9_\\-\\.\\+]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", options: []) else {
            return false
        }
        return regex.numberOfMatchesInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == 1
    }
}

Less Gross Storyboard Segue to a Navigation Controller

This is a really ugly piece of code I’ve found myself writing in Swift whenever I’m preparing a storyboard segue where the destinationViewController is a UINavigationController whose root view controller is the thing I actually need to set properties on:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let viewController = (segue as? UINavigationController)?.topViewController {
        // Set up the view controller
    }
}

And so I decided to make this slightly less terrible by adding this category to my app:

extension UIStoryboardSegue {
    var navigationController: UINavigationController? {
        get {
            return destinationViewController as? UINavigationController
        }
    }
}

So now that ugly line becomes this:

if let viewController = segue.navigationController?.topViewController {
        // Set up the view controller
}

In Praise of Non-Magical Pointing Devices

Last week I tried playing a game on my Mac for the first time in a long time. About a minute in I realized that a trackpad or Magic Mouse was not going to cut it. I needed something with actual separate buttons that click. The one I landed on, after reading a few positive reviews, was the Razer DeathAdder Chroma. Yes, I agree the name is ridiculous. I choose not to focus on that.

I like it for a few reasons:

  • It’s the number one gaming mouse on Amazon, but doesn’t look too much like a gaming mouse, which is good, because I couldn’t look at one of those and take myself seriously.
  • It only has two side buttons, which is just the right amount for me. I bound them to back and forward in Safari, Xcode, etc.
  • The driver software is fantastic for the tiny bit of tweakiness I want (assigning those side buttons), and also totally Mac compatible. You can even easily set different button configurations for different apps, and it will switch automatically.
  • It feels pretty good in my hand. The buttons feel nice and clicky, too. The Magic Mouse gives me hand cramps.
  • It was only $50.

The things I miss are interial scrolling and gestures. But those suck on the Magic Mouse anyway, and are easily fixed by placing my trackpad on the other side of my keyboard for gestures.