A Strategy for Great Work

Session 237 WWDC 2014

Experience with past projects can help you do better work in the future if you can draw out the right lessons from what's happened. Hear stories and gain valuable insights from a senior engineer, with a lot of Apple software development experience, who's learned a few lessons along the way and figured out some useful approaches to take.

Hello.

[ Applause ]

Thank you very much for coming today, and if you're watching later on video thanks so much for watching.

I'm Ken Kocienda, and this session is called "A Strategy for Great Work."

So I think we all try to do great work.

I certainly always try to do great work.

Regardless of the results and the outcome, certainly the effort is directed towards doing something great.

I think that's probably the same for all of you, that's why you're here at the conference today, that's maybe why you're watching later on video.

Now this is a subject, that's very important to me, I like talking about it, I like thinking about it.

And I was last on stage in 2012 with a talk called "Basics + Habits," where I talked about some technical concerns, some real certain nuts-and-bolts things about how to set up a project and then how to run projects once you have them going.

But, again, this is very tactical, sort of down into the details, things like code review and working with your other people that you might have on a team.

So today it's different.

I would like to in this session talk about some higher level ideas, kind of move it up to the level of strategy rather than tactics.

And so I went out and got a helpful quotation from Wikipedia to sort of think about what the difference between strategy and tactics is.

And so tactics are the actual means used to gain an objective, while strategy is the overall campaign plan, which may involve complex operational patterns, activity and decision-making that lead to tactical execution.

Certainly, the complex operational pattern sounds like programming to me, right?

Definitely.

So I think that really sort of strategy is you're having a big idea of what you might want to do, and that really should hopefully be driving what you actually do to accomplish the goal, right?

So today I'd like to talk about some of these ideas, these high level ideas that inspire and inform my everyday work.

But really this session is not sort of how to make a great project in 21 days, right?

I mean it's not going to be, it's never that simple, right?

Every time you see something like that X or 21 days it's never, ever, ever that simple.

So it's not simple; you kind of need a plan for kind of attacking the problem here.

And so today how I'm going to do that is tell you some of my stories, projects that I've been involved in.

But, you know, but there's kind of like a note of caution when you hear stories and maybe try to apply it to your own life.

And I have an example here.

Let's say you're in Las Vegas and you see somebody go by who is carrying a big pile of chips over to get them cashed in, and you stop the person.

You say, "Wait, what did you do to get that big pile of chips?"

And the answer comes, "I put it all on 14."

Okay, so it's true, but not so useful to you, right?

You go over and put it on 14, you may or may not get the same result, most likely not.

So hopefully the stories will be interesting to you, but the real goal before, during and after the story, right, particularly after is to extract out the lessons from the stories because I think the lessons if you take them in the aggregate starts stringing together some lessons.

That sort of points toward a strategy, it certainly does for me.

So today eight stories, 11 lessons, take all those lessons, put them together and really that is what informs my work.

And, again, of course, I'm always trying to do great work, so hopefully this will all come together in a nice big circle at the end.

So to begin with the stories.

Number one, the story is "Like a Crystal Ball," and the lesson is know a good idea when you see it.

So I joined Apple in June of 2001, and if you think back to that time, Mac OS X, version 10.0, was released about three months before.

Now that's kind of a long time ago.

When you think about it the browser on the platform was Microsoft Internet Explorer, and that's the browser that's shipped with the operating system from Apple.

Not only that, there was no framework to load and render web content, right?

So we just had an app, but no framework.

So my job, along with someone else, a fellow named Don, we joined the same day.

Our job became make Apple a web browser and an Objective-C Framework, too.

Again, load and render web content and make that available as an API to you all, to the developers.

So we started looking at some options.

Well, what were the options available at the time?

And you see sort of the leading candidates there.

Some of these were commercial products, kind of a buy option.

Some of them were Open Source projects out there in the world going on.

We could go and make perhaps, adopt that source code for our project.

We could also start from scratch, we considered it, absolutely.

So my job was to begin to do some technical investigation of particularly the Open Source options.

And I downloaded Mozilla.

There's one story, I took about a week, I remember, to try to just get Mozilla to build on the Mac.

And I remember at one point one of the steps in this long recipe of steps that needed to get done to get Mozilla to build, I needed to rebuild the C, metro work C library, was one of the steps.

So this was not a straightforward thing, but I eventually got it building and, you know, okay.

But this process went on for weeks, and I went and got these programs.

The commercial products, you know, what I did for that was got them running and started doing some performance analysis and say Unicode compatibility.

And so between the commercial products, those test results, and the Open Source projects, some sort of reckoning of how much source code was there, how easy it would be to adapt it and so forth.

