Creating Data Models in Swift With Core Data

Because of the lack of a built-in utility for creating data models for Core Data entities, a lot of tools have popped up to make developers' lives easier. Most notably among them, mogenerator. Mogenerator accomplishes a number of things. For sake of later comparison, I'll list a few of the most useful mogen features:

  1. Simple, easy creation of classes for your data model.
  2. Pattern of two-class creation -- allows you to have and keep custom code without risk of overwriting it, while still maintaining flexibility to update your entity's attributes in .xcdatamodel. Updates regenerate the second file, leaving the entity class file and added custom code in tact.
  3. Convenience methods to access the attributes of your entities.
  4. Scalar accessors that let you access BOOLs, integers, floats, instead of just NSNumbers.

I'm currently working on a project in Swift, which means another chance to reevaluate existing patterns and old habits that may or may not fit into the Swift paradigm. On a side note, hasn't the release of Swift been great on a meta level? I know of so many people and companies that have been able to use Apple's release of a new and powerful programming language as an opportune moment to fix or completely redo areas of their codebase that were dragging on the entire app (or company). Once you're caught in the technical debt trap, it's almost impossible to get out. But it is possible. And fortunately for us, Swift makes it easier and faster than ever before to write clean, maintainable, beautiful Cocoa apps.

I was recently at a SLC CocoaHeads meetup and asked the group if many people still use mogenerator in predominantly Swift projects. I was immediately directed to an Xcode feature that I've missed amongst all the other Apple news, a job change, and a relocation from SF to SLC over the past few months. Or maybe this came out with Swift 1.0? I'm not entirely sure. Either way, they told me Xcode can now generate classes for your models in a two-class pattern similar to mogen. Of the four mogen features mentioned above, the first two are now seamlessly integrated into Xcode + Swift.

To be fair, creation of NSManagedObject subclasses was always possible... and from Xcode 4.3 you've been able to do it from the Editor Menu too (pictured below). I actually wasn't aware of the Editor Menu trick... my experience with Core Data comes from working with it on two previous occasions. On one I was contracting with the team for six weeks. It used mogenerator and was my first exposure. My involvement with Core Data there was limited to referencing the data model and minor tweaks. The second project's Core Data implementation was completely manual. I took over the project and worked on it as the sole developer. Two very contrasting approaches, both suiting their needs just fine.

Back to the Swift + Core Data goodness, by selecting your .xcdatamodel file and opening the Editor Menu from the Menu Bar, you'll be given a contextual set of options relating to Core Data. Select Create NSManagedObject Subclass, select the data models and entities you'd like to manage (select all for the first time, select one or a few for an update), select the destination directory and create. This will create two files for you. The first is a subclass of NSManagedObject and represents your entity. The second creates an extension (similar to the Objective-C categories approach) called EntityName+CoreDataProperties.

//  User.swift
//  Perspectives
//  Created by Kyle Clegg on 11/19/15.
//  Copyright © 2015 Kyle Clegg. All rights reserved.

import Foundation
import CoreData

class User: NSManagedObject {

// Insert code here to add functionality to your managed object subclass

//  User+CoreDataProperties.swift
//  Perspectives
//  Created by Kyle Clegg on 11/19/15.
//  Copyright © 2015 Kyle Clegg. All rights reserved.
//  Choose "Create NSManagedObject Subclass…" from the Core Data editor menu
//  to delete and recreate this implementation file for your updated model.

import Foundation
import CoreData

extension User {

    @NSManaged var email: String?
    @NSManaged var password: String?
    @NSManaged var name: String?
    @NSManaged var userId: NSNumber?
    @NSManaged var collections: NSSet?


As the comments auto-generated by Apple note, EntityName+CoreDataProperties.swift will be scratched and regenerated when you run through the process again after you update your model in the future. That's the beauty of it. Any convenience methods, helpers, accessors, etc. that you may want to include should be added to the entity's class, and updates are handled by Xcode without destroying your code in the entity's class.

Gotchas? Nothing major really. I suppose two minor things are that CMD-clicking the entity when it appears in code in other places can bring you to an empty User.swift file when what you really wanted to see were the properties. A little annoying, but understandable. A second one is that when you regenerate models after a property update or addition Xcode doesn't overwrite the EntityName+CoreDataProperties.swift file. It creates a second one. Just select one of the two (either one), hit delete and select Remove Reference. ¯\_(ツ)_/¯

So there it is. Simple data model creation and updates using Swift extensions and native Xcode integrations. I should note that we are losing some functionality provided by mogenerator, but I'm okay with that for now. Mogenerator gave me way more functionality than I asked for, and I'll bring it back in the future if I feel like I need it. For now, I rest easy knowing that there's no magic going on, just simple, clean Swift Core Data code.

Hiking Half Dome

A few weeks ago I hiked Half Dome with my parents and sister. If you're unfamiliar with Half Dome, it's a huge granite dome that rises almost 5,000 feet over the main valley in Yosemite National Park. It's a challenging 16 mile round trip hike that requires being in a good shape and preparation, but isn't beyond the realm of possibility for regular people.

2015-09-08 07.01.00.jpg

We started at 5:30 AM from Upper Pines campground, which was about a 15 minute walk from the trailhead. Next time, I'd try to start at 3:30 or 4. It's not that the trails are too busy... it's just a long day ahead of you and you don't want to be pushing sunset at the end of the day. The cabled section near the summit is busy pretty much every day from 10 AM to 4 PM, so unless you start really early (3ish or earlier), there will probably some sort of wait and crowd near the top, but more on that later.

The good thing about starting before sunrise is that early morning hiking seems to pass by quickly. When you can't see past your headlamp's shine you focus on putting one foot in front of the other. We made good, quick progress before sunrise as a result.

Oh yeah, before I go any further... what are those things on my feet, you ask? And yes, lots of people asked. For the past five years I've worn Chacos for pretty much any outdoor activity I've done with the exception of running, including whitewater rafting, hiking, and canyoneering. The longest hike was probably 10 or 12 miles, so I was a little concerned about 16... but not too worried.

After my dad asked me about a hundred times about wearing open toe shoes the night before -- and even offered (insisted) I wear the extra pair of hiking shoes he brought -- I have to admit, I was wondering if I was pushing past the suggested Chacos threshold. With 1 bar of Edge service I googled "Hike Half Dome in Chacos" from the lodge, found nothing, and decided if I'd hiked Mt. Timpanogos with no issues I should be fine. I started the hike with a pair of socks on just to be on the safe side and took them off after two hours.

2015-09-08 07.54.06.jpg

About two-thirds the way up, after crossing paths with well over a hundred other hikers, and to my dad's surprise, we encountered a second Chacos-wearer. In her mid-fifties and sporting a full-length hiking skirt, she caught up to us as we were paused for a rest. She commented that she'd been following my tracks for a while, searching for her Chacos mate. While I can't say I recognize Chacos footprints myself, I'm very impressed. Respect, Chacos lady, respect.

The final ascent to Half Dome's summit includes a 400 foot stretch of metal cables, at as much as a 45 degree angle. The cables were initially put in place almost a hundred years ago and they allow anyone with a good pair of gloves to ascend relatively safely. Injuries and death have occurred, but they are uncommon. The cables make for a interesting, almost welcoming challenge after propelling yourself 8 miles straight uphill with your legs.

As we were hiking down a wildfire broke out to the northwest of the summit. A few helicopters and half a dozen planes showed up, surveyed the scene, and dropped powdery red fire-retardant.

There are two main trails you can take to Half Dome. The John Muir trail is a bit longer, but less strenuous, while the Myst trail is shorter but much steeper (and full of hundreds of huge steps). We took the John Muir Trail up and the Mist Trail down. We hustled down the mountain and got back to camp right at dusk.

Feet-wise, the Chacos did the job, and some. They had excellent grip on sub dome's and Half Dome's granite surfaces, and got me home 100% blister free. If you're questioning whether your Chacos can handle Half Dome, the answer is yes... so long as your feet are used to the straps and you've done a few shorter hikes with them before. As far as who fared better on the mountain between my old man and me, I'll put it this way. One of us never had to stop to change socks. One of us made it up and down without blisters. It's the same one.

Embracing Diversity

Alternate title: Why we're failing at diversity and what we can do to fix it.

Diversity is one of those things all businesses want. Like creativity or innovation, it sounds great, feels hip, and helps your business look good, right? But do we really value diversity, or just the word itself? When talking about diversity the first obstacle to tackle is understanding why it matters so much. Otherwise it may be misunderstood and relegated to another checklist item like ping pong tables , free meals , and bring your dog to work Fridays .


So why is it important? Because diversity directly translates to success. A recent study by First Round Capital found that companies with a female founder performed 63% better than all-male teams.

Diversity is an opporTunity

Think about that. That's a 63% higher ROI for investors. That's real return, real profits, real success. It benefits business owners, investors, employees, and customers alike. Diversity works. It breeds success and is NOT a checklist item. It's an opportunity, and with increasingly competitive industries on all fonts, it's a big one.

We should think about diversity similar to how to we think of innovation. There’s no magic moment when a company or team becomes innovative. Rather, ongoing innovation drives the success of the product, culture of the team, and evolution of the company. Tell me the last time you thought, “Whew! As of our last hire we are now innovative.” Ridiculous, of course. Diversity, like innovation, is something we actively work to improve. And remember, the reason why... diversity drives success.

So What is diversity

Before I go any further I should clarify, what is diversity? It's not just about skin color or gender, that's for sure. Which is part of the reason why throwing up a "diverse" team picture on your company website (worse yet, paying actors to model for it) or holding an obligatory women-in-tech panel at a conference doesn't all of a sudden mean you're diverse. The power is in creating an environment with diversity of perspective, experience, and thought. In slightly different words, as Entrepreneur put it recently, conflict is part of human nature.

Why can’t we all get along? Because we can’t. Conflict is part of human nature. There are times when it’s important that we don’t get along. There are times when we need to confront our differing viewpoints and learn to conflict in productive ways. The great irony is that the process of learning how not to get along is critical to building successful relationships and effective teams.

Diversity doesn't necessarily mean we don't get along, but it does mean valuing perspectives and giving differing ideas ample chance to be explored. Conflict, so long as you steer clear of cheap shots and toss egos out the door, can be a powerful thing. Learning to confront our differing viewpoints and conflict in productive ways can drive the development of new ideas, strategies, product designs, and more.

I support diversity, I swear

Is diversity actually a problem today? Yes. This post isn't meant to be an attack on anyone. But at the same time, I'd guess that 99% of the people who hear the word would think, "chyeah, go diversity, for sure!"

And yet, things like above still happen. All. The. Time. A few weeks ago at a tech conference a talented female founder and CEO told me that the lead investor in her company asked to meet without her present at the next board meeting. She obliged because with no other interested investors, she didn't have any other options.

Let me give another example with a wider data set. Recently, a study was performed where employee reviews were collected from men and women in tech. 245 reviews were collected, from 180 people, 105 men and 75 women. The reviews were shared voluntarily with no special stipulations about gender or any other factor. The question to be answered was "Did review tone and content differ based on gender?" The results:

Critical feedback was not evenly distributed by gender. 59% of the reviews received by men contained critical feedback. 88% of the reviews received by women contained critical feedback. In other words, "Men are given constructive suggestions. Women are given constructive suggestions – and told to pipe down."

While both men and women received constructive criticism, women were also more likely to receive negative personality criticism... much, much, more likely in fact. "This kind of negative personality criticism—watch your tone! step back! stop being so judgmental!—shows up twice in the 83 critical reviews received by men. It shows up in 71 of the 94 critical reviews received by women." The manager's gender did not affect the nature of critical feedback in the review.

There’s a common perception that women in technology endure personality feedback that their male peers just don’t receive. Words like bossy, abrasive, strident, and aggressive are used to describe women’s behaviors when they lead; words like emotional and irrational describe their behaviors when they object. All of these words show up at least twice in the women’s review text I reviewed, some much more often. Abrasive alone is used 17 times to describe 13 different women. Among these words, only aggressive shows up in men’s reviews at all. It shows up three times, twice with an exhortation to be more of it.

I would challenge ourselves to think honestly about our past experiences. Were we more quick to perceive a woman's opinion or action as "abrasive" than a man's? According to this study, the answer is likely yes. In addition to promoting equality, welcoming differing opinions can lead to healthy debate and challenging the status quo in ways that may not have occurred otherwise.

Without a culture of diversity -- as well as a framework that allows teams to openly challenge the status quo and debate ideas free from intolerance and dogmatism -- we run the risk of 1) failing to give good ideas a chance to be explored, 2) bad decisions being made for the wrong reasons, 3) team members feeling their views are suppressed, and 4) losing valuable team members entirely.

