Active Filters: Techniques

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:

class Monster {
  var name: String

  init(name: String) {
    self.name = name
  }

  convenience init() {
    self.init(name: "Nameless Monster")
  }
}

class Peakachew : Monster {
  var shouldFollow: Bool

  init(shouldFollow: Bool) {
    self.shouldFollow = shouldFollow

    super.init(name: "Peakachew")
  }
}

Whew!

More on initializing in Swift next time!

Way back in Bite #1 (zomg!) we talked about initializing View Controllers in Swift. Swift's init functions are still a source of confusion for many newcomers. Today we'll look at a couple cases where Swift synthesizes inits 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's inits.

struct Spaceship {
  var name: String
}

let ship = Spaceship(name: "Outrider")

Default Initializers

Classes can synthesize a default init function 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:

class Spaceship {
  var topSpeed = 1000
  var currentSpeed = 0
}
let ship = Spaceship()

There's plenty to cover about init'ing things in Swift. We'll take a look in future Bites. Oh, and happy 200th Bite !

It happens to the best of us. We're going along, composing some UIViews in our app. We're styling them, configuring them, we can't wait to try them out. That's when we see it. A big, empty, unescapable void of nothingness right where our views should be! 😱

Today we'll look at some tips to solve a case of missing UIViews.

First, we should arm ourselves with tools to help inspect what's going on. Xcode's own View Debugger is a great place to start, and Reveal.app is a fantastic third-party solution.

Whether it's one of these tools, or simply writing some in-depth logging functions, our first step should be to look at both our view hierarchy and its layout for anything funky.

print(UIApplication.sharedApplication().keyWindow?
  .performSelector("recursiveDescription"))

We can use private functions like recursiveDescription to print out a handy tree-view of our views to Xcode's Console.

Most of these debugging sessions stop here, as the problem often involves a view not being in the correct place in the hierarchy, or Auto Layout has gone and done something wacky with our views' locations.

If we're still stuck though, here are some sanity checks we can perform:

  • Are any views hidden?
  • How about transparent? (0 alpha)
  • Is it masked via a maskLayer?
  • Does it have a CGRectZero frame?
  • Is the key UIWindow a weird size or in a weird place?

Try making each view a specific ugly color (the static .XColor() functions on UIColor work wonders here).

  • Is another view covering it up?
  • Is .clipsToBounds enabled and a strange frame/bounds is causing the view to be clipped?

If all else fails, comment out everything, and add it back one bit at a time until something fails.

Happy 🐞 hunting!

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.

Here's a few variables in C:

const int *someInt
int *anotherInt
struct Spaceship *spaceship

When referenced in Swift, these become:

UnsafePointer<Int>
UnsafeMutablePointer<Int>
COpaquePointer

What about those pesky void pointers in C?

void launchSpaceshipWithID(const void *spaceshipID);

Buckle up, for this we'll need to go unsafe...

Swift tries its best to keep us safe, so for something like void pointers, we'll need to jump through a few safety-defying hoops:

var sID = 31
withUnsafePointer(&sID) { (p: UnsafePointer<Int>) in
  let voidP = unsafeBitCast(p, UnsafePointer<Void>.self)
  launchSpaceshipWithID(voidP)
}

First we create a regular Int value in Swift. Nothing special. Then, we'll pass it in to the withUnsafePointer function, along with a closure. Inside, we'll be passed in an UnsafePointer version of our original Int. We'll use the unsafeBitCast function to convert it into to a void pointer. Finally, we'll pass it in the C function. Whew!

Topics

#184: More Swift Tricks 🎩

Topics

Today we'll continue our look at Swift tips and tricks. Let's dive in.

Nested Types

We'll begin with an organizational tip. We can nest our type declarations inside one another to group related definitions:

enum CostumeDepartment {
  case Day, Night

  struct Color { /* ... */ }
  struct Image { /* ... */ }
  struct Text { /* ... */ }

  func appLogoImage() -> Image { /* ... */ }
}

Swift's compiler is smart enough to take note of this nesting whenever ambiguity arises. This means we can use types nested inside multiple "container" types without any issues.

Even-lazier Lazy Definitions

We covered the lazy keyword in Bite #179. It turns out, we can be even lazier, and omit the extra closure altogether. (Still works the same).

lazy var backgroundView = SpecialBackgroundView()

Variadic Parameters

Objective-C supported these as well, but they were a bit of pain to work with there. In Swift, we simply add an ellipsis (...) to our function's definition, and we receive the arguments as a strongly-typed Swift** array**.

func sum(numbers: Int...) -> Int {  
  var total = 0
  for number in numbers { total += number }
  return total
}

...or if we wanted to write that function in an even Swiftier way:

func sum(numbers: Int...) -> Int { return numbers.reduce(0, combine: +) }

Topics

#180: More Swift Tricks 🎩

Topics

Today we'll continue our look at interesting Swift features. Let's begin.

Type Matching with β€˜is’

Try as we might, sometimes still we end up with an AnyObject or Any reference in our Swift code. We can ask if it is a given type or subtype using Swift's powerful pattern matching:

protocol Vehicle { }
struct Spaceship : Vehicle { }

let thing: Any = Spaceship()

if thing is Vehicle { print("let's move") }
else { print("can't move") }

Parsimonious Declarations

Hat tip to Erica Sadun for passing along this one. We can use a sort of Tuple-ish syntax to create a bunch of related references inline:

var (top, left, width, height) = (0.0, 0.0, 100.0, 50.0)
spaceship.width = width