Some test results, I printed out on paper, but I didn't have a demo.

No demo, just test results.

So right about that time we got a new engineer on our team, a fellow named Richard.

And so I showed him, described to him basically as I described to you what I'd been doing, showed him the test results.

And he said really what have you been doing?

Six weeks and this is all you have?

So I was like, well, yeah.

I just kind of shrugged and said that's what I have.

So he just didn't think very much of that, and so he went away.

And two days later he had a demo.

He took one of those options, KHTML, which is the web rendering engine that was part of the KDE desktop environment for Linux.

He grabbed that source code, got it running on a Mac, just did whatever kind of hacks that he needed to do to get it running, and had Konqueror, the KDE's browser, running on a Mac in an X window.

This was amazing.

It was absolutely amazing.

We were just standing there and like looking at a browser running on the Mac, that's like it was like a crystal ball, it was absolutely amazing.

And we saw all the people who were involved in, you know - not only us on the project, but then decision makers at the company - saw that KHTML was our future.

This was just like he'd opened up this tunnel to, like, the future.

It was absolutely amazing.

And so the lesson from this experience is to know a good idea when you see it.

I mean really for me, I kind of felt like a bumbling idiot.

There I was for six weeks trying to figure out what to do and really had nothing, and someone new came in and in two days he had the future right there that we could use.

Now sort of the sub-lesson for this is really what does this mean, know a good idea when you see it?

Is even if something like this happens to you and you're made to look like an idiot, it doesn't matter.

I didn't care.

It shouldn't matter to you either because there's actually some, a couple of good things about this experience.

Number one, I had a great new team member who I was going to be now involved with, who was going to be helping me to kind of make this project happen, and he really proved in two days that he was really good.

And so it was just like, boy, the next day, well, we kind of know what to do, right?

We're going to start making this future real.

And so that's kind of the story of "Like a Crystal Ball," but there's a bonus lesson here, too.

Not only know a good idea when you see it, but kind of this extra lesson of make demos and prototypes.

If you're starting on a new idea don't test results, that's all well and good, but you should also at the same time make something that you can actually begin to use like you want to use the real thing that you're going to be making ultimately in the future.

Get that, open up your own tunnel to the future, right?

Get something in front of you and working as soon as you can.

So that's "Like a Crystal Ball": Know a good idea when you see it, and make demos and prototypes.

So the next story, number two, is "The Black Obelisk," and the lesson is don't try to solve every problem at once.

So continuing right on from the end of that last story: KHTML, fantastic.

The more we looked at the code, the more we were confident that this was really the way for us to go.

But really what do we do now, right?

I mean what do we do, right?

And so, as you can imagine, Open Source we go and it's part of the KDE desktop, so we went and we downloaded all of KDE.

But the thing is we only wanted KHTML, only the HTML rendering engine, and we also wanted KJS, the JavaScript engine.

So the job became to sort of draw a line around just the HTML part of this whole desktop environment so that we could just extract that and use it.

And this turned out to be about 100 source files.

It seems tractable.

So the next step was to bring those files over to the Mac and start compiling them, one at a time, right?

Of course, it didn't compile because we just took this source code that expected this whole other desktop environment around it, and now we just sort of pulled the whole rug out from under it.

So, you know, it didn't compile.

We had a whole bunch of missing things, and so we just began stubbing them in, stubbing in missing functions one at a time.

And these were very, very light stubs.

These were only stubs in header files, right?

So we only wanted to sort of define the problem in terms of all of the missing things that we needed to add.

This was very, very slow work.

It took about another six weeks - six weeks was kind of a magical number for this project.

This took about six weeks of just compiling.

It would be like 10, 11 hours of compiling every single day.

So it was pretty painstaking, and then even at this step nothing linked because as I mentioned these are only header files.

So we were only running, we weren't I made a custom make file, I said don't even try to run the linker, just like try to show us what we were missing.

So after we were done with that, right, we had another six weeks to get everything to link, actually going in and finishing out sort of the header file, actually putting in some stub implementation for everything.

And even then we had lots of crashes because in a lot of functions that returned strings, we returned empty strings, and obviously that's not really what a lot of the code was expecting.

So we also added in a whole lot of log statements to our implementation, saying, yes, this is not implemented at all, I mean it returns a value, but sort of not implemented at all, partially implemented.

Yes, we think we're pretty close, and implement it.

So we had a whole bunch of log statements that we would see; we had a whole bunch of messages getting written to the log as we actually tried to use the program.

And after this whole process of many, many weeks, we eventually wound up with a Mac program that used KHTML, and then one day the lights came on.

