The Swift language is always evolving. Bugs are being fixed, new proposals are implemented, etc. It'd be great if we could try out these features out as they're being implemented, without having to wait for official releases.
Today we'll take a look at how to download, install, and try out the latest Swift Toolchain in Xcode. Let's get started!
We'll begin by heading to https://swift.org/download/ and looking for the "Snapshots" section. Here we can also find many other preview releases, etc.
Click "Xcode" to download an installer:
We'll run open the installer, and complete its steps.
We can now open Xcode and select our new Toolchain.
We can also manage Toolchains in Xcode's preferences:
With our new Toolchain selected, all builds will use it, neat!
Getting involved with Swift's development is a great way to stay informed on where things are headed. We'll look at getting even more involved in future Bites!
We've covered GCD a few times back in Bites #85 & #35. This year, GCD is getting a huge overhaul that brings it into the modern world of Swift. Today we'll take a look at what's changed, let's dive in.
TLDR: Grand Central Dispatch now has a richly typedSwift 3 API.
Here we create a new queue, and enqueue some image processing work on it. Then, we do the same thing, but back on the main queue, enqueueing the work of setting resized image on our imageView there.
That's just the beginning. Here's a few more examples of how to use the new "swifty" GCD:
We've been able to watch Swift 3 materialize through the Swift Evolutionmailing list throughout the year, and with WWDC 2016 behind us, we have a pretty clear picture of what Swift 3 will be.
Today we'll start taking a look at what's new and changed in this release, and how it can help us build our apps. First up is the "Great Rename", Let's begin.
Swift Protocols are awesome. Understanding how they can (or should) fit into our code can be tricky. Today we'll take a baby step into the world of protocols with a simple, but "real" example and try to illustrate the upsides. Let's get started.
We're going to be fancy and abstract away some of our layout code. So we'll create a little struct to hold some layout settings like this:
See? Fancy. This is great if we want to specify each individual combination each time, but it'd be nice if we could define some sort of "pre-canned" layouts that we could use by name. Sounds like a great job for a Swift Enum.
Lovely, this will be handy. How are we going to wire all this together though? Simple, we'll make a Protocol that's only responsibility is to convert itself to a LayoutSettings.
Making our CannedLayoutEnum adopt our new Protocol is a bit more involved, but really just means switch-ing over self and return the proper combination of settings for each case.
Swift Enums are super handy. With associated values, they can be used in some quite interesting ways. Today we'll check out a couple. These aren't working examples, but might spark some ideas. Let's take a look.
Enums with Extensions
Keeping colors in one place is a great way to ensure consistency in a project.
This one is a little crazy (but fun!). Imagine we had our own custom system for laying out views in our app. We could not only describe that system perfectly with enums, we could even add a little more dynamic spice to the mix by making one of the associated values of our enum a closure. Neat!
When Swift debuted, we said goodbye to using #pragma pre-processor definitions to organize our code. Don't worry, Xcode still has our backs. We can use a few different "special" comments in our code and Xcode will pick up on them and display them in its jump bar:
The extra dash character in the name of our MARK gets us those sweet separators in the source navigator dropdown.
Xcode also supports a similar bit of functionality for TODO and FIXME comments. They'll show up in bold in the same dropdown.
As a bonus, we can use a little regex magic to get Xcode to generate build warnings for TODO and FIXMEs. We'll just add a new Run Script build phase to our project that contains:
The guard statement was added to Swift in its 2.0 release. It can dramatically increase the readability and clarity of the conditional checks in our code.
We can think of the guardstatement like a sort of inverted ifstatement. We essentially say: "this thing must be true otherwise we're bailing out!". Here's a fairly full-featured example:
Here we're ensuring that we have a fuelCell using optional unwrapping, then using pattern matching to make sure that our (now unwrapped optional) fuel cell has enough fuel in it for us to launch. Right away we can start to see how much clarity this adds.
If either part of our condition fails, we use the else block to run some code then return from the function.
Also as a bonus, the variables we unwrapped in the guardstatement are now available, unwrapped, and in-scope for the rest of our function (anything below the guardstatement). Neat!
This allows the rest of our function to focus on the actual work being done, rather than checking for validity throughout. We can stack these up too, it's quite common to see multiple guardstatements at the top of a functions in Swift.
It's important to note that we aren't required to return at the end of a guard's else block. Imagine using guard in loops to continue, or in a function that throws to throw an error. Guard helps keep our code clean and readable. Happy guarding!
Today we'll continue looking at initialization in Swift with Designated Initializers. Let's get started.
Swift's initialization system is made up of what are essentially a set of rules. We'll step through them here. Let's start with a class.
The first rule of Designated Initializers is that we need one. All classes must define (or inherit) at least one.
Ok, we've added one designated and one convenience initializer. Not too shabby. Now, let's use this base class.
Uh oh, what's going on here? Turns out it's the next rule. We're writing the designated initializer for Peakachew. Designated initializers must call a designated initializer from their immediate superclass, not a convenience one like we tried to do here.
Well, we've fixed our first problem but we've hit the next rule. Designated initializers have to initialize all stored properties on their class before calling super.
Lastly, designated initializers must call their parent class's initializer before assigning a value to any properties they've inherited from it.
With that, we're done. We're now following all the rules:
Way back in Bite #1 (zomg!) we talked about initializing View Controllers in Swift. Swift'sinitfunctions are still a source of confusion for many newcomers. Today we'll look at a couple cases where Swiftsynthesizesinits for us.
Structs
Swift offers free "memberwise"initializers for Structs. This means that if we define a Struct, and opt not to define any initializers, one will be synthesized for us, under the hood, using the properties we've given to the Struct. If we add our own though, we lose the synthesized init, and become responsible for defining 100% for the Struct'sinits.
Classes can synthesize a default initfunction for us. Only one that accepts 0 parameters, though. We'll get this if we define a class, while assigning default values to all its properties:
classSpaceship{vartopSpeed=1000varcurrentSpeed=0}
letship=Spaceship()
There's plenty to cover about init'ing things in Swift. We'll take a look in future Bites. Oh, and happy 200thBite !
Most Swift developers are familiar with how great Swift is at integrating with Objective-C, but what about C itself? Today we'll look at how we can interact with C variables and pointers in Swift. Let's dive in.
First we create a regular Int value in Swift. Nothing special. Then, we'll pass it in to the withUnsafePointerfunction, along with a closure. Inside, we'll be passed in an UnsafePointer version of our original Int. We'll use the unsafeBitCastfunction to convert it into to a void pointer. Finally, we'll pass it in the C function. Whew!