(Re)naming your app

One of the biggest goals of every iOS product team is to own the search App Store search results for anything relating to your app. Apple gives you 255 characters to title your app. 255 is kind of a lot. One practice to achieve better search rankings is to include subtitles, phrases, or keywords in the app title itself, which is generally believe to factor 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 these things are important. So what's the point of this little post? We recently changed the name of First Opinion.

  • Prior name: First Opinion - Text a Doctor
  • Current name: 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 ASO (App Store Optimization, as I've noticed it's beginning to be referred to as), you may want to tone it down a notch or two 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 UX and 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.

Now WHAT

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.

Flight

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.

#womenInFLIGHT

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.

#TWITTERFLIGHT

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.

UIAlertController

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
}
alertController.addAction(cancelAction)

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

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

UIVisualEffectsView

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: -
// FIXME
// 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.

Target-Action

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.

Blocks

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.

Notifications

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.

KVO

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.

ReactiveCocoa

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

Finding the Right iOS Dev

Over the past few weeks I've had a few friends and colleagues ask me about the iOS developer interview process -- both on the interviewer and the interviewee sides. Having sat on both sides of the table, this post is a collection of thoughts on how to find the right developer for the job. I should note that these opinions are entirely my own and are completely subjective.

First, I think there a few things to consider before diving straight into interview Q&As -- there's a lot more to it than just rattling off a list of Objective-C programming questions found from a Google search. Yes, that can help you find smart engineers, but it might not get you the whole picture. Here are a few main points to consider when looking at a candidate:

  • Published work
  • Knowledge of Objective-C and Cocoa Touch
  • The right ratio of hackerness vs convention-use
  • Online reputation*
  • Overall tech savviness

Published work

You'll want ask for examples of published work. While at Cocoa Camp last summer I noticed several things that Apple looks for in a perspective engineer. Here are two from my notes:

  1. Someone who is driven to learn - and ship.
  2. Someone who has an obsession with creating - and delivering.

There are lots of extremely talented computer scientists and web developers in the world, but it takes a unique blend of hard-skills and finishing ability to make a good iOS developer. While pet projects are nice, that alone shouldn't impress you. Half-baked ideas are just that, half-baked, and not something you want to publish as your company's next app. Looking at the candidate's apps on the app store will tell you more about their experience level than their resume ever could. If their work was written as a team effort, ask them which pieces they developed or what percentage contribution they made to the overall app.

Knowledge of Objective-C and Cocoa Touch

You'll want to be sure the person has a solid understanding of programming principles, design patterns, Objective-C, and the Cocoa Touch frameworks. The depth of knowledge and understanding required will vary depending on the experience level you're looking for and how much you want to pay, but here are my suggestions for a good junior-level iOS developer.

  • MVC pattern - Ask the candidate to include an example or explanation of how they've used it in an app. 
  • Protocols and delegates - Ask the candidate "why are delegates protocols?" (and not normal classes). What I would look for is that the candidate can explain that protocols are more flexible than a normal class, because they can be implemented by any class, allowing for greater reuse. If they can explain this to you, in addition to the general idea behind the delegation pattern, that's a good sign.
  • Strong vs weak pointers - What's the difference? When would you use one vs the other?
  • Check out Ray Wenderlich's post on iOS interview questions.
  • Any questions specific to your project, code base, or existing development team that can help determine if this person is the right fit.

Hackerness vs Convention-use

I'm not sure what else to call this one. Objective-C is a very convention heavy programming language. If the candidate is a recent transplant from another development stack or a hobbyist iOS developer turned professional, they may not have fully embraced the Objective-C way (no ill-will towards these groups, I came in with almost exclusive Java/Android experience when I started with Objective-C). There are always opinions when it comes to code formatting, design patterns, and naming conventions, but with iOS in many cases there is a recommended best practice that should be followed.