So my coworker, Richard, was actually off on vacation.

He was really kind of doing this, sort of leading up the effort to get things to link and not crash so much, and then I came in and took over the process and actually got the first thing to draw on the screen.

So I loaded a URL, in this case www.yahoo.com, and reams and reams and reams of log messages go by, and the program didn't crash, and then there was a short pause, and it drew.

The Black Obelisk [applause].

So this is the first thing that WebKit, and Safari ever, you know, what became Safari, ever rendered.

Now, see, it's a little bit of a secret, as it actually turns out that this was a reversal, that Obelisk should have been on the other side of the screen, but we fixed that sort of little geometry problem very soon after.

But you can imagine that once I got this going, go ahead and fetched everybody who was disclosed in the project, and we're all sitting around sort of like "2001 Space Odyssey" with this Black Obelisk, going "whoo."

So that was a very happy, happy moment.

Now the lesson from this experience is don't try to solve every problem at once.

At this point we had almost no knowledge of now the innards of KHTML worked.

This was simply a mechanical process of making the compiler happy, making the linker happy, making it so the program didn't crash when we tried to do something with it.

It was all very, very mechanical.

The compiler says there's something missing, go add that thing so that it's no longer missing, right?

Now it turns out, of course, a web rendering engine is a very, very complicated piece of software, and but we just didn't have the bandwidth to think about it at this point as we were trying to just get those lights to come on.

That began to happen as soon as we had a program that would no longer crash, right?

So don't care.

If you're trying to attack a new, big problem, and you've got this big problem space, particularly if that problem space is new to you, just try to figure out what the most important thing is to do first and do that.

Don't think about the whole problem or try to operate on solving the whole problem at one time, right?

So don't try to solve every problem at once, and that's "The Black Obelisk."

So the next story, number three, is "The Hardest Problem.

And the lesson is find smart friends and listen to them.

So fast forward to the fall of 2003, and my job became editing to WebKit.

So we wanted to use WebKit to edit HTML mail in mail.app on Mac OS X, and we wanted to make editing in WebKit look and work like a text editor, okay?

So the problem that we were trying to solve is somewhat obvious, right?

A lot of other platforms, in particular Windows, sends HTML mail from Outlook, and we wanted to not only render it, which we could now that we had WebKit, but we also wanted to edit it.

Because if you think about it, before WebKit had editing the web content would show up in your mail message as an attachment in our TF document with a big blinking insertion point after it, you could just kind of delete the whole thing with one delete an entire web page with one back space.

So that's not what we wanted, we wanted to be able to get into the details of the web content so we could edit it, right?

So now, the hardest problem I have ever, ever worked on in my, well, many, many years of programming is arrow navigation through web content.

Now what do I mean by that?

So picture a tiny little web document, like this, and what you do then is you hit the arrow key the right number of times and the insertion point winds up at the end.

That's it: just go character by character, have the insertion point show up in the right place each time you press the arrow key, and then similarly press the arrow key to go back the other way and send the insertion point back to the start.

That was it.

This turned out to be very, very difficult.

Now why is this?

Because, you know, unlike say an RTF document, which is just a series of characters and indexes into, basically an array of characters, web content is a tree structure.

So if you see on the top where the insertion point is at the end, and then if you look at the model, the web document, the insertion point would blink at the end if in the web document, the insertion point was there or there or there or there, right?

So what I had here was a complex model of view relations where the model changed, but the view didn't change, right?

So now to begin thinking about this I used the DOM, the web DOM, the document object model, the API for addressing web content, and used positions in the web content to try to understand where to make the insertion point blink.

And so, as I just illustrated, I came up with this notion of then equivalent DOM positions.

DOM positions that would make different DOM positions, but that would make the insertion point blink in the same spot, okay?

So I started writing some code: very simple, right arrow, algorithm here, get the insertion point position in a DOM position, then find this function and use this function, equivalent downstream position to find the DOM position that would still make the insertion point blink in the same spot, but was closer to the end of the document.

And then go to the next position and then set the insertion point there.

Now that seems reasonable, but kind of focus in on these two important functions here, right?

Well, naturally it's just a program, right?

I mean so if you wanted perfect results the functions need to work perfectly.

And the problem with that was that equivalent downstream position was implemented in terms of get next DOM position, so sometimes I would have this feedback process going where bizarre things happened because a bug would then feed into itself, right, and cause something that was very, very difficult to understand and diagnose simply by looking at the result in the view.

So it was complicated, right, to get right.

And then other issues come up, as well.

What if you're already at the end of the document, the visual end of the document?

As you know, if you've ever probably viewed source on an HTML document, there's often many, many things, at the very least sort of a closing body tag, closing HTML tag.

