Swift Tricks

A handful of tricks we use at HODINKEE.

Member Short Hand

You can access members of any “known type” by calling .someValue or .someFunction(). This is most often seen with — but is not unique to — enums.

// UIColor.whiteColor()
view.backgroundColor = .whiteColor()
// CGRectZero
view.frame = .zero
// You can address initializers this way too
tableView = .init(frame: .zero, style: .Plain)

Framework Resources

Sometimes you need to load resources from another framework. Make that easy by exposing a public bundle() function in each framework.

private final class BundleHelper {}
public func bundle() -> NSBundle {
return NSBundle(forClass: BundleHelper.self)
}

Later you can call OtherFramework.bundle().

Likewise, you can also declare helpers for loading specific resources across framework boundaries.

public func image(name name: String, compatibleWithTraitCollection traitCollection: UITraitCollection? = nil) -> UIImage? {
return UIImage(named: name, inBundle: bundle(), compatibleWithTraitCollection: traitCollection
}
public func nib(name name: String) -> UINib {
return UINib(nibName: name, bundle: bundle())
}

Now you can call OtherFramework.image(name: “avatar/placeholder/small”) or OtherFramework.nib(name: “UserTableViewCell”) to fetch a resource provided by that framework.

Thanks to module namespaces, you can declare functions like this in multiple frameworks and address each individually.

Closure Types

Sometimes Swift is unable to infer the type of a closure. I was under the impression for a while that the entire closure had to be typed to solve this problem. Often times the input types are known and it is only the return type that is not. It is possible to leave the parameter types to Swift and only explicitly provide the return type.

array.map({ number -> String? in
guard number > 0 else { return nil }
return "\(number) Photos"
})

Zip

The Swift standard library offers many functions for dealing with simple data structures. If you find yourself with a couple of sequences and need to pull each element out of both, use zip. zip takes two sequences (of equal length) and returns a sequence of binary tuples with the Nth element of each of the input sequences.

Before:

let first = [ 1, 2, 3 ]
let second = [ "One", "Two", "Three" ]
for (index, first) in enumerate(first) {
let second = second[index]
/* */
}

After:

let first = [ 1, 2, 3 ]
let second = [ "One", "Two", "Three" ]
for (first, second) in zip(first, second) { /* */ }
Like what you read? Give Caleb Davenport a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.