Swift Reference

Kip Landergren

(Updated: )

My cheat sheet for the Swift programming language covering best practices, comments, and helpful resource links.

Contents

Swift Version Note

The following document refers to Swift version 5.2.

Swift Terminology

library
a collection of code or data that can be imported
module
a single unit of code distribution
package
a collection of Swift source files and a manifest file conforming to a PackageDescription; could be a library or executable

Keywords

static

struct Foo {
  // indicates a type property, callable on
  // the Foo type as Foo.bar, scoped to the
  // type Foo
  static var bar = "bar"
  // indicates a type method, callable on
  // the Foo type as Foo.baz().
  static func baz() { /* do something */ }
}

Sequence

filter(_:) is equivalent to Ruby’s “accept”: if the predicate returns true, the element will be included in the returned array.

Array

Array length / array size / array count:

let length = array.count

Sort array using NSSortDescriptor objects:

let sorted = (unsorted as NSArray).sortedArrayUsingDescriptors([sortDescriptors])

Check if array contains any matching predicate:

let outcome = array.contains(where: { $0.hasProperty })

Filter array for elements that satisfy predicate:

let objectsWithProperty = array.filter { $0.hasProperty }

Date

Get Unix epoch time as TimeInterval, typealias for Double:

let secondsSinceEpoch = Date().timeIntervalSince1970

DateFormatter

When in doubt, review the archived Date Formatting Guide.

Localized Dates

Important:

let usDateFormatter = DateFormatter()
usDateFormatter.locale = Locale(identifier: "en_US")
usDateFormatter.setLocalizedDateFormatFromTemplate("yMMMd")
print(usDateFormatter.string(from: Date())) // Apr 20, 2020
let frDateFormatter = DateFormatter()
frDateFormatter.locale = Locale(identifier: "fr_FR")
frDateFormatter.setLocalizedDateFormatFromTemplate("yMMMd")
print(frDateFormatter.string(from: Date())) // 20 avr. 2020

Unicode Date Format Patterns

Based on tr35-31:

y Year. e.g. “AD 2020” becomes “2020”
yy Year, maximum length of 2. e.g. “AD 2020” becomes “20”
yyy Year, with up to 2 spaces of padding. e.g. “AD 20” becomes “020”
yyyy Year, with up to 3 spaces of padding. e.g. “AD 20” becomes “0020”
yyyyy Year, with up to 4 spaces of padding. e.g. “AD 2020” becomes “02020”
M Month, numerical. e.g. “April” becomes “4”
MM Month, numerical, with zero padding. e.g. “April” becomes “04”
MMM Month, abbreviation. e.g. “April” becomes “Apr”
MMMM Month, full name. e.g. “April” becomes “April”
MMMMM Month, narrow name. e.g. “April” becomes “A”

Note: I have yet to determine whether Unicode Date Format Patterns is independent of, or an extension of, ISO 8601 date format patterns.

Dictionary

Dictionary literal (note: type hinting often required for complex value types):

let dataSource: [Int:[CustomType]] = [
  0: FooEnum.allCases,
  1: BarEnum.allCases,
  2: BazEnum.allCases,
]

Dictionary with an empty array as default value:

let unknown = dataSource[3, default: []]

Iterating entries:

for (key, value) in dataSource {
  // do something
}

Int

Integer Operators

// any remainder is discarded
1 / 4 // 0
2 / 4 // 0
3 / 4 // 0
4 / 4 // 1
5 / 4 // 1
6 / 4 // 1

NumberFormatter

Getting a localized ordinal number:

let ordinalFormatter = NumberFormatter()
ordinalFormatter.numberStyle = .ordinal
let one = NSNumber(value: 1)
let first = ordinalFormatter.string(from: one)!
print(first) // 1st

NumberFormatter.Style Values

Refer to NumberFormmatter.Style documentation.

TimeInterval

typealias for Double, always in seconds.

Switch Statements

Important points:

enum

enum CompassPoint: Int, CaseIterable {
    case north // rawValue of 0
    case south
    case east
    case west
}

Note:

Numbers

Int signed integer value type
Float single-precision floating-point value type
Double double-precision floating-point value type