A lot of times there's script content.

There might be style content.

There could be any sort of information that's not visible after the visible end of the document.

And by DOM position it will, you know, if you just kind of send it off to a position it will merrily go there, and there won't be a place for the insertion point to blink, so this was a problem, as well.

And then what if you want to move by word because the ultimate goal was to make a text editor, right?

So you hold down the option key and arrow, and then you move word by word, not character by character.

And so I was nowhere, I was stuck.

I was working on this, well, just for the sake of argument say six weeks, the magical number, but for many weeks without really feeling like I was making progress.

So I asked for help, and fortunately I had some very smart people in my team, which of course the other stories have already illustrated.

And I explained the problem to them, much as I just did to you, and their solution came back very, very clear that DOM positions were too low level.

I was trying to build a very complex edifice, but I was using too fundamental an abstraction to get the job done.

So I needed a more powerful abstraction.

So they came up with one, they gave me one.

They called it VisiblePosition.

And all this was, this is C++ code, so this is C++ class that represented a place in a document where the insertion point can blink, and then secondarily a library called visible-units that could take a VisiblePosition and move by words, lines and documents, okay?

So they gave me this design.

Now the point is that I still had the hard work of figuring everything out, but now I had a complete outline of all the code that I needed, every place, word by word, well, I knew now there was actually a place in the document, there was a stub function that was where the move word by word code should go, where that should live.

And so this, really this set of abstractions really helped me to just organize the work and figure out where this solution should live.

It also made it easier to think about the problem so that I wound up with fewer of these kind of functions that fed back on each other producing bizarre results.

So when you're blocked don't be blocked.

Find smart friends and listen to them.

In this case they said VisiblePositions, visible-units.

I said, OK, I will do that, and it worked, it absolutely worked.

I certainly went back and got some more of their help, some details, but this was the big, big help.

Find smart friends and listen to them, particularly when you're stuck.

Do not stay blocked.

And this is how I got through my hardest programming problem.

And so the next story, number four, is "QWERTY," and the lesson is work should explain itself.

So fast forward to 2005 now, and I joined the iPhone development project pretty early on.

And initially I joined to work on WebKit because it seemed like a good match for my skills and experience at Apple, but I soon transitioned to work on keyboards.

So now if you think about it, right, and this is kind of what we had when we started with the iPhone.

We had a screen, and we had this notion that the keyboard would be on the bottom and the app content would be on the top.

And, of course, the big question was, well, what should the keyboard do, how should it work, what should it look like?

And if you had seen even from the very beginning the Steve Jobs' announcement of the iPhone, the original announcement in 2007, he pointed out very, very clearly this virtue of the iPhone that it didn't have those plastic keys on the bottom, we could draw the keyboard and make it look like whatever we wanted.

So now jumping back to the beginning of that story, because Steve on stage was the end of that story, right, we didn't have plastic keys so we needed to experiment of what we were going to do, right?

How were we going to replace those plastic keys with software?

And we came up with many, many ideas for how we would do this.

Now there are a lot of challenges, particularly at the beginning, when we were all new with dealing with a touchscreen keyboard, particularly touchscreens in general and touchscreen keyboards, specifically.

So one of the challenges is that small targets are hard to tap, it's pretty logical.

I'm sure you even experienced that now, the smaller the targets get the more difficult they are to tap.

And not only that, but as you go for a target, as you get close to it your finger covers up the thing that you're looking for, so the smaller that it is the more difficult it is to do some fine-grained adjustments as you get close.

So these were - we, in our experiments, we were seeing the result.

This was very challenging to make a keyboard that worked, at all.

And so in the beginning, we were pretty clear, or at least we thought we were clear, that bigger keys would be the solution - this would solve both problems.

So I have an example of something in the spirit of one of the experiments we tried, not an exact example, but something very, very much in the spirit of what we tried, and I call it the keyboard keyboard because if you think about, you know, other things in the world that accept a lot of touch input, right, well it's a piano keyboard, right?

So you could maybe conceive of a keyboard that looks like this.

So now how does this work?

Well, I'm going to try to - I'm going to type the T key, and so how do you get a T?

Well, you look on all the keys, and you do make a chord, multitouch motion, to find all the keys that have a T on it.

Okay, so then we could go T.

H, H has actually got two of the same keys as T, but H is only on those two keys and the, T-H-E.

So you can see how this would work, right, a chording keyboard, right?

And this is good because the keys are big.

You can even maybe think of like it's just like home keys, right?

You just kind of keep your five fingers right on top of the keys and, you know, you can use the keyboard like that.