What can we do?

Well, that may have been a lot to process. Fortunately, we're coming to a set of solutions. Suggested by @br_ttany at #TechFestNW last month, there are two simple action items that will translate into immediate results in terms of walking the diversity talk.

  1. Identify inconsistencies
  2. Amplify voices

Identify inconsistencies

When we overhear racist, sexist, or otherwise prejudiced remarks or spot other inconsistencies in our goal to be open, inclusive, and diverse let's talk about it. This means looking at promotional materials and job perks, considering our lunchroom conversations, office environments, and business trips, and prioritizing what's important. Do you value diversity? Are you communicating it?

I recently attended #StartFEST in Provo, Utah. I was blown away by the support from local communities and the success of growing businesses. It's really something, what's going on in the Salt Lake area. One thing I found disappointing, however, was the lack of diversity in the tech community. In one presentation, a local VC firm celebrated their prized founders list (pictured in slide).

See any issues? 100% male. 90+% caucasian. Conveying to all in attendance that THIS is what success looks like. We need to fix this. Why is it an issue? Because the way we portray success translates into the way we hire, manage, and run our companies.

I would be so proud to be a part of a diverse tech community, where seeing women and people of color in these types of presentations is commonplace. I hope we'll get there soon.

Amplify voices

The second key action we can take is to amplify differing voices and opinions around us. That means taking the time to listen to people who are not like you. Yes, fixing diversity in tech is a big, challenging issue, but throwing our hands up is not an option. Take a look at your Twitter and Instagram feeds. Find people who are different from you and follow them.

Amplifying voices different than your own shows you respect and support people of varying backgrounds, experiences, and perspectives. And frankly, we need more of that in the world. If it helps lead to successful businesses and growing economies, which it does, then I'm an ally.

Moving Onward and Upward

It's come time for Dru and I to part ways with First Opinion. It didn't turn out to be the right long-term fit, but I am proud of what we were able to accomplish in the last six months. Implementing drastic changes as a brand new employee has been one of the most difficult things I've been faced with in my career. There's a few things I'd like to do for my own reflection.


I didn't accomplish as much as I would have liked, and I have much to work on to improve my ability to promote change. However, I'd like to make a list of the things I accomplished with the help of the team and the hard work of a great product manager (who probably shouldered more of the work than anyone). I guess I'll call this the high-level "timeline of success".

  • Eliminated dozens of bugs in the iOS codebase
  • Launched a new results feature, giving patients summarized outcomes of their doctor consults
  • Added robust analytics tracking to monitor use and performance of app features
  • Laid the groundwork to integrate video-based telemedicine services into core product lineup
  • Worked towards a HIPAA compliant software stack
  • Guided a transition in mobile app design from a pixel-perfect to constraint-based approach, relying heavily on the Human Interface Guidelines.
  • Identified weaknesses in the engineering process and worked together towards valuable improvements
  • Established periodic product team meetings to discuss vision, roadmap, and designs
  • Established periodic retrospectives as an open forum for team discussion and reflection

I didn't accomplish any of the above below items myself, and of course there is much more work to be done. However, we made some very significant strides in these areas that I feel, and hope, will be beneficial to the company long after my name is no longer found in file header comments, Confluence pages, and commit logs.


I also want to reflect back on what I've learned. I've had many moments of clarity over the last year where I realized things could or should've been different than what actually happened. Tempting as it is to write a longform post-mortem detailing all the reasons why First Opinion didn't work out, I'll skip it. My goal is to get back to one of the things I enjoyed as a student, writing a series of blog posts about key learnings and takeaways, but now with the experience of working with startups in Utah and San Francisco.


Early Watch Thoughts

I ordered an Watch the day preorders began at about 5 PM. (P.S. The shortcut for the  character is option-shift-k on a Mac. Memorize it.. it will come in handy.) Between my indecisiveness about which case and band combination to get and other things going on I missed the midnight-sharp preorder. So, I had to wait about a month longer than a lot of my developer friends to receive my Watch.

It finally arrived on June 1. Unfortunately for me, I didn't make it back to my apartment before the front desk attendant that received it locked up for the night, so I had to wait another 12 hours before getting it the next morning.

Current status: Watch in hand. Lola is thrilled.

A photo posted by Kyle Clegg (@kyleclegg) on

So... just... why?

