Hawaii Trip

We spent the last week on the Oahu island of Hawaii, getting home late last night. It was an amazing trip and couldn’t have gone any better. We rented an AirBnB house in Kaneohe (which is the windward side of the island). The weather was quite good most of the time; even when it was raining, the rain was warm. Quite the change from Seattle.

View from Diamond Head

Waikiki Beach

Going into the trip I was most nervous about how the boys would do. We took them on a plane last year to Phoenix but Finnian is 20 months now and can’t be still for more than 3 seconds. We didn’t buy him a seat on the plane so he was going as a lap baby. Atticus is 4 now and we figured we could distract him with shows & movies on “his” iPad. They both did wonderfully well. A couple of screaming fits by Finnian but that was manageable by getting him to sleep.

Dole Pineapple

Tree on the Dole Train

Of course, I took along my camera. I’ve got the Sony A7II body and while I normally have a 50mm f1.8 prime on there, I wanted something that could capture the landscapes we’d be seeing and get good portrait shots of us on the trip. So I rented the Sony 24-105mm f4 zoom lens from Hawaii Camera. In short, the lens is amazing and now I want one.

Emily had done tons of research and put together a packed itinerary that got us all around the island. We hit up the Dole plantation, the North Shore, hiked Diamond Head and hung out on Waikiki beach, visited Sea Life, and went to a luau at Disney’s Aulani resort. We had a lot of fun and came home really tired.

Finnian before the Luau

Atticus on the trip home

Xcoders Talk: Practical Coordinators

Last November I gave a talk at the Seattle Xcoders meetup about the coordinator pattern. There’s been a lot of virtual ink spilled on the topic of design patterns and the coordinator pattern specifically. I’ve been using it in a refactor of a side project app as well as using it pretty heavily at zulily in some of the new projects I had been doing.

I got inspired to give the talk after last year’s Swift by Northwest conference, where Dave DeLong gave a really great talk about improving MVC. He has a different take on coordinators than I do and his solution is really interesting. But I like where I’ve landed with coordinators for the time being personally.

I decided to put a little different spin on this talk than I’ve seen in other coordinator talks, and prepped a sample app that I would refactor. We go from storyboard segues to a coordinator handling the transition between two screens. There was a lot of live coding and it worked out pretty well. I hope it’s entertaining if not useful for you and I’d love to hear your thoughts on how it all turned out.

Video: https://vimeo.com/258453512
Slides: https://d.pr/NfRMIt

Making Proper Apps From Websites

While at zulily, I used to have JIRA and GitLab inside of wrappers provided by Fluid instances. Now that I’m at Lyft I’ve done the same thing with JIRA, but we use GitHub instead. For the longest time I would take links sent to me for those pages and paste them into the apps by hand since clicking on the links would open my browser instead of the app silos that I hand-crafted for these sites.

Well today @jackbrewster taught me about something great that takes this to another level. The app Choosy will let me route URL clicks to whatever app I want. I set up rules in Choosy to look at the web address that I clicked and now have it routing my JIRA and GitHub links to their proper Fluid apps. It’s wonderful!

My default browser is Safari, I keep Chrome around as my Flash ghetto (and now only it can be used for Meet as well). I can use Choosy to send the Hangouts/Meet links straight to Chrome as well. This makes everything feel completely seamless.

One other tip I got from Jack was about 1Password. Fluid instances don’t support it directly but you can invoke the global 1Password mini, find the site you need, and press ⌘⇧C to copy to the clipboard. Focus will then switch back to your Fluid app and you can paste the value in there. I was using the mouse to do this previously. This way sure seems a lot better.

Missing Options in Swift

The default behavior of iOS is to not show a notification (like the kind that comes in through your phone’s lock screen or Notification Center) if the app is in the foreground. I’m working on a ticket for the Lyft app to show or suppress notifications that come in while the app is in the foreground. iOS 10 introduced a whole new UserNotification framework that lets us do just that!

The delegate of our notification center will get a call aptly named userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void). Since we always have to call the completion handler – and that parameter defines the type of presentation we want – we can now control the notification’s display.

In Objective-C the options are so:

  • UNNotificationPresentationOptionsNone (kind of)
  • UNNotificationPresentationOptionsAlert
  • UNNotificationPresentationOptionsBadge
  • UNNotificationPresentationOptionsSound

But in Swift, UNNotificationPresentationOptionsNone is not available. In fact, you can only really see the docs for this option at this page. It’s listed as a Global Variable, and not a member of an enumeration. There’s a separate page for the UNNotificationPresentationOptions enumeration.

So I fired up a sample project and made a method that returned None from Objective-C and bridged that over to Swift. Of course it works, and the raw value is 0. So the options for my ticket are either add Objective-C back into the project (all our code is Swift) just to bring this over, or make a local variable set to a raw value of 0. The latter is likely what I’ll end up doing.

I’ve filed radar 36166279 to address this.

Update 12/21/2017

After posting this, Jake Carter replied to me on Twitter with an idea:

When I got in to the office this morning I gave it a go and it worked! I’ve used the [] syntax before so I’m a little disappointed that I didn’t remember it. I plugged that into my sample app and its rawValue turned out to be 0. So now I don’t have to choose between two bad options.

I think what tripped me up was seeing that the Objective-C version was an enumeration coupled with me not seeing that the Swift structure conforms to OptionSet. If I had slowed down for just a couple of minutes then I might have noticed.

I think I’m going to leave the radar open, though. I will probably amend it with these findings and make it more of a documentation issue rather than needing to add a new option to the UNNotificationPresentationOptions type. Thanks Jake!

Introducing Custom iOS App Analytics

TL;DR: Check out my new iOS framework for using CloudKit to track app analytics: TPHCloudAnalytics.

In my current reworking of Scorebook I wanted to get rid of Cocoapods if I could. I don’t have anything specific against it, but I wanted some more rapid development of my own framework code. So I moved the private pods I had to git submodules. This left me with only the Fabric and Crashlytics pods leftover.

While Fabric’s dashboard is quite impressive, they’ve added almost too much for my needs lately. I just want something simple to tell me how many sessions I’m getting with some basic device info, and maybe some ability to track custom events. Plus, removing Fabric meant that I could remove all closed source frameworks from Scorebook.

I had the idea a little while back to build analytics on top of the CloudKit public database. Today I had the opportunity to make it. The source is all up on Github here.

It’s fairly rough right now, only sending data to CloudKit. In the long-term I would like to add an iOS or Mac app that can ingest the data from CloudKit and present a nice dashboard. But for now this gets you to the place of recording your data.

I’d love any feedback you have to give.