And so it's easy to press the correct key, so that's good, but it's bad because there's a learning curve, right?

The first-time experience is a mystery.

You see this alphabet soup on this thing that looks like a piano keyboard.

Well, how do I use this, right?

And so we were thinking that, well, the solution would be we'd have a tutorial to teach the people how to use the keyboard.

Now it's actually, you know, this is not - this is an idea that actually has some history at Apple because the original Mac shipped with a tutorial to teach people how to use the mouse, since that was new, right?

So we figured we'd come up with a tutorial, and you think about it, is that even if we didn't have that keyboard keyboard, but if you imagine that if we did we could maybe even come up with a keyboard that used music to try to teach people that you could maybe play a tune, right?

So it wasn't the craziest idea in the world.

But after each of these experiments and each of the times that we thought through how to make a tutorial, we always came back to QWERTY because you all already know how to use it.

There's no need for a tutorial, right?

You see the thing, and instead of, gosh, what is this, and how do I use it?

Right? Instead of that you have this, where you look at it and, okay, it's different because it's a touchscreen and it's small, but we're sort of calling on and invoking, right, a lot of these kind of these familiar notions that you're already very, very comfortable with.

So that's why we wound up with this and ultimately, right, we have this today because we thought it was more important that the work should explain itself, right?

You already know how to use QWERTY.

We don't need a tutorial.

And so this was really the key to that decision, key I guess is a funny word, but it's the keyboard.

But it's the real reason why we chose to go with QWERTY because, again, we thought that work should explain itself.

So the next story, number five, "Every Word on Every Keystroke."

And so the lesson is choose the simplest thing which might work.

So continuing on in the development of the iPhone keyboard, it became my job to do the work to make QWERTY possible, right?

We had this challenge of small keys, difficult to tap now, and of course you all don't care about my problems, you just want to type quickly.

So the software was going to need to help.

And so the eventual solution for that was auto correction, which is, of course, what you meant and not what you did, taking what you did and figured out what you meant from it.

And, of course, there's quite a bit of smart people have thought about text processing and text prediction, and so some of the terms that are in the state of the art, you know, then as now Bayesian statistics and Stochastic programming, Conditional Random Fields.

And a lot of these involve large statistical models to make them work, that they rely on, language models.

And these were not going to be possible given the hardware and software environment of the original iPhone.

Not only that, but I last studied math in the eleventh grade, which was in the'80s, and it was in the early'80s.

So I was kind of looking at Stochastic programming, oh, okay, well, you know.

So really what I decided was I needed something simple because math is hard, okay?

[ Applause ]

And so here is a little bit of an idea, a little bit as to how this auto correction works, right?

Certainly, in the, you know, way back then and the first time that I tried to get this idea together.

So you're typing a letter, "I."

Well, since the keys are small maybe you meant those keys, as well.

So "I" was highlighted, but maybe you missed and maybe you meant one of the keys around "I."

Okay, and then you type a T, and, well, similarly, maybe you meant one of those letters around it.

So even just with two characters, you can see that there are a number of possibilities.

All right.

And so in one column are words that are real words and are going to be in an English dictionary, and in the other column there are just those words that are - they're letter combinations, but they're not words.

We have words that, the one column has words that are in the dictionary and the other column has just letter combinations that aren't words.

And so what do you do with this?

This is now raw material, right?

And so auto correction, really ultimately sort of a big part of it, is just speculation, you know.

Did you mean this one?

Did you mean that one?

Did you mean the other one?

Did you mean this one?

And this involved many, many, many dictionary lookups to just check.

Are these letter combinations?

Are these words in the dictionary that is selected by the user?

So I needed something that worked really, really fast.

And so the idea was offered to me that, well, you could maybe as the user is typing just kind of send that dictionary lookup stuff on a background thread and sort of post the results back when it's done.

And, of course, being back then we didn't have GCD, and so the Pthreads would have been the solution.

And it's like, I'm scared of multithreaded code.

It's hard; it's hard to get right.

I'll tell you a secret, it's just like there was actually - I did have one little bit of multithreaded code in the keyboard in the beginning to do some initialization, and that was as large a source of bugs - it was a tiny little piece of code, and that was as large a source of bugs, dealing with app startup and you launch an app and then suspend it, it was a huge source of bugs even if it was just a little bit of code.

And so I wanted to keep multithreading out of auto correction, which was much more complex, right?

Because I wanted us to keep things simple because I can understand simple.

All right, multithreading is hard.

I can't even like make an egg and breakfast in the morning, right?

I make the egg, make coffee, then make the egg, keep it single threaded, right?

Because otherwise I wind up with a messy kitchen.