I've been asked several times before and after I got the Watch why I wanted one. There's a couple reasons:

  1. I'm an iOS developer. My entire industry was created almost overnight when Apple released the iPhone and subsequently the App Store seven years ago. Watch is a new platform, and although people are justifiably skeptical, I want to be familiar with the device itself, its apps, and the tools for building watch apps given that it could have profound effects on my future career.
  2. For almost two years now, Wired, FastCompany, Mashable and the like have been proclaiming wearable tech will become an industry as big as the smartphone. We've seen some interesting products like Google Glass, Pebble Watch, Fitbits, Jawbone Up, Garmin GPS Watches, and tons more, but nothing has really pushed us into the phase of ubiquitous wearable technology. Will Watch do it? I don't know, but I'm anticipating it'll bring us closer than we've been in the past.
  3. I'll admit it. I've become quite enveloped in the Apple ecosystem since moving into iOS development three years ago. I use a MacBook Pro on a daily basis, an iPhone, and an iPad. I used to use an iPod before my iPhone replaced that need for me. I enjoy the quality of Apple products (as I also enjoy the quality of my Xbox One and old Nexus 4) and their relentless attention to user experience. I hoped that the trend would continue with Watch.

The Unboxing

This isn't me, but for reference... 

The packaging was nice, as it always is for these types of products, and the pairing process was beautiful. Your phone becomes a scanner while a nice animation displays on your Watch. You point your phone's camera at it and you're paired.

First Impressions

Love it - Setup

There's no need to search for and download 50 apps to get up and running. Because you already have an iPhone full of useful apps and because many of those app developers wanted to provide you with an Watch experience, all you have to do it select which apps you already use and love on your phone that you now want on your watch. On top of that, you don't have to login or configure anything for those apps, since they're already authenticated from your phone.

Love it - Notifications

I've long felt that something is wrong with iOS notifications. From 2009 to 2012 I would switch back and forth between Android and iOS each year and always felt that Google had figured it out with their notification management. On Android it was easy to receive notifications, even in other apps or games, and decide whether to engage or ignore. The notification would also clear when you opened the app later, preventing you from a mess of old notifications hanging around your notification drawer. 

Apple has improved notifications greatly since 2011 with the notification center, actionable notifications (reply to text message, etc.), and the ability to clear multiple notifications simultaneously, but I still find my notification center clogged with alerts that haven't been relevant to me for days. Already, the Watch has solved part of this problem by giving me easier access to my notifications.

Love it - The inconspicuousness

I didn't want to become a glasshole. Well, I didn't. Err least don't think I have. I live in San Francisco and need to keep my head up when I walk to work so I don't get hit by an Uber driver. To that point I really like being able to get a notification to my wrist. It saves me from needing to pull out my phone probably 50-70% of time. Random ESPN notification? Nah. Urgent work thing? I'll pull my phone out and look into it.

Love it - Battery life

There's not much to say... it's really good. Definitely gets you through the day. I think Apple played it smart by limiting third-party developers from accessing some of the higher energy-consuming features of the watch for the initial launch. This fall, third-party apps will be allowed access to the speaker, microphone, heartbeat monitor, and other sensors. Battery life will definitely be affected, but I trust Apple wouldn't open up the developer toolkit unless they had a good way of ensuring the majority of apps won't turn into battery guzzling drains.

Love it but needs improvement - Apple Pay

Apple Pay is nice. Dru and I both use it on our phones when at Walgreen's or Whole Foods. On Watch it's even more convenient, so thumbs up there. The first time you use it, though... it's awkward.

On that third graphic how would you think you activate Apple Pay? The part where it says "Double Click to Pay?" I'll give you a hint, it doesn't involve any TAPPING. You double CLICK the side button. I guess you learn it once and you know, but when you have a line of 5 impatient San Franciscans behind you at Whole Foods and can't figure it out for the life of you... it sucks. Hypothetically speaking, of course. So while I love the convenience of Apple Pay from a watch, the education behind it still needs improvement.

It's okay - Default activity tracker

It's pretty cool, I think. I haven't been meticulous in setting target numbers, but in general it's helped me pay more attention to my health throughout the day. And I haven't turned it off yet, so that's a good sign.

It's okay - App loading times

Some apps (including Apple apps) take a little while to load. This should also be improved this fall when apps are allowed to run natively, rather than relying on your phone's Wi-Fi and the watch's bluetooth connection to your phone. It'll also improve as app developers get more familiar with the platform and optimize their apps for Watch (e.g. by not loading tons of data up front like they may be able to get away with on iOS or Android).

Needs improvement - Becoming a staple

The device isn't on the level of making me turn around and go grab it if I realized I've forgotten it five minutes after leaving my place. Maybe it'll get there. I also sometimes forget to charge it at night, which means I either leave it home for the day or bring the charger with me and plug it in somewhere.

Watch Apps

Some of the apps I use:

  • Faces - The default screen that shows when you look at your watch. I chose the solar face because I think it's pretty awesome. 
  • Instagram - the square nature of Instagram makes Watch a great platform for it. It's surprisingly easy to browse Instagram from the watch. I think my IG activity might've doubled since it's one of the first highly functional non-Apple Watch apps I've found.
  • Twitter - not crazy functional, but useful.
  • Timer - it's just easier than an iPhone timer for some reason. Small thing, but nice.
  • Slack - you can't scroll full channels of chat messages, but you can see DMs and mentions.
  • Passbook - Dru and I have seen two movies by just pulling up a Fandango pass on Watch. The theater attendant scanned the QR code on the watch and we were in. Really smooth both times.

I'm sure I just haven't been exposed to dozens more great apps. If you have any that come recommended, please let me know.

Watch or Watch Sport

I couldn't decide which one, and you might be in the same position. I ended up ordering the sport edition (black aluminum case) the first day so I could get my order in, but then changed my mind and ordered the stainless steel with black leather loop. I didn't cancel the first order, and both have now arrived so I've actually been able to play with both models. I decided to keep the Watch Sport because I liked how I really liked the inconspicuousness and how lightweight it is - it just felt normal and right. It was also cheaper. The stainless steel definitely felt more professional though, and that milanese loop 👌. Both are fantastic.


I don't really have a formal conclusion. So far I'm happy with my purchase and am looking forward to more apps coming to Watch, as well as more functionality in existing watch apps as Apple opens up the platform a bit more this fall. I can't say you should go drop $350+ on an Apple Watch today, but if you are already a watch person, or a tech early adopter, or perhaps both... then go for it. And send me a little digital touch drawing if you do.

(Re)naming your app