You might be thinking "so what if they do it their own way, so long as it works" (especially if you're just looking for a temporary contractor). Wrong! No matter how small you think your project will be, there are going to be changes to be made down the road. And who's going to read that code? It might be the original developer, or it might not. Use of conventions allows for easier readability and better maintainability, and will lower your switching costs if the original developer doesn't work out or decides to suddenly leave for another gig.

If you yourself have a good knowledge of iOS development, brush up on your Cocoa Coding Guidelines and ask for a code sample. Look at things like use of class prefixes, method names, constants, and categories. Ask the candidate about software design. Do they design their code for personal use, quick-and-dirty, never to be touched again, or do they design their code with reusability and efficiency in mind. One of the best signs of a modern programmer is that they design their code -- internal and external -- as if it were an externalizable service - taking a page of Amazon's book. A code sample can also be useful to see their design style and identify particular areas of focus (e.g. networking, UI, data persistence, animations, etc).

Online Reputation*

I put an asterisk next to this one because I think this might be the most debatable point. For me personally though, I give bonus points for active use of GitHub, StackOverflow, App.net, and Twitter (unless its to manage a Biebs fan handle). Open-source software is huge both in web and mobile. If the candidate is familiar with pulling code off GitHub (properly attributed of course), it could definitely come in handy in the future. Better still if the candidate has contributed to open-source projects or created one of their own.

Completely on the other side of the coin, I know several excellent developers who don't care much for social media or personal branding. It's no knock on them, it's just not in their interests. That's fine too, just be aware of it and make sure the candidate is a good cultural fit for your team. e.g. if you're launching a social network for chihuahuas and the candidate isn't active on Facebook, Twitter, or Instagram, it's probably not the best fit even if they are extremely smart.

Overall Tech Savviness

Lastly, and you've probably done this by now, Google search the person's name and see what turns up. In emails or an interview ask them what they like about programming, iOS, and technology. You know this, but design is HUGE in mobile app development. It should be a big deal to the interviewee. UI/UX will make or break your business, so make sure you value this appropriately. I love that in a mobile developer job posting for Alpine Replay, their "next steps" are simply:

  • "Send us an email. Please include some of your sample work, a collection of your favorite designs (not yours) and whatever else you feel may be applicable."

A savvy design enthusiast who's up on the latest trends and upcoming iOS 7.1 or iOS 8 features could help take your app's user experience to the next level.

Disclaimer

All the suggestions in this post are personal opinion. Any and all of it should be adjusted to fit your needs and your team's culture.

Five Word Tech Horrors

Got a kick out of this hashtag over the last 24 hours.

No, Apple didn't copy Android

I wanted to get this thought out about 2 months ago, but here it is now. Better late than never.

There's been a lot of talk around the interwebz about Apple knocking off Microsoft, Google, or __________ (fill in the blank) with the latest refresh of iOS. While it's easy to complain about how this or that already existed elsewhere, rather than pointing fingers and chalking everything up to someone copying someone else, to me the much more logical explanation is that Apple has simply updated its design to be more modern (as have others). To say that flat buttons belong to Android is somewhat naive, because certainly Windows Phone has been leading the way in flat UI when it comes to smartphone OSes over the last few years. Further, if you read into iOS 7 and get your hands on it you'll see that Apple did not simply flatten everything out.

In the developer keynote, Craig Federighi stated that the goals of iOS 7 included three overarching themes.

  1. Deference - The UI defers to the content. It's helpful and intuitive, but unassuming and out of the way. This is a big change from the skeuomorphic ways of the past.
  2. Clarity - Clean, precise UI as well as a major increase in accessibility support.
  3. Depth - This is where Apple has struck gold IMO. They were able to modernize the interface, yet kept a distinctly unique experience by focusing on depth and contextual awareness using blurs and realistic, physics-based animations.
The focus on these themes and the amount of detail included at each and every level of iOS 7 make it apparent how truly unique Apple's approach to a 2013 mobile OS is. And the best part, Apple didn't go sell their soul to the flat UI gods - it's still very much iOS. More at Designing for iOS 7.

No, Apple did not copy Android. Apple took their time in moving on from the iOS design of the old, but they did it in their own way. And if you look at it, all major platforms and companies have moved to simpler, cleaner UI over the past 2-3 years. It's not one company stealing another's idea, it's the major players realizing the direction of design trends and incorporating them how they see fit.

It took Apple two years longer than it should have in my opinion, but as usual they came through with a excellent product in iOS 7 and I highly recommend updating if you haven't already.

Why singletons are bad

Disclaimer: This isn't a total knock on singletons. Alternate title: "Why singletons can be bad".

Software Design

Yesterday I had a conversation about software design with an experienced colleague and found myself reaching when discussing design patterns. Specifically, we got onto the topic of the singleton pattern. 

Knowing from recent experience at Cocoa Camp that singletons are not the end all be all solution for object oriented programming (yes, I might have thought that at one point), I was careful not to sound overly enthusiastic that I used the singleton pattern. I  first learned about the singleton pattern an Android dev class that I took in Winter 2011 (at BYU). It sounded pretty cool then, and it was even a semi-significant part of the midterm. I later began learning Objective-C, and after using the pattern in a few iOS apps over the past year - including collaborative projects with other developers who hadn't ever mentioned any negatives in the singleton pattern - I had gradually assumed that they were a pretty solid way to go. Last month at Cocoa Camp the pattern came up and although we didn't get into any detailed discussions on it, I got the impression that singletons weren't as favorable as I had thought... 

Back to our conversation, I mentioned that I knew singletons had positives and negatives and explained a little more about why I'd used them in the past. He pried pried a little deeper, asking two questions that I want to expand on. "What are some of the downsides to the singleton pattern?" "What alternative design patterns would you suggest?" I mentioned a few things, including keeping the object in memory for the entire life of the application, rather than when specifically needed, and that an alternative method could be to pass the data between view controllers rather than via the shared singleton instance. Then we moved on.  Conversation over.

Why singletons are bad

Later (okay, ten minutes after the conversation ended), I found Steve Yegge's blog post, Singleton Considered Stupid:

Begin Quote 

Here's what most people got out of Design Patterns: "blah blah blah blah SINGLETON blah blah blah blah". I kid you not. I've seen this so many times that it's become a full-fledged pattern in its own right; patterns need a name, so let's call it the Simpleton Pattern.

The Simpleton Pattern unfolds like this:

Me: So! Have you ever heard of a book called Design Patterns?

Them: Oh, yeah, um, we had to, uh, study that back in my software engineering class. I use them all the time.

Me: Can you name any of the patterns they covered?

Them: I loved the Singleton pattern!

Me: OK. Were there any others?

Them: Uh, I think there was one called the Visitater.

Me: Oooh, that's right! The one that visits potatoes. I use it all the time. Next!!!

I actually use this as a weeder question now. If they claim expertise at Design Patterns, and they can ONLY name the Singleton pattern, then they will ONLY work at some other company.

End Quote

I really hope I didn't fall into this category in the mind of my colleague, but wow was I unprepared for those two questions. Especially the second question. There are few design patterns with a name as catchy as the singleton pattern. There certainly are other ways and methodologies to accomplish a programming objective, but what's the catchy name for instance classes, interfaces, and passing data between controllers?

I've done some more reading and in hopes of getting it right the next time, here are some of my thoughts.

What do you think are some of the downsides to the singleton pattern?

There are actually a ton. The reasoning is pretty straightforward and I don't know why I didn't think of these earlier.

  • A shared singleton class requires that memory be in use throughout the entire application, even when the object isn't needed.
  • Singletons hide dependencies!
  • As a result of these hidden dependencies you can lose track of the coupling. Instead of meticulously passing each object you need (and only the objects you need) into a function, you instead call [AppUser sharedAppUser] to access your shared instance. While it feels cleaner since it can mean less lines of code to get the access you need, you can end up with very tightly coupled code.
  • You can't (really) subclass a singleton
  • Singletons are hard to test! (1) With hidden coupling it's difficult to create mock objects and (2) singletons generally exist for the lifetime of the app which presents a problem for unit testing, as each unit test should run independently of other unit tests.
  • Just think of it as the "global-ton" pattern. The name isn't that far off. Does it still sound as sexy? 

There are some upsides too, but I'll save that for another time. 

What alternative design patterns would you suggest?

  • Object oriented programming. This isn't just a snarky answer. Use instance classes that are instantiated within the scope that they are needed and pass those objects between methods or controllers as necessary. 
  • Create the instance of your object only within the scope that is needed (be careful not to abuse the AppDelegate).
  • Use dependency injection to pass a single instance of the object to the components that need it (like your unit tests).

Takeaway

      Be smarter. Understand what is actually happening when you use the singleton pattern. As tempting as slapping in SynthesizeSingleton.h into an iOS project is (see http://www.cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html), it is NOT the solution to all your problems. You may not need it at all. Tightly coupled code can be a major problem with singletons, and chances are you probably aren't unit testing (or not properly anything) whichever objects you've transformed into singletons ...which you should fix. Most of all, if you enjoy software design but can only list of the singleton pattern when trying to have an intelligent conversation about design patterns, you have homework to do.

      Sources / Related Material