OK, so keep it simple.

So here is actually a little algorithm for searching a dictionary.

Word list on one side, and a little algorithm on the other side.

And this was actually thought up by the same fellow who did the KHTML demo.

And so he came up with that good idea, and as part of some of our other experiments, and, boy, I saw that good idea and I used it.

So what do you do?

You have a list of words in a dictionary, you memory map it, you iterate the list once to find the line endings, you store those addresses in a pointer array, you can then binary search and you can find whether a word is in the dictionary really, really fast.

Really, really fast, and so next after that I wrote a custom C++ string class that could wrap any string in that memory map area.

Each of those strings were null terminated on the end, so you could just kind of go and wrap an address, and you have a string, as long as you're at a line start.

And so this turned out to be really, really fast.

I could check dictionary membership in microseconds, even on the original iPhone hardware.

So this was now really, really fast.

And so what this did was it made speculation really, really cheap, and that in turn made auto correction possible.

So I could go from this and take all of those permutations, even for as long a word as you might find in a language, and actually go and figure out whether that word is going to be in the dictionary or not and whether similar options would be as well.

And this turned out to be so fast that I stored no state for the current word.

I didn't store previous results.

All I did was actually store the string for the user's typing.

If we think back here, all I've had stored is I T.

What have you typed?

The actual characters that were lit up, right?

Not the neighboring ones.

But the only thing stored was the characters that were lit up, okay?

So only store that string.

So it's actually, I reran the entire algorithm on every keystroke from scratch, which means of course that it searched the whole dictionary, 70,000 plus words, on every keystroke.

Because, to me, this was the simplest thing, as I was thinking about it, it was the simplest thing which might work.

And by coming up with sufficiently fast implementations of this, it turned out that the simplest thing did work.

Simple is often speedy, and simple was something I could understand.

And when there are bugs I could understand where those bugs might have been, and that's every word on every keystroke.

Choose the simplest thing which might work.

And again if you're kind of looking from the beginning of a project trying to think to the end of a project and what you might have when you're all done, that's why it's termed this way, choose the simplest thing which might work.

If you did actually have a crystal ball you could tell whether maybe your idea would work.

But I think this is, even from the beginning, if you kind of think of the simplest thing which could possibly just give you what you need, go with that first.

I think that's a good idea.

And so the next story, number six, is "We Only Need One of These, Right?"

And the lesson is only show your best work.

And so fast forward to 2009.

I joined the efforts to develop the iPad, and the iPad needed a keyboard, and so it's by this point I had two signs pasted onto my back - one said "Kick me," and the other one said "Because keyboards."

So it was sort of something that seemed to be in my area.

And so I noticed that in landscape, you turn an iPad to landscape, that the number of keys that you could fit across the top was close to the size of a full-sized desktop keyboard.

And so here is a representation of a full-sized desktop keyboard, and there is the size of the keys that we could fit on an iPad.

And if you see, overlay one on top of the other, it's pretty close.

It's not exact - the iPad is smaller - but it's close.

And so I was thinking that, hey, well, you know, it's not exactly the same size, but auto correction could maybe help you to type comfortably, right?

So, yes, big keys across the top that seemed like a good idea.

But then we also had the question in our minds of what if you wanted more keys?

We now had space for them.

Allocating the space on the original iPhone keyboard was tortuous because we couldn't even fit the period character on the first keyboard that you saw.

We had to put that onto a secondary key point.

And so we didn't have that problem.

Now we could have more keys.

We had the room for them, and so you can imagine that we can start getting some more keys.

In this case I put in shift and caps lock and tab and a couple extra characters off at the side.

And then I direct your attention to this here, so we would have a switch that would allow you to go very, very quickly between the one with the big keys and then the one with the more keys.

And sort of similar to what we have where you change to numbers and punctuation, but this was really keeping the letters the same and just bringing in more keys.

And so, you know, a bunch of us who were working on this, we thought this was the best of both worlds.

It was cool, right?

So I got to demo this for Steve, which is a gulp.

And so, so bringing the iPad, you know, you kind of have the demo room, and go in there and he's in there, and it's like "He's in there."

And then, okay, so you put the iPad in front of him, and fortunately the work explained itself, so the description was as short as we're looking at iPad keyboard options today, here are two options, press the switch key, done.

So he did.

He looked at the first keyboard, and he pressed the switch key, saw the animation.

He looked at the second keyboard, he pressed the switch key again, he saw the first one come back.

A third time, presses the switch key, sees the second one come in, and he looks at this for a moment, and then he looks up at me and says, "We only need one of these, right?"

And he's looking at me.

And so I gulped a couple more times.

