Going Server-side with Swift Open Source

Session 415 WWDC 2016

While the Swift language makes it easy to write software that is incredibly fast and safe by design, Swift being open source means you can use it on an even broader range of platforms, from mobile devices to the desktop and in the cloud. Come for an overview of available projects at Swift.org and examples of the community in action.

[ Music ]

[ Applause ]

Welcome.

My name's Philippe Hausler, and I work at Apple on Foundation, and today we're going to talk about Swift On Servers.

We'll go over why Server-Side Swift is compelling, how all the pieces fit together, what you get out of box, what you don't, some real-world examples of Swift running on the server, and, most importantly, what you can do to contribute to making Swift On Servers awesome.

Modern application development isn't just building for one platform.

It's an ecosystem.

You'd be hard pressed to find an application that doesn't have some sort of server-side component, be it from analytics, real-time communications, or shared state being stored in the Cloud, servers are an integral component in making rich and compelling apps.

Now building the next great thing, often there are contact switches that have to be made.

You end up humming along, writing your application, and the next thing you know you're writing in a different language.

This can cause downtime and repeated implementations, and we all know how much we dislike repeating ourselves in code.

But Swift running on the server has the potential not to just provide a seamless development experience but also a richer and more compelling user experience, too.

By sharing the right parts of your code base, time can be saved not just for writing it but also testing and QA.

But it's not just the language.

It's the API's.

It's often hard to disambiguate the architecture of the API's from the construction of the language with constructs like strings, arrays, dictionaries, concurrency.

They often become a core set of libraries expressing that language.

And with that, it brings us to the architecture of Swift, not just on the server, but how Swift fits together on all platforms.

As in early design consideration, Swift wouldn't just be a Darwin-only language.

It can by its very nature run on many platforms, and with the community's help, that goal has just been started to be realized with platforms, support to platforms like [inaudible] SD, targets like Raspberry Pi, and even things like Windows and Android.

Some pretty exciting stuff.

On all of these, Swift relies on the system libraries.

Building on top of that, you have the standard library.

It provides some of those fundamental basic building blocks and data structures.

On Darwin, we have an addendum called the overlay that aids system frameworks to interface better in Swift, but since there is no foundation or dispatch shipped with Linux, a portable interface was established to fill in those fundamental pieces.

We started off with an outline of what needed to be there and a few initial implementations, and with the community, we have added many of those basic items that are needed for any modern development.

So when you application comes into the mix, you can see that all of the pieces just fit together the same way on both platforms.

With Swift built in this manner, as a developer, you can pick the right pieces out of your application to build for the server and use familiar constructs that you're used to using.

Swift.org is the central place for getting the most recent version of Swift.

Signing up for the mailing list, getting links for the GitHub repositories or continuous integration builds, or a great place to read the documentation on the most recent developments in Swift.

It is the place for the Swift tool chain.

So what comes in this toolbox?

Out of the box, you get support for building on both Linux and Mac.

So you can develop on your Mac and deploy to the Linux servers.

There are continuous integration servers to ensure that the changes that are made to the language and API's happen and continuously integrate so that everything works as expected.

You have the standard library.

That gives you those basic building blocks, protocols, structures, and types that you would use in building any Swift application, but you also get Foundation, Dispatch, and XCTest as projects within the, the Swift tool chain.

These give you a cross section of portable API's that can keep your code nearly the same as you build across multiple platforms.

But you also get a suite of tools for compiling, packaging, and debugging Swift apps as well as the Swift Rebel to complete, try out some of those new features, and you get all of these things on both platforms.

Now there are a few things that are not included.

There was a design, a design decision that was made that some things just didn't make sense in a cross platform nature, or that they were better, better served to let developers build their own solutions since they're highly specialized.

New platforms are not just code.

They are continuous integration and verification, and the champions reporting to new platforms usually know the best to implement those.

User interface is a very platform-specific thing.

On iOS, you have UIKit.

On Mac, you have AppKit, and even though that they share a lot of similarities, there have to be two different things because they're solving different problems.

For that matter, UI can be web templates, and sometimes the user in user interface isn't a person, and, instead, it's another service connection that is routing a service protocol.

These are all clearly something that are very, very specialized.

Now deploying your applications to the server in and of itself is a specialized task.

This way you can pick the right service that fits your requirements, your budget, your scale, and, of course, your application.