One of the biggest goals of every iPhone or iPad app is to show up in App Store search results for anything relating to the title or general purpose of the app. Apple gives you 255 characters to title your app. 255 is kind of a lot. One practice to get better placement is to include subtitles, phrases, or keywords in the app title itself, which (it's generally believed) factors into the in the app's ranking in search results. This explains why several apps have titles such as below.

  • Day One (Journal / Notes / Diary)
  • Amazon App: shop, browse, scan, compare, and read reviews
  • TuneIn Radio - Stream free music, sports, talk & news stations, podcasts, songs & tracks
  • Later - Automatically Text, Tweet and Email Scheduling For A More Productive Life by Postpone and Delay
  • First Opinion - Free 24/7 Doctor Access

Apple also gives you 100 characters to provide "one or more keywords that describe your app. Keywords make App Store search results more accurate."

Now obviously this is important. So what's the point of this little post? Well, we recently changed the name of First Opinion from "First Opinion - Text a Doctor" to "First Opinion - Free 24/7 Doctor Access."

In doing so I noticed something interesting. When I search for "First Opini..." on the app store I now see both titles as well as the company name in the search results. I'll be honest, I have no idea how long the old title will continue to show, but it made me think... while it's important to have your app correctly titled and to optimize keywords for better search rankings, you should probably be careful how often you do it.

If you find yourself obsessing over keywords, titles, and App Store Optimization as a whole, just... stop worrying about it so much... before you start communicating your finickiness to potential users. Choose a solid title for your app, some relevant keywords, and move on to focusing on building an all around great app.

Here we are, San Francisco

Well... it's been a while. And a lot has happened the past two months. First off, Dru and I have now officially moved from Utah to California. Right around New Year's an opportunity arose for both Dru and me at a company called First Opinion. After much thought, we decided to postpone our plans to build in Lehi and join the team in San Francisco. Super hard decision given how much I've been rooting for the little guy in Utah tech the past five years. I really love the Utah tech community and our CocoaHeads meetups. Thinking about it though, while Dru and I recognize that there really isn't a better place to bootstrap a business, this was an opportunity we didn't want to let pass by.

We accepted positions with First Opinion a few weeks ago, and in about two weeks went from finalizing floor plans/prepping to build a 2800 sq. foot home to selling virtually everything on KSL and moving to San Francisco in search of a small 1 bedroom apartment with 12 boxes and a couple suitcases to our name. Never would've guessed this, but finding housing in San Francisco is hard. Who knew? Between hotels, Airbnb, and crashing at the office we've had a comfortable bed to sleep in, but hopefully we'll be able to wrap up the apartment search soon. I know Lola would be rather appreciative.

The great thing about moving is the chance to start fresh. The past month has included 6 full Jeeps worth of donation items to DI, the sale of 3 vehicles, and about 20 items sold on KSL. It's funny how attached you can get to your possessions. And not just because they are shiny and new -- I'm talking old Jeeps, game consoles, a dumb t-shirt you love, and a $20 set of golf clubs. Some of the best parts were seeing the new homes that our stuff was going to. Granted, we let a lot of our stuff go at a premium since we were trying to get out to San Francisco as fast as possible... but from the guy who bought Dru's red Jeep with plans to turn it into a southern Utah rock crawler in 30 days to the teenage girl who was so stoked to get an Xbox 360/Kinect and a bunch of games. Or the people that found the first starter snowboard, road bike, and golf clubs. Or the teenager and dad that bought my XS 400. All awesome homes for some of the toys that have made life more exciting in one way or another over the past few years.

Last Tuesday, after 3 days of packing with some HUGE help from family and friends we finally got on our way. And now, in pictures...

Passed out after staying up all night packing.

Passed out after staying up all night packing.

You've been good to us, yellow brick Lehi home. So long for now.

You've been good to us, yellow brick Lehi home. So long for now.

We packed up a 10' Budget rental truck... definitely did not need the whole thing. Or 80% of it.

We packed up a 10' Budget rental truck... definitely did not need the whole thing. Or 80% of it.

Lola enjoying her first few days in the city, constantly at Dru's hip.

Lola enjoying her first few days in the city, constantly at Dru's hip.

Holding up at a hotel near the office.

Holding up at a hotel near the office.

Lola attempting to get used to the whole city thing.

Lola attempting to get used to the whole city thing.

At a cafe in Hayes Valley.

At a cafe in Hayes Valley.

We've been doing a lot of apartment searching the past couple weeks. The dynamics of all the different neighborhoods is so interesting. You have some of the more traditional San Franciscan neighborhoods like the Castro, Nob Hill, and Hayes Valley, you have the Civic Center area with Twitter and a few high-rise residential buildings like NEMA and AVA popping up, and you have these newer districts like Mission Bay and Dogpatch that are a little further out (but not too far away). I'm glad we didn't just jump into a lease found on craigslist before checking out the areas, because in addition to working in the city, we're excited to live in and be a part of the community. We want to find an area that gives us easy access to do that. A couple leading favorites as we've been searching are Avalon Hayes Valley, 8 Octavia, and Linea, all of which are in the Upper Market to Hayes Valley neighborhoods.

To wrap it up, Dru, Lola, and I are here, safe and sound. We're getting up to speed at First Opinion and looking forward to contributing to its massive success ;). We worked together at Solutionreach for two years and really loved contributing towards a meaningful product, and being able to do that together. Being an earlier stage company and being direct to consumer rather than selling to doctor's offices, it's a unique opportunity to make a difference on a small, but passionate and dedicated team in an industry that we care about.

Swift Flickr Search

The Flickr API has been a go-to resource for iOS programming tutorials pretty much from the beginning. Well, here it is in Swift. A couple months ago I was asked to do a coding challenge for a job interview. The instructions didn't specify a programming language, only to write an iOS app that searches the Flickr API for images and displays them (those weren't the exact instructions, but more or less cover it). I did it in Swift, and although it took me longer than it should've, I learned a few things about programming in Swift.

Super basic layout... just a search box and a table for search results

Super basic layout... just a search box and a table for search results

Tapping a search result shows a larger version of the photo

Tapping a search result shows a larger version of the photo

Swift lessons learned:

  • Data provider pattern
  • Asynchronous callbacks
  • Using structs to declare static variables
  • Simple JSON parsing

Data Providers

Rather than putting the networking code in the view controller, it is separated into a data provider class. This class uses a callback to send the appropriate data back to the view controller for display. This pattern is used in Objective-C as well, and is a great way to keep code organized and avoid massive view controllers.

Asynchronous Callbacks

Due to the asynchronous nature of API calls, it's useful to return a callback from the data provider once the server response has been returned. This is done by defining a callback block in the FlickrProvider class.

typealias FlickrResponse = (NSArray?, NSError?) -> Void

The callback will be passed into the function to fetch photos.