And so and he says, "Well, which one do you think we should use?"

And I said, "Well, you know, I think we should use the one with the bigger keys because it's just easier to type, it's close to the size of a full-sized keyboard."

And he said, "Okay, we'll go with that one."

[ Laughter & Applause ]

And that was it, really.

I mean that really was it.

It was just quick, and so that's why we wound up with this and then ultimately today, this.

And, of course, the lesson is only show your best work.

Perhaps more than anyone else, Steve understood this.

Go out and think of all the ideas that you can and not only just think of the ideas, but get them and make them and use them and live with them and think about them.

And then try to figure out which is the best one.

So what was interesting to me about that story is that even though I was under a lot of pressure, when he asked me which one I thought was better I knew, but I didn't have the courage to just go in there and show him the one that I thought was really the best the first time.

It needed his extra prodding, that little bit of extra investigation, that little bit of extra poking to say, wait a minute, right?

Which is the best one?

Which is the second best one?

Let's not show the second best one, right?

Only show your best work.

You have to go through all of the effort to generate lots of ideas to come up with one that's really worth it.

And that's "We Only Need One of These, Right?"

Only show your best work.

Okay, story number seven, is "Let's Try It 2% Darker," and the lesson is iterating quickly leads to better work.

And so 2012 I joined the effort to develop iOS 7 and, of course, as you know one of the big goals for iOS 7 was a whole new look.

And you ask the question, well, how do you make all of these choices?

And a lot of times coming up with these new design ideas, it felt like a game of Whac-A-Mole because every decision affects every other decision that you make, right?

You change one thing, and you have these things over there that kind of familied well with the thing the way it was before, and now it doesn't seem like that, now it seems that the thing that you've just changed doesn't really work well with everything else.

And so this required a tremendous amount of tuning, iterating and iterating and iterating, version after version, effort after effort to try to get things so that they all looked like they belonged together.

And so if you kind of break that down from the process of actually trying to do that work, one design iteration most of the time looks like this, okay?

A guy, like me, will bring a demo to the designer.

The designer will have feedback.

I'll take notes.

I'll then go away to make those changes that the designer has requested.

Then we schedule the next demo, and then we have that next demo, and we go back to the beginning.

So this process can take hours or days because people are busy, right?

And sometimes, you know, it's just hard to get together.

And so we wanted a way to go faster.

Can we go faster?

And so one of my very, very smart friends, again, smart friends, it's a real key, one of my very smartest friends came up with this idea of settings.

And what are settings?

Well, settings are tunable values, right?

You take all of the settings that you might want to tune and put them in just an object that just is a bag of properties.

You use KVO, so that when you change one of those properties the parts of the system that are interested in those values changing can know about it.

She also came up with this way to save and restore these options, and then there was also a way that you could have settings, which own settings, which own settings, so you could have a tree of settings.

And also came up with an editing UI, and it's the editing UI I want to show you.

So here's just a very simple example, a very simple app that lets you manipulate geometric shapes.

So I've got now one blue circle, and you can go and with the settings UI you can then bring up a hud right in the app, twiddle a couple of sliders and change from one blue triangle to three red triangles, great.

And then similarly we can go to this other one that actually support those nested settings, that would use sort of iPhone style, side-to-side navigation to show you the different levels of settings.

And so if I take the red triangles and move it back to the settings for the blue circle, you have this.

And so what did this do?

This did something very important.

This reduced iteration time because once you had the right settings surfaced in the app, you could sit with the designer, an engineer could sit with the designer, and try many, many, many options.

And so we got to the point where you kind of tried to figure out what control center could look like, and the designer could say, well, what if we made it 2 percent darker?

I don't even know if you can see that up on the big screen?

It's the point of it, is that we were trying to get tuning to this level, 2 percent darker, 2 percent darker on your left than on your right.

We wanted that level of polish and attention to every single value in the OS.

So when we had a tuning session like this, it was great because I could just go back to my desk now, copy the defaults that got saved from the tuning session, copy those to the new defaults, and commit.

It's great, and this made it cheap and easy to tune; we could just do it over and over and over and over again.

And this was the way that we wound up with just a handful of blur styles for iOS 7 that are used consistently everywhere.

It was very, very difficult to come up with those, with that set of blur styles.

And this is how we did it by just iterating and iterating and making iterating easy and cheap.

The lesson really, right, is iterating quickly leads to better work.

I think my experience from iOS 7 was there was a direct correlation between how easy we made it to try out new things and what the quality of the final work product was.

And so that's "Let's Try 2% Darker," and the lesson is iterating quickly leads to better work.

Okay, story number eight.

Three lessons from making this session.