This shouldn't have to be tied to a specific track in Swift.

Running on the server, you can have multiple applications running with multiple versions of Swift.

It's amazing to see the enthusiasm to create an open and sharing community, and these are just a few of the great things, great opportunities to enrich the Swift ecosystem.

There have already been some great efforts put forth in all of these areas and more, and our fellow contributors over at IBM have been making some really pretty neat things.

We've gone over some abstract overviews.

So let's dive a little bit deeper.

So here to present some real-world examples of how they're, they are getting involved in Swift at IBM is John Ponzo and Patrick Bohrer.

[ Applause ]

Thank you, Philippe.

Hi. My name is John Ponzo.

I'm the Technical Leader for Mobile Cloud Development at IBM, and I'm thrilled to be part of WWDC today.

We at IBM are very excited about Swift community and being part of the open source, and we see great potential for the language.

For those unfamiliar, let me tell you a little bit about IBM and our involvement with Swift.

Apple and IBM announced our partnership focusing on enterprise apps and solutions in 2014.

And, subsequently, IBM became one of the first, early adopters of Swift when it was announced here at WWDC just two years ago.

Since that time, we've created over 100 enterprise applications, building those apps and solutions entirely in Swift, and we also have one of the highest concentrations of Swift developers at IBM building these apps today.

Our experience building these enterprise apps and solutions consistently points to the importance of the backend, enabling a great experience.

As developers, we know how important it is to have a backend, to enable a great mobile experience.

We also know it's important for us to quickly and safely deploy the right code to the right place, and that's why we're so excited to help bring Swift to the server.

We appreciate the wealth of activity around Swift.org community, ranging from the mailing list to code contributions and new open source projects that are forming.

I'd like to highlight some of the things that we're doing at IBM to help the open source community bring Swift to the server.

First, I'll tell you about community enablements and tell you about our Swift Sandbox and Swift package catalog services that we created to help developers to easily learn, discover, and share Swift assets.

Next, we are motivated by consistent developer experience that links the client and server, and towards that end, we created the Kitura web framework that's helping to motivate and prioritize our contributions into the core libraries of libdispatch and foundation.

And next, Cloud enablement is an important part of the development process, and we are driven to make it even easier and fun to deploy Swift to the Cloud.

Through early support in the IBM Cloud for Swift runtime and the introduction of Xcode companion applications to help deploy that code to the Cloud.

When Swift.org was released in December, one of the first things that we wanted to do was to help grow the developer ecosystem.

We saw the value of the language, and we wanted to quickly introduce it to other developers.

We created the Sandbox that allowed, it allows developers to easily run and test code on Linux.

The Sandbox runs in a browser, and with it, you can easily start writing your Swift code, save that code, and see the execution on the server.

Since we released the Sandbox, we've added a number of enhancements based on community feedback and requests.

The Sandbox currently supports a mobile UI, multiple UI themes, autosaving of code, and the ability to select multiple Swift runtimes.

Also, to help developers to share questions and solutions around Swift, we added code snapshot support that's backed by a persistent URL.

You could use this to share code across mailing lists and developer forums like stackoverflow.com.

Thank you, and we've seen over 1.5 million executions in the Sandbox since we launched in December, and this is over 200 percent increase since just this February.

And the Sandbox is unlocking access to Swift from other platforms.

In fact, we're seeing steady growth and interest in executions and sessions coming from other operating systems.

We're very pleased to see this, and we'd like to see Swift grow even more.

We're also seeing usage from around the globe.

Developers using the Sandbox to learn Swift and collaborate.

Our intent is to continue to support the Sandbox to help grow the community.

A vibrant package ecosystem is critical to any language.

While the Swift Package Manager specification is an early technology, everything that we're doing on the server is based on the creation and composition of Swift-based packages.

Because of this, we found the need to both discover and to publish our own packages.

So we created the Swift package catalog to help with this goal.

We continue to update the package catalog as the Swift Package Manager specification evolves.

And today we have over 1,500 Swift Package Manager compliant packages on the catalog, and this is up 400 percent since February.

Next, when we start thinking about servers, a foundational requirement for any server language is the ability to stand up web interfaces.

While web frameworks are responsible for listening on ports and routing code to the appropriate logic, we thought it was very important for that logic to be as consistent as possible with the client-side programming model.

