Topics

Topics

Back in Bite #292 we looked at Sourcery and how we could use it to add handy properties like count to our Swift enums. Sourcery is still just as awesome but Swift 4.2 actually removed the need for using it in this... case. 🤭 Let's take a look.

We'll be adding to the list of cases in our enum frequently as new spaceships are added, and we'd like to display the number of spaceships in our app. We could extend our enum, adding a count property:

Topics

Topics

In Bites #316 and #317, we began looking at Swift's new Codable (Encodable & Decodable) protocols. Today we'll continue by learning more about how Swift Enums work can work with these protocols. Let's get started.

First off, lets try a basic example. Here's an enum:

enumSpaceshipKind{casetransportcasefreightercasefighter}

If we simply do this:

enumSpaceshipKind:Codable{

We'll get an error: Type 'SpaceshipKind' does not conform to protocol 'Decodable'.

We can get around this by making our enum a "raw" value type like a String:

enumSpaceshipKind:String,Codable{

Nice. Since Strings are Codable, this works great. Same goes for Int and other basic Codable types.

This is a fine solution for simple use cases, but things get a little (alright, a lot) more involved when one or more of our enum cases has associated values.

Here's an example:

publicenumContentKind:Codable{caseapp(String)casemovie(Int)}

If we compile now, we get that same does not conform... error.

Let's fix that by extending our enum. First, since we'll be taking on more of the encoding and decoding logic ourselves, we'll need our own Swift Error type to throw when things go wrong.

extensionContentKind{enumCodingError:Error{casedecoding(String)}

Then, we'll need to tell Swift the keys we'll be using to encode or decode our data. We'll use another enum for this, this one adopting the built-in CodingKeyprotocol:

Then we check for each of our two possible cases, configuring ourselves and returning if successful. Finally, if we didn't return successfully and reach the end, we throw one of those CodingErrors we defined earlier.

This time we grab the encoder's container up front, then simply switch on ourselves to see which value to encode.

Now our associated value enum can be encoded and decoded all we want. Nice!

Pro Tip: Writing all of this by hand can get extremely tedious for anything more than a few simple cases. Try something like Sourcery (Bites #292, #294, and #295) to generate this more boilerplate-ish Codable implementation.

Topics

Topics

Swift 4 has brought with it a ton of great improvements. Today we'll cover one of them, it's the new Codable protocol! Codable ships with Swift 4 as part of the Swift standard library and allows us to conform our own types to it to get encoding and decoding functionality "for free".

Encoding and decoding types has never been easier.

Let's dive in!

Before we begin lets back up a second and look at what we're trying to accomplish when it comes to encoding and decoding.

Essentially we want to take an instance of an object or struct and convert (or "encode") it into some other, (usually "machine-readable") format. Then, later, we want to be able to convert (or "decode") the information in that format back into our object or struct.

These days the most common format for encoding/decoding is JSON. It's supported just about everywhere and has the advantage of being both human and machine readable.

For this reason, we'll be discussing JSON in this Bite. It's important to note though, that Codable isn't specific to just JSON. It's built to support encoding and decoding into just about any format we can think of.

In the past, we might have used something like the JSONSerialization class in Foundation to do encode our types into JSON.

This works great, but the encoding input and decoding output was either a Dictionary<String: Any>, or an Array of them. Then we'd need to manually convert to/from our "real" types.

Topics

Topics

Today we're going to begin looking at the lazy keyword in Swift. It describes some functionality in the language for what Apple calls " just-in-time calculation" of work.

This is great for times when we have expensive work to perform, or maybe the work is just some ugly complex code we'd like to tuck away. Perhaps we simply want to better compartmentalize the bits of our code that initialize UI elements, the use cases are plenty.

Today we'll start with Lazy Variables. Let's dive in!

Say we have a View Controller with a titleLabel. Pretty old school standard stuff.

We need to create the titleLabel, save it to a property, configure some stuff about it, then add it into the view heirarchy.

We want this work to be done after the view is loaded, and not when the view controller is first created, so we are forced to put it in viewDidLoad.

Additionally, we're forced to use a UILabel! force-unwrapped type on our titleLabel property to make the compiler happy.

Note: We have to use var instead of let when defining lazy properties like this. Our property might not (likely won't) have an initial value until after the instance of our view controller is created and its view is loaded. This completely breaks the rules of lets (constants).

That's all for now, in future Bites we'll look at other lazy behaviors in Swift!

Topics

Topics

Swift Protocols are great. They allow us to express the idea of expecting a set of functionality, without needing to expect a specific concrete type. Today we'll look at creating a Protocol to make working with colors in our apps a bit more flexible. Let's dive in. 🏊

We'll start by creating a new Protocol, giving it a conventional name, and require just one read-only property from our conforming types. This property will always return a UIColor.

publicprotocolColorConvertible{varcolorValue:UIColor{get}}

Now, let's try this new Protocol out by creating an enum that represents the different colors we use in our app:

lethv=SpaceshipNameHeaderView()// works!hv.nameTextColor=UIColor.black// works just as well!hv.nameTextColor=SpaceshipsColors.aluminum

Swift Protocols can help us write code that is both expressive and quite flexible. They can take a while to get a handle on, but understanding them is a key step towards unlocking the full power of Swift.

Topics

Topics

We’ve covered a little about working with C APIs in Swift back in Bite #189. Swift 3 brings us a ton of new goodies and improvements around C APIs, let's dive right in and take a look.

Swift 3 improves upon a number of areas of C API usage in Swift, but the biggest one is importing functions as members. Essentially, taking free floating C functions, renaming them, and shoving them onto a type as functions.

One place where this behavior really shines is when using CoreGraphics to draw into a view.

The first is a bit of automatic inference. Many APIs (like CoreGraphics and CoreFoundation) use consistent (albeit often verbose) naming schemes for their functions. The Swift compiler can now exploit this to (for example) detect functions returning a specific type and convert them into init functions in Swift.

Note how enum cases are used interchangeable both with and without dots.

In Swift 3, this has been cleaned up and dots are now required when using this shorthand style to access enum cases. There's one exception and that is static functions on enums, which still infer self: