Swift 3 introduces new API Design Guidelines specifically crafted to the unique character of Swift for clear, concise code. This talk will explore the philosophy behind the Swift API Design Guidelines and their application throughout the Swift Standard Library and the Cocoa and Cocoa Touch APIs. See how this API transformation will affect your Swift code and learn how to ensure a smooth transition to Swift 3. Learn how Swift 3 imports Objective-C APIs and how to expose rich Swift interfaces for existing Objective-C libraries.
Welcome. So, I'm Doug Gregor.
I'm here with my colleague Michael Ilseman
to talk about design.
Because good design makes us more productive.
And good API design helps us write code that is clear,
concise and beautiful in Swift.
And that's every bit as true whether you're writing your API
for a million other developers or just
for yourself inside your own app.
Because good design really does matter.
So, we're going to be talking
about the Swift API Design Guidelines today.
These are new guidelines we're introducing with Swift 3.
We're going to talk about the philosophy behind
Talk through some of them to try to get a sense of how
to build great Swift APIs.
Now, then we're going to talk about the Grand Renaming.
Which is what we like to call the application
of these guidelines to all of the APIs you use day to day.
Swift Standard Library.
Cocoa and Cocoa Touch APIs.
Now, this Grand Renaming is going
to affect a lot of your code.
Pretty much all the code that you've written
in Swift 2 is going to change in some sense in Swift 3.
So, we're going to talk through what that means for your code.
And how to deal with it.
And starting thinking in Swift 3.
Finally, we're going to talk about some new tools and tricks
that we have for mapping C and Objective-C APIs
into beautiful Swift APIs.
That's a whole lot of what and how.
The biggest question you probably have
about the guidelines is why?
Why, after two years of working
with Swift are we changing all the APIs that you work
with on a daily basis?
And the answer comes down to the character of the language.
Because every programing language has its own
It has its own syntactic feel.
But it's more than the syntax.
It's also the kinds of tradeoffs
that that language decides to make.
Does it skew toward safety, performance?
Do you care about some mathematical terseness
or something that is clear and easy to read?
You take a look at Swift code, and it's instantly recognizable.
And you can see Swift rendering an opinion
about certain things here.
It uses trailing closures.
So the control flow works
with your libraries and your APIs nicely.
It has optionals, so you have
to consider the possibility of nil everywhere.
You can't just ignore that this possibility exists.
And so, when you're working with Swift it feels like Swift.
But it's not just the language contributing to it.
It's really the APIs you use day in and day out.
And these APIs have to meld with the character of the language.
So you get a consistent, whole experience of working
with beautiful Swift code.
Now, these are some Cocoa and Cocoa Touch APIs.
And these APIs were designed based
on the coding guidelines for Cocoa.
You may have read these before.
I hope you have.
They espouse clarity and consistency
in the design of APIs.
And we've been applying these to thousands upon thousands of APIs
over more than a decade, all right, to produce the Cocoa
and Cocoa Touch platforms.
And these wonderful APIs we use.
Now, these guidelines were designed
for a different language with a different character.
And so, when you bring all of these APIs that were written
for Objective-C into Swift unmodified,
they seemed a little bit out of character.
They feel a bit not-Swifty.
What's that even mean?
You hear it a lot.
But in essence, this is why two years in to having Swift
as a platform that many thousands
of developers are using, is the right time to reevaluate.
Because we have experience from a much larger community
to understand what works well in Swift code.
And so we set off to design the API Design Guidelines to try
to codify what it is to build a Swifty API
and help everyone build more consistent, more clear APIs
within this language that we love.
Now, in the lower left you see SE-0023.
That's the Swift evolution proposal number
that contains all of the API Design Guidelines.
You'll see these proposal numbers throughout the talk.
Again, you can go look at Swift.org,
look up this proposal number to see more information
about that particular change to the Swift language.
But for now, let's talk about the guidelines themselves.
The main principles of the Swift API design guidelines are
clarity at the point of use.
Where your API shows up in someone else's code.
And we love concise code.
But the clarity is the most important aspect.
It's more important than having brief code.
That said, concise code does happen in Swift.
Swift code does tend to be more concise.
We can feel it when we look at the language.
And we see it in actual metrics when we talk about apps
that have been ported into Swift and written in Swift.
But that comes from using the right contextual cues.
Let's dive into these principles a little bit more
and look at some APIs.
So, we're going to talk about usage first.
So why focus on the use sites?
Well, for one, it's just a simple numbers game.
You're going to write your API once.
People will look at that API in code, or maybe look
at the documentation for it a couple of times.
But the vast majority of times that your API matters,
the number of times it's seen, it's going to be in the context
of a whole lot of other code.
And when you're in that context, you have all
of this extra rich contextual information.
You have the local variables, their names, their types.
You have uses of related APIs.
And so the goal of your API isn't
to stand up and say, "Hello!
I'm here and I have a nice big name."
The goal of your API is to fit in with the rest of the code
so that the end result is beautiful.
Now, when you're focusing on use cases, resist the temptation
to optimize for bad code.
It is absolutely true that someone can go and use names
like A and B and C for all the variables.
And this code is not clear anymore.
You can't fix this bad code with your API alone.
All you can do is make other code more verbose or less clear.
So focus on proper use cases.
Focus on the beautiful code and tune your API for that.
Let's actually look at a specific example here.
And so we're going to start with an API
that is removing an item from a collection.
We're going to start by calling it removeItem.
But I've made my first mistake.
This is not a use case.
This is just a name in the abstract.
So, let's bring up a use case that I have in mind today.
Don't ask why.
He knows. So, remove item ted from the list of friends.
Now, you'll notice that there's actually two things
in this use case that are referring
to what the argument is.
They're trying to describe the argument.
There's the word item that's part of our name.
And then there's the argument ted
which is some local variable with a type.
Of these two, the variable ted is the actual better descriptor
of what the argument is.
It's in context.
As you're reading this call in context, you know what
that local variable is.
It means something.
It has a strong type.
So maybe the problem here is really
that the word item isn't sufficiently descriptive.
Maybe we'd feel a little bit more comfortable
if it were called removeObject.
Well, that's probably not right,
because we're probably using value types here anyway.
So it's just actively wrong.
We could say, hmm, removeElement.
Okay. Collections in Swift use the term element.
But, it's not helping us any.
And moreover, if we were to start writing
down different use cases,
it might actually become less clear.
Here I want to remove element caffeine
from a list of organic compounds.
Caffeine is not an element.
It's a compound made up of elements.
So, our attempt at using some innocuous word here
to describe the argument has actually led us
to less clear use cases.
Okay. So maybe the problem is that we should stop trying
to get these innocuous sort of general words in there
and we should be really specific.
Remove person ted from the list of friends.
It's a little awkward in English.
I wouldn't say that.
I would just say, remove(ted).
But moreover, if I do this, if I try to get really specific
for this generic API, well now I expect
to be specific everywhere.
And now there's one conceptual API of just removing an item
from a collection has different names throughout the
That makes it harder to understand.
It's harder to recognize that actually we're talking
about the same thing in different contexts.
So, the Swift API Design Guidelines go a different route.
Omit needless words.
If a word is not contributing to the clarity
of the use site, don't put it in.
So we can just say, remove(ted) from the list of friends.
It reads really nicely.
Now, one of the reasons this works so beautifully in Swift is
that it has a strong static type system to make sure
that you don't write nonsensical code and again,
interpret it in the wrong way.
And so the strong static type system is making sure
that the argument you passed to remove is an element
of the corresponding collection.
If you were to do something truly inadvisable,
like for example, try to remove caffeine from your list
of friends, you're going to get an error message
from the compiler telling you that that doesn't make sense.
So, we've talked about readability of the use sites.
And we've eliminated a bunch of words, which might put you
in the mind that what we're looking for is terse code.
That's not true.
We want clear code.
But, clear code has to hit the correct point in this sort
of spectrum of terseness to verbosity.
And if you think about what is verbose code, verbose code is
when you have extra information in there that you don't need.
And verbose code actually hurts clarity.
Because what is your mind doing as you're reading
through this verbose code?
It's trying to filter out all of this extra noise,
all the things you don't need because they're redundant,
to find the actual signal in there.
Now, the other end of the spectrum is also not good.
If you have code that is too terse,
then you're missing critical information that you need
to understand that code.
A sign that this is happening,
that you've made things too terse,
is when you're reading code and you find yourself jumping
to the API documentation all the time
because the APIs themselves are insufficiently descriptive.
So we're looking for this sort sweet spot in the middle
where you get clear code that is concise.
So all of the information you need to understand those APIs
and how they work is there in the contextual information.
This is actually a principle of the Swift language itself.
So I'm going to put up a bunch of code here.
And in this bunch of code we actually have verbosity that's
not needed in Swift.
That verbosity is all of these explicit type annotations.
These aren't adding to readability.
You can get a sense of what the types are just
by reading the APIs.
And indeed, in Swift you probably wouldn't write the code
You would probably align that type information
and let the static type trebicore [phonetic] do it
for you leading to more concise code
that you can still read through just as well.
Now of course, types are important.
And the types are there.
And if you need reassurance about what a particular type is,
if it'd help your understanding, of course,
the answer is just an option click away inside Xcode.
So let's look at another API and try to talk
about when a word actually is needed
to help describe an argument.
We'll take this little API here that adds a child view
at some particular point within some main view.
And so we write out a use case.
Always start with the use case.
And think about the words that apply to the arguments.
So in the first case we have the word child is applying
to this view argument that is our first argument.
Is child adding something?
Well, we know from the static type system
that sidebar is going to be a view of some sort.
But this word child is clarifying the role
of this parameter in the operation.
It's stating that this argument here will become a child.
It's establishing hierarchy.
That's really important information
for understanding what this API does.
Now, in the second argument, we have atPoint and then origin.
What's origin going to be?
Well, it's going to be a CGPoint.
This API is going to take CGPoints.
And you can't provide anything other than a CGPoint here.
So this word, it's not adding anything.
It's just restating information that's already
in the strong static type system that will be enforced
by the Swift language.
So take it away.
You don't need it.
And now notice what the call site looks like here.
If we read it out, you add the child sidebar at the origin.
It reads grammatically.
This is one of the principles
of this particular API Design Guidelines is
that we really want the use sites to read grammatically.
And we had this for our example here of remove(ted)
from our list of friends.
Now, let's look at a very related API.
So this is removing specifically some element.
If we look at, say, the API that removed something
in a particular position.
Read it out.
Remove position of former friend from the collection.
It's not right.
This isn't the collection of positions.
This is a collection of people.
To actually make this read well we want to say, remove at.
Let's read this out remove at the position of former friend.
Notice how we've clarified the behavior of the API by putting
in this first argument label to describe the relationship
of the argument to the method.
This brings us to naming and the idea of naming.
So, in Swift, a function name is comprised
of so-called base name, which here is remove in both
of these APIs, as well as all
of the argument labels for the arguments.
And so these two related APIs, they share the same base name
of remove because they're in this method family of operations
that remove something from a collection.
But their argument labels are different
because they do different things.
One removes an element by its identity.
The other one removes its element based
on its position in the sequence.
So slightly different APIs have different names.
Now, you can overload based on type information.
And if two APIs that share the same compound name.
But you should only do this
when the APIs have the same semantics.
So it's fine to overload the append name
with no argument label here to append a character
or a string to some text.
Because fundamentally these are the same operation.
They're just overloaded on different types for convenience.
Now, when you're coming up with first argument labels, again,
you want that use case to read grammatically.
And that includes the base name of the method as well
as the argument label.
So my first API here removeBoxes (withLabel:WWDC).
Notice how that reads well.
Now, inside that API we have a prepositional phrase.
So it's a little bit of English grammar here.
But essentially it's withLabel.
And it describes the relationship of the argument
to the actual operation of removing boxes.
And so when you have one of these prepositional phrases,
put it on the first argument label
to describe the first argument.
You also use first argument labels
if you essentially can't form a grammatical phrase
because it would be misleading
to have the first argument in there.
And so here we have a viewController.
And we say dismiss(true).
What is that?
I can't banish a Boolean constant to anywhere.
And so to make this read grammatically,
I need to put an argument label in there.
Dismiss the viewController.
And it's animated.
Animated is true.
And so this is extra information that's coming along.
The first argument label breaks it up so that it reads well
and it's clear that what we're dismissing is the actual
There are a couple of other rules you can read
about on Swift.org.
But essentially you still will omit first argument labels
in some cases.
And these are cases where in the API it reads well
to just have the argument there, insert michael
at the start index of friends.
That reads well.
We don't need a first argument label to make it read well,
and so we leave it out.
Okay. Let's talk a little bit more
about naming before we move on.
So, when you name a method, name it based on its side effects.
So, use English verbs, commands,
to tell the receiver do something.
So here we might say, okay, we have the friends collection.
A viewController, present it.
Organic compounds, append to it.
Right? These are actions taken.
We name based on the actions taken.
Now, when we have methods whose primary responsibility is just
to return some value we use a noun.
Describe the thing that is being returned.
And so here we can ask for the background title of a button
or the suffix of this friends array.
Now, when you're dealing with value types,
it's sometimes the case that you have both a mutating
and a non-mutating form of essentially the same operation.
And here what we like to call --
we apply what we like to call the ed/ing rule.
And so this follows from English grammar.
And essentially you start with the verb form.
And so here we have reverse a collection.
You're commanding X to reverse itself.
Now, for the more noun-like other form,
we use the "ed" rule.
So we ask for X reversed.
Where we're describing what the result is that we want to get.
And that corresponds to the mutating form.
Now, when the "ed" rule doesn't apply,
the "ing" rule generally does.
This is usually when we have an argument here.
So we have a document directory.
We can append a path component to it.
We told it to append this.
Now we have the non-mutating form.
Give me the document directory appending this particular
So these rules, and many, many more, are described on Swift.org
as part of the API Design Guidelines document.
Highly recommend that you read them and try
to apply them to your own APIs.
But of course, these guidelines,
they're not interesting unless they actually are
And this is why we set off on the Grand Renaming.
Which is the application of these guidelines
to the Swift Standard Library, to the Cocoa
and Cocoa Touch APIs as well as targeted improvements to APIs
like Core Graphics, Grand Central Dispatch.
They're used all the time to give them these Swifty makeovers
to be beautiful in Swift.
I talked a little bit about the scale of the Grand Renaming.
So, this is a little screen shot
of a small Swift app called Lister we've been shipping
for a couple years.
It's one of the sample applications
when it's being migrated from Swift 2 to Swift 3.
You can notice there's a whole lot of .swift files on the left.
Basically every Swift file in the entire project is changed
by the transition from Swift 2 to Swift 3.
And if you're looking at some of the details in the middle
and the right panes here, you probably noticed that all
of these Cocoa API names have changed.
Okay? So, there's a lot of change here.
We'll talk about that.
But really what's interesting is
that these Cocoa APIs you may have been using
for a very long time, the APIs are the same,
but now a given API has two different names.
Has one name that's appropriate for Objective-C
and one name that's appropriate for Swift.
As a Swift programmer, most of the time you don't need to care.
You can entirely work within the Swift names.
Use your generated interfaces, the documentation,
everything will show you the Swift names.
And that's all you'll deal with.
However, there are times when you're interacting
with the system where you actually do need the
For example, if you're wiring up target action.
And so, here we actually need
to provide a selector to target action.
And we have this string literal.
What do we write here?
I don't know.
You can look at the generated interface.
Maybe ask your Swift compiler friends on Twitter or something.
You can come up with the answer.
But, please don't do this.
Because this is a really, really weak link
between this string literal, which is super easy to mistype,
and the method above that you actually meant to call.
This is why in Swift 2.2 we introduced #selector.
#selector is a very simple thing.
It's an expression.
It takes in the name of a Swift method
and produces the Objective-C name for that method.
You don't have to care what that Objective-C name is.
The compiler will get it right.
And the great thing about this, of course,
is that Swift makes sure that that method exists.
Makes sure it's exposed to Objective-C,
and computes the correct name.
And of course, this is safe against refactoring.
Works with code completion.
So it's a much nicer development experience.
That means you don't have to worry
about the Objective-C names.
In Swift 3 we've extended this so you can also refer to getters
and setters of properties.
So we round out the set
of Objective-C method names you can actually compute.
So this is very easy to use.
You just pass in the argument label setter or getter
to get the setter or the getter respectively.
And then refer to an Objective-C property.
And of course, the compiler will validate
that that property exists, that it's exposed to Objective-C
and get the right Objective-C name for it.
Now, selectors aren't the only sort
of stringly type thing we have when talking
about Objective-C method names.
We also have Key Paths, which are notoriously hard
to get right when writing these things
as string literals with no validation.
And so, in Swift 3 we're also introducing #keyPath.
#keyPath does exactly what you'd expect.
You get to refer to a dotted sequence of property accesses.
Compiler validates that these are actually Objective-C
properties, gets the right names.
And then produces the string that we pass
down into the frameworks.
And so between #selector and #keyPath,
you can essentially not worry about the Objective-C names.
You just write everything in terms of the Swift names
and you stay in that set of names.
You don't have to straddle the boundary.
Now, there are cases where you do need to think
about what the Objective-C names are.
You may have a mixed project with Objective-C code in it
that needs to refer to the names in your Swift code.
And names like this handleDragWithSender
for just don't feel right when they're in Objective-C.
So for these cases, you can use the @objc attribute.
And in parentheses put the exact Objective-C name that you want.
And that will be reflected in your generated headers and all
of the metadata and everything else so you get specific control
over the Objective-C names, but no other part
of your Swift code actually has to care about this.
And of course, this @objc with a name works for properties,
it works for methods, classes, protocols.
Anything that can be exposed to Objective-C from Swift,
you can control the name here.
So you get nice Objective-C APIs for your Swift code.
Okay. There's a lot of change coming with Swift 3.
The Swift language itself abstracts away the need to worry
about the Objective-C names,
and yet it gives you the control you need for those times
when you do care about the Objective-C names.
The tools are here to help you.
So the Swift 3 migrator is going to Swift 2 code and migrate it
to the Swift 3 names and the Swift 3 syntax.
It's a lot of change.
But these tools will help you get over the hump
and get working with Swift 3.
Now, the Swift 3 migrator is a great tool.
But it can't migrate your muscle memory.
Certainly can't migrate all that code you copy
and paste from stack overflow.
So, the Swift compiler's also here to help you.
The Swift compiler, it knows the Swift 2 names of all
of these APIs as well as the Swift 3 names.
So if you write or paste in some code from Swift 2,
it'll recognize the old API names and give you diagnostics
with Fix-its to update your code so you can get moving faster.
Additionally, we've put in near miss detection
when you're implementing optional protocol methods.
And so this is great when you're implementing a delegate.
You make some minor mistake in the name
of that delegate method you want to implement.
Now you'll get a warning with a Fix-it to fix up the names
so you can be sure that your method will be called properly.
Now I'd like to turn things over to my colleague Michael,
who's going to talk about the mapping of C
and Objective-C APIs into Swift.
So that's a lot about Swift.
But what if you're an Objective-C developer
or are working with a mixed project?
All of your Objective-C APIs are available in Swift.
They always have been.
But as Doug explained, they were designed
for a different language.
They are increasingly starting
to feel a little bit foreign in Swift.
So today I'm going to show you how you can take control
of the situation and give your Swift users the APIs
I'm going to start with a couple Objective-C APIs
as they were imported into Swift 2.
Here we have two methods; saveToURL, forSaveOperation
But these don't really express the API Design Guidelines
that Doug outlined.
There's a lot of redundant type information.
We're not making effective use of the first parameter labels,
first argument labels.
So I'm going to start with what you get for free automatically
in the Swift 3 compiler.
Swift 3 has improvements to how Objective-C APIs are imported.
The Swift compiler will inspect method names
and use grammatical cues in order
to infer first parameter labels.
The Swift compiler will inspect names in order
to eliminate redundant type information.
The compiler can even infer default arguments
for common Objective-C idioms such as completion handlers.
Or option sets.
And also, there are new value types
such as URL that bridge to NSURL.
So when we import, we just import it directly.
To find out more about these value types, visit,
What's New in Foundation for Swift later today.
So, automatic inference is great and all,
but fundamentally it's driven by heuristics.
The compiler, it can't read your mind.
It doesn't know your intent.
And every now and then you want to specify your own name.
So we've extended NS Swift Name.
Now, NS Swift Name has been around since Swift 2.
But in Swift 3 we support full compound naming.
A compound name is a base name plus the argument labels.
So in this case, we have two methods.
They're performing semantically very similar operations.
But they differ basically in how they treat their argument.
And so we import them with the same base name constraints,
but we say we want it equal to this anchor or greater than
or equal to this anchor.
Now, method names will get you a long way towards a Swifty API,
but this doesn't quite go far enough.
Here I have some simple code that's creating a standard
But if you look at this, this doesn't really feel very Swifty,
which is a plain string global variable.
Plain string global variables,
that's not really how we do Swift.
This is what we jokingly refer to as stringly-typed API.
And the fact that this API takes a string,
that kind of allows simple errors.
And yes, I know this bug is shallow
and a developer would catch it right away.
But the fact that a user of this API has to remember what it is
and it's not a valid string to use here,
that's an unnecessary cognitive burden.
So, why is this API like this?
Well, we all know why this API is like this.
It came from Objective-C.
But the fact that this API came from Objective-C,
that's an implementation detail.
And that implementation detail is leaking out.
And at Apple, we're not big fans of leaks.
To figure out what's going wrong,
let's see how this Objective-C API is mapping into Swift.
Our global variable comes in as a global variable, of course.
But other than the name of this global variable,
nothing really tells you
that this a very specific string meant for a very specific API.
Now, we could try adding a typedef to try
and hint at our intent.
But a typedef, it's just a type alias.
It's a new name for an old type.
And so that doesn't really fix the problem here.
So, how will this API look if we were going
to design this fresh in Swift 3?
Well, we'd probably make a new wrapper type around string
to get some strong typing.
And these global variables, well,
those would instead be static properties.
So in Swift 3 we introduced a new attribute just
for this use case.
You can access this attribute
through NS Extensible String Enum when you wish
to tell the Swift compiler
to make a new wrapper type around your string.
You can just add this to your typedef.
And the importer will create you the new type around this.
And any global variables of this type will get imported
automatically as static properties of this type.
Now, we chose a struct here because this is extensible.
That is, other modules may want to define their own.
And if they do, they will also be imported as static properties
on an extension of this struct.
Now, behind the scenes the Swift compiler will map this directly
to the underlying stored value,
meaning that there's no extra overhead or boxing
or intermediaries involved.
So, let's focus on the use site.
Because good API design is always focused on the use site.
Before and after.
And because the type context is clearer,
we can even just say .gregorian.
I'll kick it off by starting myself next time.
Also, in Swift 3 NSCalendar, it's now just known as Calendar.
This is a little fix up.
So, we have method names and we have types.
What else do we have?
Well, we have an elephant.
That is, we have an elephant in the room.
And we've been pretending not to notice it.
But it's always been there.
And it's C.
Now, with Objective-C, the APIs were already object-oriented,
so when we import them we just change a few strings,
add a few types.
It's relatively straightforward.
But what about C?
I'm going to focus on Core Graphics.
Now, Core Graphics is a very popular API that's used
by pretty much every Swift app out there.
It is a powerful API.
But it looks and it feels like C.
Let's start with some code.
I have two functions here.
The first one transforms a --
takes a transform and rotates it about a given offset.
And the second function traces a path in red.
Now, neither of these functions are too complicated,
and the details don't matter.
But I just want to look at how does this look?
How does this feel?
Go ahead and take a moment.
So, if you notice, this code is completely filled
with global variables and global functions.
And we don't really like global functions, of course.
Or global variables, of course.
So, how could we take an API like this
and make it look Swifty?
How can we make it feel Swifty?
Well, for that, we revisit our friend NS Swift Name.
You can use NS Swift Name in order
to import globals as members of types.
Let me start with global variables
to show you what I mean.
Here at the top I have this C definition.
Below that the generated Swift interface.
And underneath that the Swift use site.
And we will be focusing on the Swift use site
and improving the Swift use site.
So we add NS Swift Name and we use typename.membername in order
to tell the Swift compiler that kCGColorWhite should be imported
as the static property white on CGColor.
And of course, the Swift use site can now use the properly
And of course, if the type context is clear,
users can even omit the CGColor.
Now Core Graphics has a lot of different global functions
to create all different kinds of CG Affine Transforms.
as CGAffineTransformMakeRotation on all of these.
But in Swift we prefer Initializer.
So we use TypeName.Init and provide argument labels in order
to tell the Swift compiler
that this should really just be an initializer.
And we use argument labels in order
to clarify the roles of the parameter.
You can also import as an instance member.
Use the special argument label self in order
to tell the Swift compiler what argument
to plug the reference to self into.
And so now CGContextFillPath is now just the method fill path.
And of course, the Swift use site,
it just calls it like a method.
And the compiler will take what's on the left of the dot
and plug it into the appropriate parameter position as denoted
by the special argument label self.
We can get more complicated.
You can prefix a Swift name with getter or setter in order
to tell the compiler to import this function
as a computed property getter or setter.
ArtistSetName are now just the getters and setters
for the computed property Artist.
Let's focus in the use site
because good API design is always focused on the use site.
Before, we would use a global function
to remember the former name of an artist
and a different global function to set a new name.
But now, our users can use the computed property directly.
In all cases, this is a zero cost overhead.
That is, when the compiler sees myArtist.Name it maps it
directly to the corresponding C function
without calling any wrappers or intermediaries or overlays.
You can also use NS Swift Name in order to nest types.
Remember earlier when we created a new calendar identifier type?
Well, you can use typeName.
-- well member name --
nest a type name in order to nest a type.
So in this case we get Calendar.Identifier.
Now, we love the new NS Swift Name.
We love it so much that we went absolutely, completely bananas.
[ Laughter & Applause ]
Don't clap for this.
And we applied it to over 600 APIs
in Core Graphics alone, 600.
Now you can clap.
That's a lot of bananas.
So, let's revisit the code from before.
Before, our global variable,
which is painfully global, is now a member.
And because the type context is clearer,
we can even omit the type name.
Our global functions are now methods.
Actually, now that I look at this,
I think this code can even simpler.
We don't need that extra variable result.
And so now this reads --
And so now this reads nice, natural and Swifty.
We take a transform.
We translate it.
We rotate it.
And we translate it back.
CGColorCreateGenericRGB as well as all of the other many,
many different ways to create colors,
these are now initializers with argument labels.
And of course -- hold your applause --
and of course CGContextAddPath, ContextPath and all
of the other crazy redundant stuff, they're now methods.
We hope you enjoy these new APIs.
So, to summarize, first we presented the new API Design
Guidelines in Swift.
Good API design is always focused on the use site.
Second, we looked at the Grand Renaming.
This is also known as, "Oh, no!
But don't panic.
The names are better.
The code is clearer.
And you have the tools to migrate.
And last, we looked at the new functionality
in the Swift compiler so that you can have your own
For more information, visit the page for this site
at developer.apple.com and check out Swift.org, the homepage
of the open source Swift project where you can see all
of the Swift evolution.
I also showed you Core Graphics.
But Grand Central Dispatch has had its own Great Renaming using
many of these same techniques I presented today.
So, Friday, check out concurrent programming
with Grand Central Dispatch in Swift 3.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.