class func fetchPhotosForSearchText(searchText: String, onCompletion: FlickrResponse) -> Void {
  // Hit API, parse JSON response, return an array of photos
  onCompletion(photosArray, nil)

Use in your view controller as follows.

FlickrProvider.fetchPhotosForSearchText(searchText, onCompletion: { (photos: NSArray?, error: NSError?) -> Void in
  if error == nil {
    // Fetched some photos!

Static Variables

Run into class variables not supported yet? Use a struct instead. Where you would have used a const or a #define before, you can declare struct with a static constant. This can also help you keep API credentials, notification names, NSUserDefaults keys, etc. organized.

struct Keys {
  static let flickrKey = "z0461br2b85aee5"

jSON Parsing

There are a few libraries that have been written to help you parse JSON in Swift, but in this case we'll just keep it simple and us NSJSONSerialization. This will convert JSON into a dictionary.

var jsonError: NSError?
var resultsDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: &jsonError) as? NSDictionary
if jsonError != nil {
  println("Error parsing JSON: \(jsonError!)")
println("results: \(resultsDictionary)")

finished Product

The end result is a simple app that allows you to search the Flickr API to your heart's content. View SwiftFlickrSearch on GitHub. The code doesn't have many comments because by nature Swift is fairly self-documenting. Welcoming any changes or improvements though.

TestFlight and the iOS Testing Workflow

Apple may be trying to teach us something about testing with the new TestFlight integration that quietly rolled out in September. For the greater part of iOS's life, testing has been a problem that was up to the developer to solve. Only recently, with Apple's acquisition of TestFlight and Twitter's acquisition of Crashlytics, has an more concrete workflow emerged.

Internal and external testers

You can now add up to 25 internal testers to your application. These testers can immediately receive a build once it's been uploaded to iTunes Connect. 25 is nothing though, you say. We could add 100 devices to the iOS Dev Center, you say. Enter external (beta) testers. You can now add up to ONE THOUSAND external testers. That's 1000 people to help you refine your app before you launch, or critique your design update before you tick off your existing user base.

There's a catch, though. All builds distributed to external testers must pass through an Apple review. While these reviews do not fall into the same queue as those submitted for App Store release, they can take time. For Scrimp, the first review took about 12 hours, with two reviews since then taking just a few minutes, each. What this means, though, is that you can't power through a three new features on Friday afternoon and expect to send it out to beta testers before peacing out for the weekend. And maybe that's a good thing.

Note: internal testers require iTunes Connect accounts, external testers just require an email and downloading the new TestFlight app.

The new Prelease dashboard tab in iTunes Connect

The new Prelease dashboard tab in iTunes Connect

What Are You Suggesting, Apple?

The new workflow seems to suggest a pattern of sending frequent (daily?) development builds to an internal team -- perhaps developers, designers, QA engineers, product managers, etc. -- and more polished testing builds (i.e. those passing Apple's prerelease review) to the external team -- company executives, beta testers, grandma, etc. It also could mean the elimination of the putting the latest (aka buggiest) builds directly onto others' phones at random points throughout the day. Rather, quickly submit from Xcode and hit a button in iTunes Connect to distribute. Let Xcode and iTunes Connect manage the distribution and versioning for you.

It's clear that Apple has heard our concerns and is opening the doors WIDE OPEN in terms of beta testing apps. No more setting up people in the iOS member center for the sole purpose of installing a test version of the app. No more worrying about managing and deleting devices (actually, you still need to worry about it, but chances are tons of your 100 allotted devices are being used exclusively for test devices). No more need for an enterprise account in a lot of cases too. Everything is simplified. What you now get is the ability to easily test your app with as many people as most could want. We went from 100 testers PER DEV ACCOUNT to 1000 testers PER APP. Now that is awesome.


That's up to you. If you've already got a system working with Crashlytics, HockeyApp, or even the old TestFlight web app you may not need to worry about it. On your next project though, I'd recommend trying the new Testflight integration. Apple puts extreme amounts of energy into product design, as we all know, and this is no exception. If nothing else, I find it interesting that Apple has structured the workflow this way. It's similar to environments I've been a part of and setup in the past, but now has the potential to establish itself as a community best practice.


Returned from @Flight late Wednesday night. It was Twitter's first mobile developers conference and I was lucky enough to get accepted to attend. No real expectations going in, other than to see what a Twitter hosted conference would be all about and meet some cool people.

In contrast to my experience at WWDC 2013, Flight was much smaller. 800 attendees, plus press, vs 6,000 or so at WWDC. It was held at the Bill Graham Civic Center, near Twitter HQ and right in front of SF City Hall. Apparently also the site of punk rock shows I probably would've attended had I grown up near San Francisco.


Flight actually kicked off with #womeninflight, a panel of inspiring women discussing their challenges, triumphs, and experiences working in tech. My favorite comment of the night was probably Patty McCord's response to a question of women's wages, how to ask for a raise, and "trusting karma". She said, simply, "If you want to get paid well, work with smart people on shit that matters, and deliver on time."

A few of my favorite takeaways.

Not the most surprising comment coming from a recruiter, but a great point about knowing the data and your market value nonetheless.

On the topic of companies underpaying women engineers sometimes the only solution is to leave.

I believe the correct stat was 41% (not 61%), awfully high in either case.

This is something I believe the entire industry can fix. Engineers, product people, business-y people. We can all relate to being the only whatever in the room in some way. It's not a fun feeling. Kindness and openness to the backgrounds of others goes a long way towards the productivity of a team and the success of a company.


Since I joined Twitter in 2011 -- yes, I am a late adopter, Twitter reminds me every time I looked at my profile --  no other app has changed the way I consume information about the world more. Twitter has had a profound effect on my ability to quickly access information I want, in real-time, and with direct access to people or channels I care about. With that in mind, I was excited to see what their mobile developers conference would be all about. The biggest news at Flight the launch of Fabric, a suped-up, easy to use wrapper around Crashlytics, MoPub, and a Twitter SDK. The biggest surprise was definitely Digits, a service that allows your to log into apps by ditching the traditional username/password combo and just using your phone number.

Pre-keynote. Twitter had people use Jawbone Drop to select the music playlist. They also grabbed tweets and put them up for all to see. We wondered if it was pulling all tweets with the #twitterflight hashtag, but ultimately decided they were curating the list.

Pre-keynote. Twitter had people use Jawbone Drop to select the music playlist. They also grabbed tweets and put them up for all to see. We wondered if it was pulling all tweets with the #twitterflight hashtag, but ultimately decided they were curating the list.

Dick Costolo kicked off the conference with a short intro. I think I was expecting more from him, but it was fine.

Dick Costolo kicked off the conference with a short intro. I think I was expecting more from him, but it was fine.

At the end of the keynote and Digits demo I got pretty excited about things. Even made it up onto the big screen (top right).

At the end of the keynote and Digits demo I got pretty excited about things. Even made it up onto the big screen (top right).

Without boring everyone with a play-by-play that you could get on any tech blog the last fews days, here were the most interesting parts to me:

  1. The idea of phone sign-in taking over email/password and even social sign-in. A great point that someone made was wait... isn't SMS dying? I'd say yes and no. Declining, absolutely, but I don't think it's going away. The part that does seem a little self-serving to me is the point that people in Brazil and India with no email can now use Digits to sign up for apps. The thing is, they probably won't be using an iPhone in that case, because Apple requires an email address in order to setup an Apple ID and download apps on the app store. So while it may help people without an email address more easily use apps on the web, I don't see how it specifically helps iOS and Android developers on that front.
  2. I will start using Digits in my apps ASAP. Yesterday I implemented it in an app I'm working on at i.TV. It was easy to implement, but it doesn't work very well yet. We tried signing in with 4 or 5 mobile numbers across both AT&T and Verizon and none worked. The only one that worked for me was using my Google Voice number. Fabric is brand new, and not yet open to the public, so I'm not too worried. By all accounts it looks like it'll be a big time-saver for both developers and end users.
  3. There was no mention of Windows Phone. Not once. I'm a big fan of WP and hope it establishes itself as the third player in mobile, and honestly I thought it had. But from the presentations, verbiage used e.g. "both" platforms, and talking with other attendees it was pretty clear to me that as far as anyone is concerned, only iOS and Android exist.
  4. Roughly 12% of engineering grads are women. Combine that with a 41% rate of women leaving engineering careers and that makes for a very small percentage of women at current tech companies. I'm a little biased, because my wife is an Interior Design/Architecture student turned product analyst, turned front-end developer, and most recently turned product manager. The perspective and feedback she brings to my former school projects, hackathon ideas, startup ventures, and current career path is truly invaluable to me. The diversity of her feedback is such a great thing, for me, and I know diversity of thinking can be a huge benefit to all teams and companies.
Inside the M&A Process - small panel discussing learnings from the acquisition of Crashlytics.

Inside the M&A Process - small panel discussing learnings from the acquisition of Crashlytics.

Hands down the most delicious sugar cookie of all time.

Hands down the most delicious sugar cookie of all time.

2014-10-22 15.35.34.jpg

Why transparency can hurt you

It's true. Transparency can cause your app major problems. You know what's the worst? Apps that freeze up, especially when scrolling. If you want a great user experience then you want great graphics performance. Enter transparency. There are some simple ways to optimize your layouts in order to improve graphics performance. Because what you don't want is a huge hierarchy of nested views with transparent backgrounds, layered on top over each other over and over again, all in a massive UICollectionView with tons of networking requests going on.

Individually, none of those things are bad. Transparency? Noice. Fresh data? Good. Beautiful UI? Yeah.

However, with iOS 7, iOS 8, and Yosemite's dive into the use of blurs and transparency in the quest for Clarity, Deference, and Depth come decisions and tradeoffs to be made in the implementation of our apps. 

The first thing is to understand a little about compositing. When it comes to motion pictures compositing involves combining visual elements from separate sources into a final image (or sequence of images). Think green screens.

In a mathematical sense one of the basic operations of compositing is referred to as alpha blending. Consider two images placed on top of each other, the foreground image with an alpha level of 0.5. Compositing occurs by mathematically combining information about both images and generating a third, composited image.

In iOS it's very common to set a view's alpha property in order to gain a level of transparency. In combination with the use of blurs Apple has created stunning interfaces in the operating system itself and in Apple apps like FaceTime and Camera. And lots of great apps have followed suit. Tons. But here's the problem, it's not as simple as going in and setting some clear backgrounds. To create a great user interface and a smooth, fluid experience the use of blurs and transparency must be extremely calculated. It's easy to add some transparency, try it out on the simulator or your newish iPhone, and call it good. But will it hold up across all devices, OS versions, and when used in a UITableView containing dozens, or hundreds, of items?

Fortunately there are a few simple things that can be done to optimize graphics performance. These are the low hanging fruit, but can potentially make a huge difference.

  1. First, be conscious of using [UIColor clearColor]. It's not free!
  2. Declare views as opaque whenever and wherever possible. Have a UILabel with a clear background and colored text? If whatever's behind the label is a solid color, then rather than setting the background of the label to clear, set it to the appropriate color and set opaque to YES. This will prevent the need to blend the layers every time the view is rendered.
  3. This is a silly one, but if you have a button without text, make sure you remove all text and set the font color to default. There is no reason to set the text to clear color. None at all.
  4. Be aware of animating alpha changes, for example when asynchronously fetching images while scrolling a UITableView. The fade-in might look nice, but it can be costly. Consider a good placeholder image instead. If you take a look around (e.g. Facebook, Twitter, among others) you might notice that the fade-in is a little less common than you thought. I'm a big fan of Twitter's unobtrusive gray placeholder that switches to the image as soon as it's been downloaded and readied for display.

Okay, so transparency is not inherently evil, but it can lead your app to dark dark places. I've recently been taking a hard look at graphics performances in apps I'm working on and have been pleasantly surprised at the performance gains (errr, absence of performance issues) using said techniques.

Other suggestions:

  • Use Instruments to measure your app's graphical performance
  • Turn on "Color Blended Layers" in the iOS Simulator - you might be surprised at the places where the GPU is wasting precious computational cycles


Also recommended:


New in UIKit in iOS 8

With all the excitement surrounding a new programing language and another major version bump in Xcode, I've found myself pleasantly surprised with some of the new API in UIKit in iOS 8. I wanted to mention a few new additions that may have managed to fly under the radar.


Goodbye UIAlertView and UIActionSheet. Hello UIActionController and block-based callbacks. Provide UIActionController with a styleType (might we see new styles in the future?), and the syntax is now identical between an actionsheet and an alertview. Big fan of the UIAlertView+Blocks and UIActionSheet+Blocks categories out there? Yes, they are great and I frequently pull them in, but I prefer to use Apple API when I can. Every added dependency is one more thing to maintain (yes, even CocoaPods) or inspect for warnings/bugs when a new version of iOS is introduced.

// Actionsheet-styled alert controller
let alertController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Woot woot!", preferredStyle: .ActionSheet)

// Add cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
    // Cancel

// Add confirm action
let confirmAction: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default) { action -> Void in
    // Confirm

// Present alert controller
self.presentViewController(alertController, animated: true, completion: nil)


Been using iOS 7 hacks to add blur effects to your app? UIVisualEffectsView will be a welcome sight. You can now created blur views and add them to your backgrounds, imageviews, or wherever else you please.

UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = someView.frame;
[self.view addSubview:visualEffectView];

Layout Margins

Confused by these -8s you see in your IB AutoLayout constraints? Me too. In iOS 8 Apple introduces layout margins on UIViews. Layout margins let you define the default whitespace surrounding your view (think of it as padding). These layout margins also cascade down to subviews that are pinned to the edge of their parent view.

From the UIView header file:

 -layoutMargins returns a set of insets from the edge of the view's bounds that denote a default spacing for laying out content.
 If preservesSuperviewLayoutMargins is YES, margins cascade down the view tree, adjusting for geometry offsets, so that setting the left value of layoutMargins on a superview will affect the left value of layoutMargins for subviews positioned close to the left edge of their superview's bounds
 If your view subclass uses layoutMargins in its layout or drawing, override -layoutMarginsDidChange in order to refresh your view if the margins change.

It appears by default Xcode 6 gives a view layout margins of {8,8,8,8}. With layout margins only supported in iOS 8+ this may or may not cause immediate issues if you build you project in Xcode 6 for iOS 7. A solution until you can support iOS 8+ is to select the constraint in IB and unselect "Relative to margin", then readjust the constant from -8 back to 0, if needed.

What Else?

  • UITraitCollection class can now be used to describe an object like UIView or UIViewController in terms of size, scale, and idiom traits
  • UISplitViewController now supported on iPhone and iPad -- oh hai, iPhone 6 Plus
  • New properties on UINavigationController including hidesBarsOnTap, hidesBarsOnSwipe, navigationBarHidden, and others

  • Take users directly to your app's settings in the iOS Settings app by passing UIApplicationOpenSettingsURLString to openUrl:

Learn More

Pragmas in Swift

New language, same old Xcode. The are no #pragmas in Swift, but Xcode 6 supports comment detection in Swift for:

// MARK:
// MARK: -
// TODO: 

Xcode 6 will list the above in the jump bar, just as it did in Xcode 5.

jump bar

See also Swift Extensions for a new pattern to group semantically related code.

iOS Design Patterns for Data Communication

iOS design patterns have evolved a lot over the years. In the three short years I've been involved in the mobile dev world, different trends have come and gone and best practices once used by many have been replaced by newer, more efficient ways of solving a problem. If you work in software development you know this... no big deal... that's just how it is. I agree. I wanted to lay out a few of the patterns for my own benefit, and include a look into one of my favorite new* patterns, functional reactive programming.

There are several different approaches you can take in communicating information between objects. Borrowed from NSHipster, this list highlights differences in coupling and intended audience under different approaches.

  • Intimate (One-to-One)
    • Weakly coupled
      • Target-Action
      • Delegate
      • Callbacks
    • Strongly coupled
      • Direct method invocation
  • Broadcast (One-to-Many)
    • Weakly coupled
      • Notifications
    • Strongly coupled
      • Key-value Observing

I don't intend for this post to only hit the listed patterns, and accordingly don't plan to just walk through each of these approaches. However, I will briefly touch on several and add some thoughts on a few other patterns along the way.


The target-action pattern is probably most familiar from using different UI controls hooked up to their respective IBActions. When a target receives an event, such as a button receiving a tap or a date picker landing on a new date, an action is triggered.

Delegation Pattern

The trusty delegation pattern. I'll never forget this question from a job interview with Apple while I was still a student at BYU. Why are delegates protocols? Delegates are extremely powerful because any object can say hey, I conform to this protocol, I'll be the delegate. Delegates can also conform to multiple protocols (friendly tip: this was the answer the interviewer was looking for). If delegates were subclasses instead of protocols then the view controller would be forced to choose one set of instructions to support. It's not uncommon for an object to conform to 3, 4, or 5. The delegating object keeps a reference to the delegate object and sends messages to it at the appropriate time. Some of the more common UIKit protocols include UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, and UIAlertViewDelegate.


Delegates are so old school, who uses them anymore? I mean, srsly:

Blocks are nice to use because they can keep the completion code/logic nestled up nice and close to the responsible party. In the words of Ryan Hodson:

Blocks are Objective-C’s anonymous functions. They let you pass arbitrary statements between objects as you would data, which is often more intuitive than referencing functions defined elsewhere.

For simple tasks it can end up feeling a lot cleaner than using delegate counterparts or creating and calling private methods. One downside: the syntax is impossible to remember. F***ing Block Syntax is your friend.


The notification pattern is so core to Cocoa that I think I've yet to see a code base that doesn't use NSNotificationCenter. As the list above suggests, notifications are a broadcast form of communication. A notification is sent out and any object listening for it at that time will receive it and can respond accordingly.

While powerful, I've seen notifications abused more than once or twice. What happens is the developer thinks to him or herself, "hmmm, I could do it this (other, more preferable) way, ORRR I could just setup a notification and be listening for it in this one (or five) other places and be done with it." The problem is that program execution suddenly goes from readable, flowing, easy-to-follow, to JMP over here and JMP over there. I'm not saying don't use NSNotificationCenter, but know when and when not to. If you are setting up notifications, listening for more notifications, and routing those to other view controllers all in your app delegate... you may be doing it wrong. Want a good use case for notifications? Currently I use NSNotificationCenter to notify listeners that network reachability has changed. It seems (to me) to be an appropriate use of a one-to-many broadcast.


Key-value observing is another of those patterns entrenched deep in the heart of Cocoa. The biggest problem in my book: it's extremely easy to write bugs into KVO code. The first time I did Startup Weekend I joined a team with an experienced, long-time Mac dev and KVO was almost the death of me that weekend. The idea is powerful: observe keypaths and get notified about state changes in any other object. At CocoaHeads last week we were on the topic of KVO in Swift and began hopeful speculation for next year's WWDC providing a new API built on top of KVO that makes KVO super nice in Swift.


Speaking of super nice KVO... enter ReactiveCocoa (RAC). What is RAC? The first question is what is functional reactive programming (FRP)? The best explanation of FRP I've hear thus far, from one of the creators of RAC:

Programs take input and produce output. The output is the result of doing something with the input. Input, transform, output, done.

The input is all the sources of action for your app. It’s taps. It’s keyboard events. It’s timer triggers, GPS events, and web service responses. These things are all inputs. They all feed into the app, and the app combines them all in some way to produce a result: the output.

The output is often a change in the app’s UI. A switch is toggled or a list gets a new item. Or it could be more than that. It could be a new file on the device’s disk, or it could be an API request. These things are the outputs of the app.

But unlike the classic input/output design, this input and output happens more than once. It’s not just a single input → work → output—the cycle continues while the app is open. The app is always consuming inputs and producing outputs based on them.

To put it another way, the output at any one time is the result of combining all inputs. The output is a function of all inputs up to that time.

When I mentioned FRP in the first paragraph I put an asterisk next to new. That's because FRP is not new. The principles of reactive programming have existed since at least the 90s, and KVO in many ways accomplishes similar goals in eliminating state and observing objects for changes. ReactiveCocoa includes a powerful API that achieves many of the goals in reacting to property changes but without the pain points of KVO.

The de facto RAC example seems to be observing a UITextField (or perhaps many) for text changes and updating say, a login button, to an enabled/disabled state based on the contents of those text fields. The same approach without RAC requires, no joke, checking the contents of fields in viewDidLoad as well as the use of at least two different UITextField delegate methods (namely, textField:shouldChangeCharactersInRange: and textFieldShouldClear:).

One of my favorite other use cases so far is reloading tables in UITabBarController's root view controllers. If you've used UITabBarController before, you may have been surprised, confused, frustrated (or just not cared) to find out that the root view controllers in each tab are only loaded once (or you may have been smarter than me and realized from the beginning that it actually makes more sense that way). You don't get a full refresh of the view lifecycle, so you can't rely on viewDidLoad being called... ever again, really, unless the app is FCed. But at the same time putting a fetch operation in viewWillAppear just feels like a bad idea, right? Do you really want to fetch all that data again if the user leaves the screen and comes back 2 seconds later? Of course not. Okay what next... setup an NSTimer or some sort of timestamp and only fetch it if it's been at least 60 seconds? All that hairiness for something as simple as fetching some data? And what if on top of that you fetch that same data on a different screen or on appDidResume, how do you notify that view controller?

ReactiveCocoa has made my life so much easier when it comes to this. I setup an observer for the data cache property that feeds the table on that screen, then simply fetch ze datas on viewDidLoad. Once the data returns and updates the cache, the observer reacts to that change and reloads the tableview. I've also added a call to fetch that same data on applicationDidBecomeActive so it's periodically updated. It works great, is super clean, and avoids some ugliness in subclassing UITabBarController and using timers.

Summing it up

Functional reactive programming and ReactiveCocoa is the latest of many new patterns to influence iOS development and Objective-C. It borrows good ideas from other paradigms and brings new solutions for solving familiar problems. Each of the patterns mentioned above have their own characteristics and intricacies. I'm not advocating for a complete functional revolution, but learning functional programming does make you a better programmer. For those who just haven't bought into the FRP hype, I leave you with this story from Rob Napier's post, Swift is Not Functional:

I used to ride a motorcycle. When you’re riding a motorcycle, you have to be much more aware than when you drive a car. If you’re not, you’re going to get hurt. But the thing I noticed was that riding a motorcycle made me a better car driver, too. Functional programming is like that. Riding a motorcycle isn’t always the best way to get somewhere, but we’d have better drivers if everyone learned on motorcycles. We’d have better programmers if colleges taught Haskell first and Java later.
And a picture of my motorcycle for good measure.

And a picture of my motorcycle for good measure.

Writing more performant mobile apps

Although I earned a technical degree in college I would still say that I am in large part a self-taught programmer. Yay for DIY. I started programming in a 100 level CS class at BYU years ago, but I wasn't really programming back then... I was blindly following TA help sessions and being handheld through everything. A few semesters and a couple CS/EE classes later I still wasn't much of programmer. It wasn't until Dr. Liddle's Android class in Winter 2011 that things finally clicked for the first time.

For the semester project I was creating a simple Cow Tipping game where you tap cows until they tip over. I remember trying to figure out how I would track how many taps are left before the cow tips over. I discussed the problem with a friend and he gave me a couple suggestions. I eventually arrived at using a map with keys being cow ImageViews and values as the number of taps left until it falls over. It was the first practical application for data structures that I'd found.

From that point on I did a couple more side Android projects and landed my first Android contract job and, a few months later, an Android internship at rain. Then in summer 2012 I began interning at Solutionreach and was asked to learn iOS. I was gaining experience and a portfolio, yes, but thinking back I made the jump from DIY coder to writing enterprise apps pretty quickly, to be honest. I've spent a lot of the last two years trying to supplement my ability to write apps with software design principles and performance optimizations. Having recently started with iTV and getting exposed to a different, mature iOS codebase it's been a great opportunity to challenge existing lines of thinking and learn about better, more performant approaches and patterns. It's one of my favorite things about the gig.

Okay so finally to the code part. In Objective-C, NSDictionaries and NSArrays can do anything, right? Well, yeah, they can, probably, but what about NSSets? NSSets offer better - O(1) - performance for extremely routine tasks such as accessing items in a collection or checking if a collection contains an item. NSArrays on the other hand must iterate through their entire contents until the particular object is found - O(n). So here's my suggestion: don't forget about the awesomeness of NSSet.

Okay, so some examples... First up I'm going to create a collection of twitter handles for my favorite followers. Here's three potential approaches.

1. NSFastEnumeration

NSMutableArray *mutableFavs = [NSMutableArray array]; 
for (TwitterUser *user in user.followers) { 
  [mutableFavs addObject:user.handle]; 
NSArray *favorites = [mutableFavs copy];

2. EnumerateObjectsUsingBlock

NSMutableArray *mutableFavs = [NSMutableArray array];
[user.followers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    [mutableFavs addObject:[obj handle]];
NSArray *favorites = [mutableFavs copy];

3. NSSet's valueForKey

NSSet *favorites = [user.followers valueForKey:@"handle"];

This is a fairly simple example, with the big question being okay, what now. My ultimate goal is to create a collection of favorite tweets by looking through a timeline full of tweets, comparing the author's Twitter handle, and pulling out the matches. Since I don't care particularly care about the order of the collection, valueForKey and using a set is an excellent option. Or, I may care about order eventually, but for now I don't, and later on I was planning on sorting the results alphabetically anyway, which means I have less reason to preserve order by using NSArrays at this point.

So how can it be done? Here's two approaches:

1. NSFastEnumeration x 2, aka the double for loop - O(n^2)

NSMutableArray *mutableFavs = [NSMutableArray array];
for (TwitterUser *twitterUser in user.followers) {
    for (Tweet *tweet in timelineTweets)  {
        if ([twitterUser.handle isEqualToString:tweet.authorHandle]) {
            [mutableFavs addObject:tweet];
NSArray *favoriteTweets = [mutableFavs copy];

2. NSSet's valueForKey + NSPredicate - O(n)

NSSet *favorites = [self.followers valueForKey:@"handle"];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    Tweet* tweet = evaluatedObject;
    return [favorites containsObject:tweet.authorHandle];
NSArray* favoriteTweets = [timelineTweets filteredArrayUsingPredicate:predicate];

I know what you're thinking....

If you didn't catch it, we used an NSSet to drop the complexity down from a BAD BAD BAD O(n^2), to an ALRIGHT, I CAN DEAL WITH THAT O(n) by using NSSet's constant lookup time. Think about it this way, if this user had 500 followers and we were looking at 200 tweets, with the first approach it could take 100,000 loops until we successfully had our collection of favorite tweets. With the second approach we are looking at orders of magnitude faster, and arguably cleaner code too. (For more on cleaning up these types of operations further, check out ConciseKit... or maybe just forget obj-c and jump into Swift. :)

Moral of the story is to continue to look for ways to improve your code. "Yeah, it works" may be a huge accomplishment in the beginning, but performance is key as you scale. Although it probably won't "make" your app, it can definitely "break" your app if done wrong. It's true that it may not matter either way when dealing with small data sets, but avoid the urge to think meh, it probably won't matter. In your testing you may have 4 or 5 objects in your collection, but in the real world what happens when a user ends up with 700? Combine that with a poorly designed filtering method and you could be in trouble.

David and Goliath

I've recently been reading Malcolm Gladwell's latest book, David and Goliath. Gladwell really took my understanding of the David and Goliath story and turned it on it's head. Take this quote from historian Robert Dohrenwend, cited in the book, which reads:

Goliath had as much chance against David as any Bronze Age warrior with a sword would have had against an [oppo­nent] armed with a .45 automatic pistol.

Didn't expect that, did you? You'll need a little context. In the book, Gladwell explains that ancient warfare in many ways was a game of rock, paper, scissors, the way the infantry, cavalry, and artillery balanced one another. With long spikes and armor, infantry could stand up to calvary. Cavalry, moving quickly on horseback, moved too fast for projectile warriors, and lastly projectile warriors were deadly against sitting duck infantrymen. David was a slinger, a projectile warrior, and Goliath was heavy infantry. According to custom, the best warrior from each army would fight in hand-to-hand combat, with the losing side surrendering to the victor. David, however, didn’t play by the rules. Another excerpt:

Goliath is heavy infantry. He thinks that he is going to be engaged in a duel with another heavy-infantryman. David, however, has no intention of honoring the ritu­als of single combat. When he tells Saul that he has killed bears and lions as a shepherd, he does so not just as tes­timony to his courage but to make another point as well: that he intends to fight Goliath the same way he has learned to fight wild animals—as a projectile warrior.

He runs toward Goliath, because without armor he has speed and maneuverability. He puts a rock into his sling, and whips it around and around, faster and faster at six or seven revolutions per second, aiming his projectile at Goliath’s forehead—the giant’s only point of vulnerability. Eitan Hirsch, a ballistics expert with the Israeli Defense Forces, recently did a series of calculations showing that a typical-size stone hurled by an expert slinger at a distance of thirty-five meters would have hit Goliath’s head with a velocity of thirty-four meters per second—more than enough to penetrate his skull and render him unconscious or dead. In terms of stopping power, that is equivalent to a fair-size modern handgun. “We find,” Hirsch writes, “that David could have slung and hit Goliath in little more than one second—a time so brief that Goliath would not have been able to protect himself and during which he would be stationary for all practical purposes.

Underdogs like David often learn to think differently, to change the rules of the game. When facing incredible odds what are your options? Certainly a hand-to-hand fight with a powerhouse will lead to failure. But this is where underdogs have a distinct advantage. The threat of sure failure leads to creativity, determination, and incredible courage. David was able to conquer Goliath by changing the rules of the game, and by the same vein many heavy underdogs can succeed in business by using their position as a strength.

Larger excerpt available at 'David and Goliath': Understanding the dynamics in a power struggle.
Book available on Amazon.

Another point Gladwell makes is about what most of us know as the big fish in a small pond effect. His ultimate point is that he is against someone attending a prestigious university just for the name. To choose the "elite" university more often than not means choosing to be a little fish in a big pond, since only a few will shine among the best. Gladwell believes firmly that people are generally better of being a part of a lesser known institution or company where they have a great chance of standing out.

I think this point is especially true at BYU. BYU isn’t ivy league, but it does brings out some of the best students from around the United States and from around the world. Many students, accustomed to straight A’s and the frequent praises of their professors and parents, struggle when facing B and C grades for the first time in their life. I'll be honest, I was no exception. As a computer engineering student who was top 25 in my high school class, I struggled heavily when the concepts did not come easy to me and I faced low B grades. I felt dumb and it made want to quit. After trying my hand at a mobile development class in the Information Systems department I did well and regained some confidence. Rather than trying to be the small fish in the engineering pond I decided to switch majors to Information Systems, where the business topics came easy and the technical topics were not so rigorous (or low-level). The largest personal benefit from this move was the feeling of confidence and empowerment. I no longer felt dumb among my peers, and the confidence led to great success in the classroom and earned me qualified positions at local software development companies. Now, officially one day from completing my last class at BYU, I am very grateful that I decided to make the move to Information Systems.

Gladwell explains this phenomenon as relative deprivation. The worst STEM students at Harvard are likely to be the top students in other programs, but Harvard students compare themselves to their peers and as a result have similar dropout rates as all programs across the county. In Gladwell’s opinion, it is better to attend a non-elite institution and leave feeling successful, then to have been a small fish in a big pond. Similarly, companies should not hire based on a name alone. Top performers - at any size institution or company - prove to be better employees than average performers at top ranked institutions and companies.

Based on what I've read of David and Goliath so far, I'd recommend grabbing up a copy. Gladwell taught me a couple history lessons and opened my mind on how you can turn disadvantages into strengths.

Objective-C has fallen

It's been quite a ride since the plethora of WWDC announcements yesterday. In addition to awesome new end user features in OS X and iOS, cool new frameworks like HealthKit and HomeKit, and some expected upgrades and enhancements to Xcode, Apple really threw everyone for a loop by announcing a new programming language, Swift. When Craig Federighi dropped the news it felt like getting hit by a brick wall. You could tell something big was happening when he started talking about how great Objective-C would be "without the baggage of C,"  but you had no idea what. Then it hit. Swift.

What's crazy to me is the fact that Objective-C developers were the hottest engineers on the market just 2 days ago, and now the technology has effectively had its fate sealed. Thought you were golden as an iOS dev, bought completely into Objective-C? Nope.

I'm not saying iOS developers are all of a sudden SOL and should start worrying for their jobs, but man it hits close to home that an industry I'm so entrenched in is completely upended in a day. Sean Hess put it well in our CocoaHeads google group that "framework and platform knowledge has always mattered more than language syntax. Syntax is really easy to pick up. So all the knowledge that matters you'll carry with you. It won't take much time to get up to speed for any good Obj-C dev." Indeed, there's much to look forward to as an iOS developer right now, not the least of which being the ability to build better apps in less time with Swift.

Windows going free for phones and small tablets

Microsoft announced today that they are cutting prices of Windows for manufacturers to spur adoption. And by cutting prices I mean to $0 for Windows Phone and tablets under 9". Is this big news? I don't know. In the world of Microsoft it's definitely big news, because Microsoft's original business model was almost exclusively built around Windows OS licensing agreements. Microsoft aficionados may be rejoicing, but in the greater world of mobile my read on the situation isn't so optimistic.

I feel it's somewhat contradictory to Microsoft's recent actions -- increasing vertical integration with the Nokia purchase and the forward play into manufacturing their own Surface tablets. It felt like the strategy was shifting towards emulating Apple's model of controlling the end-to-end experience by owning the software and hardware, differentiated by a heavy dose of business/productivity functionality. Now they want to compete with Android by becoming an open platform? I'm confused.

Overall I think it's probably good for the industry, so that companies like Amazon, Samsung, Pebble, Fitbit, or other OEMs have more options than just homegrown or Android if they want to start a line of phones, tablets, or watches... but as an outsider the read between the lines here is that MSFT can't make the money they want by licensing Windows Phone/Windows RT (under 9"), so they are going to try and go the open route and see if they can build the ecosystem and make money off the app store like Android. The problem with that approach is that they are 3 years too late to that game too.

Hackdance & Second Government

Dru and I participated in Hackdance this past weekend. It was a 48 hour hackathon at the Deer Valley Lodges in Park City as a part of Collective's Disruptfilm event at Sundance Film Festival. From the site:

Hackdance: the first celebrity-driven social impact hackathon kicks off on January 16th, & you're invited to take part in this historical event! Your mission: partner your tech skills w a celebrity passionate about changing the world to design apps/hacks that use technology to create social impact.

We took school and work off on Thursday and Friday, not quite sure what we'd gotten ourselves into. Dru brought her product management and design skills to the game and I came in with my iOS and Android background. The event started with the celebrities sharing their ideas for social impact. There were a lot of good ideas, including the use of Plexi APIs for reporting and preventing cyber-bullying, an ambitious but thoughtful idea for virtual second government, and a movement for improving the Plant-a-Fish donation collection, among other ideas. Dru and I liked a few of the projects, and ended up joining our first choice with Alex Ebert for the idea of Second Government.

Dru and I teamed up with two "serial hackathoners" who were invited out from Silicon Valley. I think they've done something like 15+ hackathons in the past year, placing top 3 in over half of them. It was pretty cool getting teamed up together...until I realized how serious about hacking they were. With no hackathons under my belt, my most similar experiences were the BYU Mobile App Competition and Startup Weekend. Joining with a team of hackers was quite an adjustment.

The main difference was that both the mobile app competition and SW had an end goal to build a complete product or business, not just put something together for demo purposes. We had significantly different theories on how to tackle the weekend, but overall ended up with a pretty good balance. We ended up creating a semi-functional Reddit- and Stack Overflow-inspired website and iOS app, featuring proposals for governmental change and a system of comments and upvotes.

The goal of the platform is to provide an open system for proposing governmental change without all the bureaucracy and pessimism. Ideas are then voted, vetted, and refined, with the most popular suggestions rising to the top. While most people don't bother voicing their opinions on government because of little hope it will ever be heard, SecondGov provides the platform to test out ideas in a virtual world without the worry of what can or can't be accomplished. Ultimately, proven, popular ideas from SecondGov can be taken (with their tens or hundreds of thousands of upvotes) to the real government to make real change happen.

The team

The team

Alex, who won a golden globe for best original score just last week, was awesome to work with. He was definitely the most hands-on and supportive of the celebrities from my perspective. He spent a lot of time working with us on the direction of the app, design, and prepping for our pitch. Plus, he's an artist, a writer, and a performer... he knows how to make a point with some conviction.

Dru making an awesome face

Dru making an awesome face

Our pitch to the judges went well. We definitely bit off more than we could chew by working on a web app, iOS app, exploring a virtual reality platform, and trying out a pre-release iOS motion-tracking SDK by Plantronics in the two days. Our demo included a piece from all four, but my personal favorite was the Plantronics concept headset. We used it in conjunction with the iOS app to view proposals hands-free and upvote or downvote them with a nod or shake of the head. It wasn't necessarily a cornerstone piece to the premise of SecondGov, but it was fun to work with one of the hackathon sponsors and brought a little wow factor into the pitch. I'll post a video later if I get my hands on it.

Pitching to the judges

Pitching to the judges

The result was awesome. We won first place for social innovation, including a 5k cash prize and a 10k investment from the Sorenson Global Impact Investing Center.

Alex sharing the vision

Alex sharing the vision

Awesome projects from every single team. Other final products included a Google Chrome extension for reporting cyber-bullying, YoungStarter, improvements to the Plant-a-Fish donation system, Rah Rah's tech truck, a SHFT mobile app, and a Lead and Pledge movement to end domestic violence.

Related links