And towards that end, we created the Kitura framework.

We open source Kitura in February.

It's a modular package based web framework.

It leverages libdispatch and Foundation for concurrency and utility library support.

It's also driving IBM's contributions to Swift.org.

We're using Kitura to build our service-side applications, and we're working with the community and have a number of committers outside of IBM working on Kitura actively.

It's an important part of what we're doing to server enable Swift.

We're also optimizing our Cloud for Swift-based workloads.

And I'm pleased to announce our latest updates to our Cloud foundry-based build packs for Bluemix that includes everything that you need to rapidly deploy your Kitura-based applications to the IBM Cloud.

These build packs include the very latest Swift runtimes, core libraries, and dependent C libraries.

They're needed to deploy Kitura to the Cloud.

But in addition, development is, is key, and we're pleased to announce IBM Cloud tools for Swift, a Mac companion application to allow you to easily build end-to-end applications in Swift.

The tool helps you to quickly and easily connect your client-side apps with service-side Swift that runs in the IBM Cloud.

Just continue developing your projects, your client and service-side projects in Xcode, and use this tool to link those projects and deploy your code to the server.

Now with that introduction, I'd like to welcome my colleague, Patrick Bohrer, up to the stage who will show you service-side Swift in action.

[ Applause ]

Thanks, John.

I'm Pat Bohrer.

I'm the Technical Lead for a lot of the fun stuff we're doing at IBM around Swift.

So we're thrilled to be here at WWDC, and I'm going to be leading what I call the fun and exciting part of the session.

It's fun because I'm going to be doing some live coding of Swift on the server, and it's exciting because both of my demos are dependent on a working network to the Cloud.

So wish me luck.

So as we talk about server-side Swift, it can mean a lot of things to a lot of people, but for this audience and for this session, we're really talking about web services.

So what are web services?

In a very simple level, they're programs that are off running in a machine.

They're listening.

They're listening for incoming requests.

They're responsible for routing those requests to some server-side logic, and return and response.

And now as far as what's out there, it could be a browser, it could be another application.

Who knows?

It could be another service, but as simple level, that's what it is.

So to get started, that sounds simple enough.

Let's go ahead and jump in, and do a live demo of that.

OK. So as I mentioned, oftentimes these web services are running on Linux, and we've heard about Swift running on Linux.

So let's go ahead and do our work for this first demo on Linus itself.

Let's go ahead and do that.

So here we have Linux and running.

Make sure I'm not lying.

So let's go ahead and create a directory to do some, to play around.

So we'll very creatively create a play directory.

You can see we have nothing in here.

And now we'll use the Swift Package Manager.

So every, as John mentioned, everything we're doing on server-side is based on packages.

And so we're going to use, this is a version of the Swift Package Manager that, for those watching later, this syntax changes, but for the version that we're using today, it has an initialization step.

And so if we issue this command, we can see that it's created a few files.

So based on the structure and the Package.Swift file, the Swift Package Manager knows how to build your application.

And so as you can see here, we have a Package.Swift, and it's created a Sources.main, and that's all we really need to build a Swift, a simple Swift package.

So with that said, let's go ahead and build this.

So we can issue Swift build, and that was easy enough.

And so it's created a .build/debug play executable.

So let's run that.

Ah. Hello world.

But we're building web services.

So let's get real.

OK. So here, this is what our Swift Package Manager has created for us.

So, again, it's best that we have a package based on our directory called Plays.

It's named our executed play, and so that's why that got named.

And we want to add one piece here, and that's a dependency on Kitura, and that's all we need to specify.

So now we will go to our main file.

Let's delete our old hello world, and let's add a bit of code here.

So what this code does is, again, old faithful.

We're pulling in Foundation.

We're also importing Kitura and a couple of Kitura support packages.

Here, we're specifying a router, as I mentioned, for incoming requests.

We have to route these requests somewhere.

And we're going to specify one route, right here, that is /hello.

So if any, if any requests come in, we'll run this code.

Simple enough.

We'll specify some response headers, and we'll send back a string saying hello world.

Now down here we specify what port we'll listen to, and it's the 8095, and we start listening on this port, and we specify our router as a delegate, and then we start the server.

So it's pretty simple.

Let's go ahead and save that.

Now we're going to build Kitura for the first time, and so we've added some pieces here.

As John mentioned, we're leveraging libdispatch and Foundation.

