TODD KERPELMAN: Hello, and welcome to "Route 85,"
our new show for you iOS developers.
Thanks for coming.
Glad you could join us.
So for this episode, I wanted to present you
with a quick tip that was shared by Tom Van Lenten on the Google
Maps team.
Now I would love to call this our tip of the week segment,
but I don't think I can commit to making these videos
that often, so it's "Quick Tip."
And thanks to Tom for sending it in.
So for this example, let's say that I'm building a card game
app that uses standard playing cards.
And within my PlayingCard.h file I
decide to create an enum for the suit.
So here we go.
Looks pretty normal so far, right?
And down below, we'll store this as a property.
Now let's say I wanted to write a method
to do something based on this suit.
Maybe different suits give me different point multipliers
in our card game when we get to the scoring section.
And so we'll need to write a method
to convert these suits into point multipliers.
Well, this seems like a pretty obvious case
for a switch statement.
So we'll start to type it in here.
We'll add in the case for spades,
for hearts, diamonds, and clubs.
And then we get to this default statement at the end.
And huh, well, what should we do here?
I mean, gosh, I can't think of a time we'd ever
get to this, right?
Like, we've got all of our suits covered above,
so it seems like if we get to this point,
something bad is going on.
But still, we should code defensively, right?
So maybe we'll throw an exception here.
I'm going to add the comment "this should never happen."
and then right below, we'll throw an exception,
because clearly our game is in a bad state.
Well, anybody who's worked in software
knows that simply adding the comment "this should never
happen" to your code magically ensures
that at some point in the future that exact thing will happen.
So let's go back to our card game.
And our lead designer suddenly decides
we need to have jokers in our game.
Well, jokers are going to need their own suit.
And so maybe the engineer assigned to this task,
well, they see that we need to add a joker to our enum.
But our code base has grown and maybe our engineer
doesn't notice that the getPointMultiplier
method, among all of our other code, also needs that enum,
so it doesn't get updated.
Well, what happens?
That's right.
We hit the default statement.
Our code raises an exception.
And the whole thing crashes.
Now, if you're lucky, this will get
caught in testing while in development.
If you're slightly less lucky, this'll
get caught by Apple during the approval process.
And if you're not lucky at all, it
won't get noticed until it starts
crashing on all of your players, probably
at the time the press decides to start reviewing your game.
Huh.
That's unfortunate.
So what can you do here?
Well, the answer might be to do something
that seems a little counter-intuitive at first.
I'm going to go and remove this default block
from the end of our switch statement.
I know it seems weird, right?
Like, I'm all nervous.
My immediate reaction is I want to put that thing back.
But now look what happens now that I have done this.
Xcode is warning me before I even
run this thing that the switch statement is now incomplete
and I might want to fix it.
It's smart enough to know that I haven't covered all my options.
And it'll give me this nice warning.
And in fact, in this case, ha, no pun intended,
I not only get a warning, but I also
get an error because there are times
my method no longer returns a float
and my app won't even build.
By the way, even better if you're using AppCode,
hitting Alt-Enter will give you this "create missing switch
cases statement," which will automatically spec out
those missing code branches for you.
That's pretty nice, huh?
Oh, and for you Swiftees out there,
Swift is even more harsh.
It upgrades that warning to an error.
And it won't let you create any switch
statement that isn't exhaustive.
Of course, their recommended solution
is to add a default clause.
But as we've seen, that isn't always the best advice.
Now obviously you can't do this in all situations.
If you're writing a switch statement based on an integer
or say a text character, Xcode won't
know whether you've covered all these cases are not.
And in fact, in these kinds of situations,
Xcode will complain correctly that you
do need to add a default case.
But if your switch statement is based on an enum
and you don't think that default case should ever
happen, drop it and let Xcode catch those errors for you
before your players do.
So there you go.
Thanks again to Tom on the Google Maps for iOS team
for sending me the tip.
But what about you?
Do you have an idea that you think
would make for good "Quick Tip"?
Send it in.
You can email me at the address here.
If we use it on the air, I will send you some schwag.
I'm not sure what it's going to be,
maybe a t-shirt or a key chain or an iPhone 6
or-- what's that?
I'm sorry.
OK.
I've been told we don't have the budget for an iPhone 6.
But we do have the budget for a t-shirt,
so maybe it'll be that.
Anyway, thanks for tuning in.
You keep coding.
And I'll see you next time on "Route 85."