Inline Closures

This technique has a few different applications, but one good example is capturing a value from a switch statement inline:

enum Theme {
  case Day, Night, Dusk, Dawn

  func apply() {
    // ...

    let backgroundColor: UIColor = {
      switch self {
        case Day: return UIColor.whiteColor()
        case Night: return UIColor.darkGrayColor()
      }
    }()

    // ... set backgroundColor on all UI elements
  }
}

Topics

#179: Swift Tricks: Properties 🎩

Topics

Today we'll look at a couple more tips for working in Swift. This time, we'll focus on Swift properties. Let's dive in.

Property Observers

In Objective-C, we'd likely use Key-Value Observing to "know" when the value of a property on one of our objects changes.

KVO still works great in Swift. In many cases, we might be able to get away with Swift's (much cleaner) property observers:

struct Spaceship {
  let name: String

  var currentSpeed: Int = 0 {
    willSet { print("About to change speed to \(newValue)") }
    didSet {
      if currentSpeed > oldValue {
        print("Increased speed to \(currentSpeed)")
      } else if currentSpeed < oldValue {
        print("Decreased speed to \(currentSpeed)")
      }
    }
  }
}

Lazy Properties

"Lazy" initialization is a great way to put off expensive work until some later time in our code. Back in Objective-C, if we wanted to "lazily" initialize a property, we might go override it's getter, and check if a private instance variable is nil or not, then populate it if it's not, then return it. Whew!

In Swift, we can forget all of this and accomplish the exact same with a simple new keyword:

lazy var couchPotatoes = [String]()

We can also use this technique to lazily init our UI elements, neat!

lazy var someLabel: UILabel = {
  let label = UILabel()
  label.translatesAutoresizingMaskIntoConstraints = false
  label.font = UIFont(name: "AvenirNext", size: 20)
  return label
}()

Topics

#175: More Swift Tricks 🎩

Topics

Today we'll continue our look at interesting Swift features. Let's begin.

Multiple/Chained Optional Unwrapping

This is great when we've got multiple optionals to unwrap. We can even use unwrapped references from earlier in the statement in later parts of the statement. Neat!

if let URL = NSURL(string: someURL),
   let data = NSData(contentsOfURL: URL),
   let ship = Spaceship(data: data) {
    // use 'ship'
}

Multiple Initialization

We can initialize multiple references in one statement (and one line). This works for when using both let and var:

let ship1 = "Tantive IV", ship2 = "Ghost", ship3 = "Outrider"

Slicker Array Inits

We can simplify Array (and Dictionary) init statements like this:

let spaceships: [Spaceship] = []

To this:

let spaceships = [Spaceship]()

Semicolons: Gone but not forgotten!

Removing the need for trailing semicolons was one of Swift's most welcome features. However, they actually are present in Swift, and can serve a useful purpose. They'll let us write multiple statements on one line. This works great (for example) in guard statements:

guard let error == nil else { fail(error!); return }

Topics

#170: Swift Tricks Revisited 🎩

Topics

Today we'll look at a few more interesting Swift tips and tricks. Let's get started.

Multiple Switch Cases

We'll start with a simple one. We can simplify messy switch statements by combining the similar cases. This is similar to how we can use multiple case statements in other languages, but a bit less wordy:

extension FirstOrderAPI {
  var method: HTTPMethod {
    switch self {
    case .Spaceships,
         .Crew,
         .Stormtroopers,
         .Planets: return .GET

    case .AddSpaceship,
         .AddCrewMember,
         .AddStormtrooper,
         .AddPlanet: return .POST

    case .RemoveSpaceship,
         .RemoveCrewMember,
         .RemoveStormtrooper,
         .DestroyPlanet: return .DELETE
    }
  }
}

Operator Parameters

We can actually pass literal operators in as a parameter, for example:

[1, 2, 3, 4].reduce(0, combine: +)

This works because the + operator is actually a function under the hood:

public func +(lhs: Int, rhs: Int) -> Int

Simpler Reuse Identifiers

In Objective-C, It's quite common to use NSStringFromClass to use a cell's class name as it's reuseIdentifier. In Swift though:

let reuseIdentifier = String(SpaceshipTableViewCell)

Shout out to Natasha for pointing this one out!

Topics

#164: Swift Tricks πŸ‡πŸŽ©

Topics

In Bite #159, we started looking at some syntactic shortcuts in Swift. Today we'll continue by looking at a few (perhaps) lesser-known Swift tricks, and their effects. Let's get started.

@autoclosure

This attribute can help save space when writing simple closures:

func cache(key: String, @autoclosure cacheIf: () -> Bool)

Now, the compiler will infer the curly braces {} around our statement:

cache("spaceships", cacheIf: ships.count > 0)

private(set)

struct Spaceship { private(set) var name = "Untitled" }

With the private(set) declaration, we're telling the compiler this property has the default access-level of internal for reads, but writes can only happen in the source file where it's declared.

For frameworks, we can configure both the getter/setter explicitly:

public struct Droid {
  public private(set) var number: String
}

final

When optimizing performance-critical code, dynamic dispatch can be our enemy.

If our class's properties and functions can be overridden by subclasses, we're going to pay the performance cost of an indirect call or access every time we use one of those functions or properties.

We can easily prevent this by declaring a property or function final.

This way, any attempts to override it will result in a compile-time error. We can also declare a class final, which applies the final keyword to all the class's functions and properties.

Page 2 of 4