And so what it's doing is it's pulling down, the Swift Package Manager's pulling down everything we need.

So we wrote the code we care about, and the Swift Package Manager is pulling down Kitura, it's pulling down our networking, it's pulling down some system support, a logger, all the things that you'd need in a, in a web service, as well as the ability to listen on sockets and everything else.

And so each of these are discrete packages that are out on GitHub that you can pull in.

And it's compiled and built.

So now let's go ahead and run this executable again.

So we can see that it's now, it just says it's listing on port 8095.

So let's go ahead and take a look at that.

We'll bring up local host 8095 because it's running locally on our, on our Mac and Linux, and you can see we see a Kitura page.

So this basically, if we haven't defined the default route, it'll bring up this page and specify other ways to get started.

You can always override this, but for us all we've specified is hello.

[ Applause ]

And so, of course, the first thing you have to do is say hello world, right.

So the first step, but, really, when you, when you think about it, let's go back, we'll do a bit more here.

Let's go back and edit our main file.

We have a lot of that we can use here.

So we have Foundation, and we also have the ability to generate JSON.

So add a little helper code here to help us create a JSON string.

We'll also add a new route called today.

So now, again, here's a new route that if anything comes in, saying /today, it'll do, it'll leverage Foundation to go get the current date.

We'll go ahead and create an NSDateFormatter just like we would on the client.

We'll use that DateFormatter to create a date string, a time string, and now we'll get into the meat of our response, and so here we'll create a payload which, is a dictionary, and now because in the Internet, you know, it's all JSON.

So we specify message is hello world, our date is our date, our time is our time, and, again, we convert that into a string, and that's what we send back this time.

So let's take, see what that works.

Let's go ahead and rebuild.

Much faster.

All the packages are here.

So that's good.

So, again, we'll run this again.

You can see we're listing on 8095.

We'll reload and see we're still responding hello world on hello, and now let's look at today.

And there we go.

We have our JSON payload.

And now, again, every time someone comes in here, it's, it's executing that code, and it's return and response.

So that's at a very simple level how to get started.

OK. My wife said to take off the glasses [inaudible].

So that was pretty fun, but now let's make this a little bit more interesting.

So as we go through, first I'd like to introduce you to a really interesting sample that we've made available to this community, and it's called BluePic.

So BluePic is a sample photosharing application that's social.

It has a rich client interface, a very beautiful interface that we've built and provided as part of this overall sample.

It also has a really interesting backend.

That is, a Swift server backend, pure Swift using Kitura, running the IBM Cloud, and it's also leveraging some interesting services that I'll mentioned like Watson or ObjectStore, [inaudible] SQL databases, all that good stuff.

And if you're, if you're ready to dive deeper, it even has some use of IBM's brand-new event driven programming model called OpenWhisk that also supports Swift.

So, again, this package has a lot going on, and it's available now on GitHub for those who want to get started.

So before we dive into demo mode here, I want to spend a little bit of time talking about the design pattern here.

So unlike before where we had a web browser as the client-side, we, of course, have an iOS application.

It has our model view controllers, and you can see it also has a networking interface with requests and responses.

And it's talking to our Swift middle tier, which is similar to what we just did.

It's just a little bit more interesting, but, again, accepting an incoming route request, routing those to some logic.

And then, finally, we also have another piece where we have some interesting services, which we'll get into in a bit, for holding all of this data of our application.

So, again, just to dig a little bit deeper.

So we have the client-side.

It's responsible.

It's very user specific view driven for rendering some nice, you know, interactions with the, with the user of the application, and then we have the midtier.

The midtier is responding to all of the clients with the things they have, but it's also doing some really interesting things.

So as photos get submitted into the midtier, it can, it'll accept those photos.

It'll save them into ObjectStore.

It'll create some metadata around them, but it'll do a few other things that are pretty interesting.

So it will take those photos, and submit it over to Watson's Vision Insights and extract just tags about the photos.

Is it mountains and lakes and all that good stuff, right.

So it's kind of adding the special sauce to our application from the midtier.

It will also notice where the photo is taken and call Watson's Weather Insights, and pull down information.

What was the weather like at that location?

So we're adding all of that.

So, again, instead of making all these round trips from the client-side, we're making it from the server-side, which is always on, always available to go ahead and do our service composition there.

And the fact that this is end-to-end Swift lets us deploy the right code to the right place.

So now here is BluePic off running in the wild.

It's running on a device.

It's connecting into the, you know, the Cloud.

The application server, which is then talking to all the different services I mentioned, and that's great.

Now if something comes up, and we have to debug or develop this application further, what do we do?

Right. Well, as iOS developers, we know exactly what to do.

We pull down the source for that application onto our Mac, we load it all up into Xcode, and we're good to go, right.

We can debug this.

We can debug the application.

You can even be calling out into the Cloud and making other requests.

So this is something we know how to do today, but now that this midtier is also running Swift, what do we do?

Right. You probably don't want to be using VI like I was on Linux.

But, again, we can do the same thing.

We can pull down the source code for our server-side code, again, onto our Mac, load it up in Xcode, and now we can also just do normal development and debug locally on our Mac.

So we're debugging and developing.

It's exciting.

So now our development world got a whole lot bigger, right.

So we actually control everything from end to end, from the client to the midtier, even to the services that we touch.

So we, we really are excited about this because we think it brings down that development cycle of, you know, as you're doing things on the client, and you want to add some capabilities on the backend, it's all in the world that you understand.

Towards that end, as developers ourselves, we thought we can go a little bit further.

So just like we've done with the package catalog and the Swift Sandbox, we created this application called IBM Cloud Tools for Swift as a Mac application to help us manage this bigger development world.

So we're really excited about it.

This application actually makes it possible for us to manage this entire stack end-to-end, and we, you know, there's a lot of things that we could do by hand, but why not have some tools to help you with this, right.

So we're excited to hear your feedback on this just like we have the Sandbox and the catalog.

And we'll keep, you know, we're just getting started with this application, and, again, as developers ourselves, we know what we want it to do.

We'll keep adding things, and we'll listen to this community as well, but we're really excited about the possibilities here.

So our goal is really to empower this community to keep creating great applications, and now powered by Swift on the server.

So now with all of that background, let's actually jump in and do some demos again.

Going to show you just how bright this future is with Swift.

OK. So first off, this is the IBM Cloud Tools for Swift.

If you want to get started, it presents you with an interface that's a nice rich interface, and for those wanting to get started with BluePic, it even has an ability to create a BluePic project to create just a Kitura project or to create an empty project.

Now the part that's interesting about this is not only is it doing a clone of these projects in bringing them down, it's also under the covers provisioning resources in the IBM Cloud to deploy that project when you're ready, and it will, in fact, when you create these, it will go ahead and deploy it because it knows it's a working example.

So, again, to get up and running quickly, it's a great way to start.

For us, we've already created a BluePic application here, and you can see we have a demo BluePic.

Very cleverly named.

And here you can see we have a client application, a binding between a client application and a Cloud runtime.

Both of these are in Swift.

Additionally, if we drill in, here to the server-side code, you can see it has a reference to where the code is locally on our, on my machine as well as a binding to where it goes into the Cloud as well as all of the services that is provisioned on behalf of this application.

So, again, I can manage all of this locally on my Mac.

As well as I can go ahead and launch with one click into Xcode to look at my client-side.

So here's the BluePic client-side application.

It is also created, let me zoom in here a little bit, this file.

It's a Bluemix.plist.

Knowing this development cycle, being able to run against your Cloud services locally versus remotely it's very easy to control this.

It'll either listen locally to 8090 or remotely out in Bluemix and pass in the, the credentials.

So, again, the thought here is to make this really simple.

So here we'll go ahead and run this, and so let's imagine that somebody's filed a bug report about the application.

So here's our application.

Again, it's got a nice pretty interface.

We can scroll through.

We can see some pictures.

If we click on these pictures, we can see there's more information.

So the name is nature of this one.

We can see who took it.

We can see, supposedly, this was in Austin, Texas, which we don't have mountains.

So. We can also see what the weather was like, and then thanks to Watson Insight, we see that there's a few tags here.

So this is interesting.

If I click on tags, I can see, OK, here's the, we have one photo that has a lake.

If I go back, let's click on mountain, and we can see there's a few photos that have mountains, and, again, all of this was done by integration on the backend.

We didn't have users having to tag this.

This was just auto extracted.

But we heard that there's some complaint about when I click cloudy skies.

So let's look at that.

So we click cloudy sky, and we don't see anything.