And so this is not the original session.

I wrote an entirely different set of slides.

And not only that.

I did three full rehearsals with them.

I like to rehearse a lot before, I mean it's important that this session goes well for you all.

You all came here, and I want to make sure they're giving you a good product, I mean so I put a tremendous amount of effort into preparing the slides and rehearsing.

And so with that other set of slides I used up a big portion of my time rehearsing that set of slides.

See, the good thing was, it was done way ahead of time.

It was great.

It felt good to just be like preparing for WWDC can be really, boy, it just always seems like everything is down to the wire, and this year, boy, I was really ahead of time.

But I had one more review for the content that I had in my slides, just go over the material and the content, particularly because I'm talking about some past Apple work.

And it turns out, yeah, that version just got shot down.

Yeah, you can't show that.

There were just issues that couldn't be resolved.

The details aren't important, but there's kind of the one big detail which is I don't have a session anymore.

Three weeks ago I had something that was rehearsed, and two weeks ago I didn't know if I was going to be here today.

So I needed to rewrite.

And there were three important lessons that I took away from that.

And the first was during this review session, where the person who I was submitting my slides for review to, said "You can't show that."

He didn't raise his voice, it's just like "You can't show that."

And here's why, he gave me the reasons, but he was very calm.

And even after, I mean it was clear, it was bad news to me, and even he found me later and made sure that I was okay with this decision that was a very hard one to share with me.

And so the lesson from this is be kind to people, but be honest about the work, right?

There's no reason to like be shouting and berating people who are trying hard and doing their best.

If you have ever found me in a lab or maybe even with what little time we have left in the conference before it ends, if you find me in a lab today, I hope I will do my utmost to be kind to you personally because I'm so glad that you're here and so glad you're contributing to our platform.

And I want to see you do great work, too.

But if you show me a piece of work, I'm going to be honest on what I think about it.

And those things just need to be kept separate, the personal kindness and the honesty about the work.

And, secondly, it's kind of like sort of this different side of the same coin, is that I didn't take his feedback personally.

And the lesson is to separate yourself from your work.

Now and I always invest a tremendous amount of care and emotion into my work, it's my nature, I can't help it.

But after I'm done making something and bring it to the stage that it's ready to demo, I just try to then divorce myself from that thing that I just sweated over making because that's not me, that thing that I just made, all right?

I'm ready to accept whatever feedback anybody has and ready to go and do the next thing, right?

So you need to kind of divorce yourself, when you get feedback, people hopefully are not giving you the feedback, they're giving you the feedback about the work.

So separate yourself from the work, regardless of how much time and effort and how much investment you have in it.

And the third lesson is, well, obviously, I needed to get back to work.

If I wanted to have a show, right, at all, I needed to figure out how to make a set of slides that would work.

And the lesson here is that you're never done.

Kind of seems like some sort of nightmare, if you think about it one way it's that you're never done, really?

But you think about it, no, we're never done.

We loved the first version of the iPhone when we shipped it, and then we went right back and we made version two.

And earlier this week we showed iOS 8 and Yosemite and a whole bunch of other great things, right?

You are never done.

If you're committed to working in this industry, working in high tech, right, you are never done.

The world keeps moving; you've got to try to keep moving with it.

So do the best that you can do at any one time.

And basically you're always shipping your latest demo, if you think about it that way, it's just that these demos get to be very, very polished, polished to the point where you're going to actually share it with the rest of the world, right?

So still on this idea, this is a quotation that's actually up on the wall - very, very large.

In Cupertino, a quote from Steve Jobs, and he said, "If you do something and turns out pretty good, then you should go do something else wonderful, not dwell on it too long, just figure out what's next."

And I think this is true, not only when you do something that turns out well, but it's even as in the case for me, for this session, I did something that didn't turn out so well, I needed to figure out what was next.

I could give up, or I could try again, and I tried again, and I'm very glad that I did.

I'm very happy to be here today.

And so the kind of the big, sort of joined up lesson from this section is that the stories and lessons never end.

I thought this was going to be a session just about stories and lessons and had no idea that I had started a process that would teach me more lessons.

And so those are my stories, and there they are.

Again, and I think, I hope, at least that you found them entertaining, but really I think the important part is these, the lessons, that you can take out from them, because you're never going to find yourself in exactly the same situations that I did.

But I think that you'll find yourself in situations where you can apply some of these ideas usefully and productively.

So, again, those are my stories.

And so now I ask you, I urge you, to go out and make your own stories, tell your own stories, extract the lessons out from them, right?

And then figure out how you're going to use that experience to go and do some more great work of your own.

So thank you very much.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US