Foundation

NSSet

Convert to Array:

guard let set = nsset as? Set<Element> else { /* handle it */ }
let array = Array(set)

Useful Classes

Range Operators

for _ in 0...3 { /* 0, 1, 2, 3 */ } // closed range operator
for _ in 0..<3 { /* 0, 1, 2 */ } // half-open range operator
let letters = ['a','b','c','d','e']
for _ in letters[...2] { /* a, b, c */ } // one-sided closed range (from beginning)
for _ in letters[2...] { /* c, d, e */ } // one-sided closed range (to end)
for _ in letters[..<2] { /* a, b */ } // one-sided half-open range (from beginning)
for _ in letters[2..&;t] { /* c, d */ } // one-sided half-open range (to end)

Type Casting

Type Checking

To check if foo is of subclass type Bar:

if foo is Bar {
  print("it is!")
}

Downcasting

To conditionally downcast, returning nil if failure:

if let bar = foo as? Bar {
  // work with bar
}

To force downcast, generating a runtime error if failure:

let bar = foo as! Bar

Attributes

available

Swift attributes documentation has full information about platforms, versions, and available explanations. Use @available to indicate declaration life cycle, calling with platform names, their optional version numbers, and optional explanations:

@available(platform-name version-number, *)

Mark a method deprecated for all platforms, with a message:

@available(*, unavailable, message: "now obsolete")

Comments

Code Comments

Normal comments that appear in code.

Single Line

// this is a comment!

Multi-Line

/*
 This is a multi-line comment!
 */

Inline

guard let foo = bar as? Qux else { /* inline comment */ fatalError() }

Swift Comments and Xcode

Horizontal Delimiter

// MARK: -

creates a solitary horizontal delimiter in the Xcode jump bar and minimap

Headings

// MARK: Delegate Methods

creates a heading with text “Delegate Methods” in the Xcode jump bar and minimap

// MARK: - Delegate Methods

creates a horizontal delimiter, followed by a heading with text “Delegate Methods” in the Xcode jump bar and minimap

Action Items

Note: As far as I can tell there is no additional management of action items beyond special formatting in the jump bar

// TODO: finish implementing delegate methods

creates a to-do item with text “finish implementing delegate methods” in the Xcode jump bar

// FIXME: broken on horizontally compact

creates a fix-me item with text “broken on horizontally compact” in the Xcode jump bar

Documentation Comments

Displayed in Xcode tooltips and the “Quick Help” area.

Single Line

/// this is a documentation comment! (note the third slash)

Multi-Line

/**
 This is a multi-line documentation comment!
 (note the second asterisk)
 */

Refer to the official Swift Markup Formatting Reference for information on how to improve the utility and presentation of your documentation comments.

Swift Package Manager

Package Properties

Creating a Package

Working with Packages

Note: there are special considerations when working with a local override of a remote package.

Command line usage:

$ swift package --help
$ swift package [subcommand] --help

Compiler Flags

Warn on function bodies that take longer than 100 ms to type check:

-Xfrontend -warn-long-function-bodies=100

Warn on expressions that take longer than 100 ms to type check:

-Xfrontend -warn-long-expression-type-checking=100

Best Practices

Avoiding Force Casts

Rather than:

let foo = bar as! Qux

Prefer:

guard let foo = bar as? Qux else {
  // handle unsuccessful cast
}

Singleton Usage

Refer to Apple’s Cocoa Design Patterns document Managing a Shared Resource Using a Singleton.

General

Format Strings

%d signed 32-bit integer
%@ object

More info in this Stack Overflow question: “What are the supported Swift String format specifiers?”.

Resources

Documentation

Resources

WWDC

Code

References

Frequently Asked Questions (FAQ)

Does Swift support the equivalent of anonymous interfaces?

No, the closest you can get are on-the-spot implementations of protocols via structs or classes defined in whatever execution context you are working.

What Date Format Strings Does Swift Use?

Swift uses Unicode Date Format Patterns, indicated from DateFormatter.dateFormat documentation linking to Date Formatting Guide. Note that there are specific Unicode Technical Reports that different systems conform to.