So we know what's going on here, and somehow the server's not returning the right results.

So now let's switch.

We want to go ahead and figure out, get to the bottom of this.

And so we'll go over here, and we'll click on our server-side code.

It will launch us and show us the directory where the server-side code is.

And if I go ahead and load that into a terminal, you can see a lot of the same files as I mentioned, we're doing Swift 3.0 on the server.

We have our Package.Swift.

We have our sources.

But, additionally, I went through and created an Xcode project of the server-side code.

So let's go ahead and open that.

So here's the code, and, again, here's a get handler for images.

So we know that when we want images, our image feed, we'll call this get on/images on our server.

So if we look at this, we want to go through and say, OK, well, somehow when we pass in a tag, we're not returning the right results.

So let's set a break point here, and we'll run our server.

And now we can see our server is listening locally on port 8090.

Now let's switch back.

So here we're going to have our client application say local is yes so that it will actually connect to our local server, and let's rerun the simulator.

By the way, I'm getting far too lucky with all this network connectivity.

So keep up whatever you're doing.

OK. So let's just scroll down to the file we had a little problems with.

Let's click on here.

Let's click on cloudy skies.

Ah, great.

Here, we hit a break point in the server.

[ Applause ]

So if we want to get a feel for what's happening here, and say we want to print tag.

And we can see, kind of hard to see that.

We can see that the string is coming in as cloudy percent 20 sky.

That's no good.

We don't want that.

So let's take a look at that.

We also know that we have Foundation here.

So what if we go ahead and use Foundation to clean this up a bit.

We'll remove the percent in coding.

Oh, this is now a variable instead of a [inaudible].

Let's go ahead and build this.

We'll run it again.

Rerun the server.

Let's go back to our application.

Oh. There we go.

Timed out waiting for us.

Let's go back.

Let's click cloudy sky again, and see if we fixed our problem.

Print to tag.

Ah, much better.

That's what we want.

So let's go ahead and turn off this break point and continue.

And we see we got our result.

[ Applause ]

So now additionally, since we've fixed this problem, I can go back into Cloud Tools for Swift, and I can do a redeploy of this state out to the server.

So it will start redeploying that code right away.

So, again, it's that simple to work with your client-side and your server-side and redeploy to the Cloud.

[ Applause ]

So I hope you really like these demos, and I got to tell you, I feel a tremendous amount of relief that everything worked.

So on behalf of IBM, John and I would just like to thank everyone for their time.

This is a really exciting time to be a Swift developer, and we invite you to join us and the broader community to join in and bring, to bring the power of Swift to the server.

And for more information about anything you've heard here, about what we're, what's cooking at IBM, we have our developer.IBM.com/Swift Dev Center that you can go to.

And with that, thanks again.

I'll hand it back to Philippe.

[ Applause ]

So as you can see, IBM has been doing some really awesome things with Swift.

They've not just been contributing some great code, but they've also been enriching the community with their vast experience building services and streamlining development flows.

Some of their work has been integral in making server-side Swift possible.

But you, too, can help make server-side Swift a reality, and there are a number of things that definitely you can contribute with.

Portions of Swift are not yet finished.

There's a lot of work to be done, and there are a few things that are not yet to be implemented, and unimplemented just means an opportunity to contribute.

There are number of easy ways that you can help pitch in.

The bug tracker even has a category for issues tagged as starter bugs, but code isn't just implementations.

Designing new API's and guidelines that will work well in Swift are something that are being worked on on a daily basis in the e-mail list.

Many of the discussions are working on the language itself, and coming from contributors like you.

And, of course, your packages, your applications are what going to make Swift on the server awesome.

And if you have any questions as for resources or links to what we've actually talked here today, we've got a, this session, we have everything culminated together, and there are number of other really awesome related sessions that I would highly suggest watching.

The API design guidelines can, goes over some of our thoughts behind actually the new naming within Swift 3, and I would highly suggest that you take a look at the What's New in Foundation for Swift.

All of the new value types and features that are being added are going to be available on the server as well.

Of course, performance is not just necessarily your local application.

We all, we need to be able to make sure that our servers are going to be responsive and quick.

So performance, all across the board, both on Linux and Mac is, by far, something to look into, and I would highly suggest to take a look at the new, new things in GCD that are being released with Swift 3.

And with that, thank you very much.

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