Swift Cheat Sheet

This cheat sheet is from this link, with highlighting added by myself.

/*
Multiline Comment
*/

import UIKit
import Darwin // Some C libraries to use
 
// Variable names must start with a letter and can contain most any unicode
// character except whitespace, mathematical symbols, arrows
 
// Swift uses type inference to guess the data type if it isn't provided
// It assumes this is a string and won't except any other value type
var str = "Hello, playground"
 
// Define a constant
let pi = 3.141592
 
// Prints a string along with the variable value using string interpolation
println("pi is equal to \(pi)")
 
// You can define the data type with a type annotation
let numberOfSteps: Int = 450
 
// ---------- DATA TYPES ----------
 
// Int : Integers
// Double / Float : Decimal Numbers
// String : Characters
// Bool : true or false
 
// The maximum Int on a 64 bit computer
let maxInt: Int = 9223372036854775807
 
let maxUnsignedInt: UInt64 = UInt64.max
 
// The maximum Float
println("Max Float : \(FLT_MAX)")
 
// The maximum Double
println("Max Float : \(DBL_MAX)")
 
// Floats are accurate to 6 digits
let floatPrecision: Float = 1.999999 + 0.0000005
println("Float Precision: ", floatPrecision)
 
//Doubles are precise to 15 digits
let doublePrecision: Double = 1.99999999999999 + 0.000000000000005
println("Double Precision: ", doublePrecision)
 
// Booleans are either true or false
let isOver18 = true
 
// Create a String
let myName = "Derek"
 
// Combine or concatenate strings
let statement = "My name is " + myName
 
// Strings are immutable when you use let
// myName = "Paul"
var paulName = "Paul"
paulName = "Fred"
 
 
// ---------- CASTING ----------
 
// Cast a Float into an Int
println("I'm an Int now \(Int(floatPrecision))")
 
// Cast an Int into a Float
println("I'm a Float now \(Float(maxInt))")
 
// Cast an Int into a Bool
println("I'm a Bool now \(Bool(maxInt))")
 
// Turn a String into an Int
let myAge = "40"
let myAgeInt = myAge.toInt()
 
// Turn a String into a Float
let myHeight = "6.25"
let myHeightFloat = (myHeight as NSString).floatValue
 
// ---------- MATH ----------
println("5 + 3 =  \(5 + 3)")
println("5 - 3 =  \(5 - 3)")
println("5 * 3 =  \(5 * 3)")
println("5 / 3 =  \(5 / 3)")
println("5.3 % 3 =  \(5.3 % 3)") // Remainder Operator
 
// Shorthand Increment and Decrement
var num: Int = 1
 
println("num++ = \(num++)")
println("++num = \(++num)")
 
// Compound Assignment
num += 5
println("num += 5  \(num)")
 
num -= 5
println("num -= 5  \(num)")
 
num *= 5
println("num *= 5  \(num)")
 
num /= 5
println("num /= 5  \(num)")
 
num %= 5
println("num %= 5  \(num)")
 
// Generate random number between 0 and 10
println("Random Number : \(arc4random() % 11)")
 
// ---------- CONDITIONALS ----------
let age: Int = 13
 
// Conditional Operators > < >= <= == !=
// Logical Operators && || !
 
if age < 16 {
    println("You can go to school")
} else if (age >= 16) && (age < 18){
    println("You can drive")
} else {
    println("You can vote")
}
 
if (age < 14) || (age > 67) {
    println("You shouldn't work")
}
 
println("!true = \(!true)")
 
// Ternary Operator
var isLegalToVote: Bool = (age > 18) ? true : false
 
// Switch Statement
// Works with Ints, Doubles, Floats, Booleans, Strings and more
// By default after a match is made execution doesn't fall to the next
// case
 
let ingredient = "pinto beans"
 
switch ingredient {
case "pasta", "tomato":
    println("How about spaghetti")
    // fallthrough : Would check the next case if you want
case "potato":
    println("How about a baked potato")
case "pinto beans":
    println("How about a burrito")
default:
    println("A glass of water is nice")
}
 
// You can use a Range in switch
let testScore: Int = 89
 
switch testScore {
case 93...100:
    println("You got an A")
case 85...92:
    println("You got a B")
case 77...84:
    println("You got a C")
case 69...76:
    println("You got a D")
default:
    println("You got an F")
}
 
// ---------- ARRAYS ----------
 
// Every item in an array must be of the same type and
// can be Ints, Floats, Doubles, Strings, Bools, Structs
 
let friends: Array<String> = ["Bob", "Fred", "Paul"]
 
let randNums = [3, 6, 9]
 
// Values are referenced using indexes starting at 0
println("Random Num 1 : \(randNums[0])")
 
// Create empty array
var groceries = [String]()
 
// Add items to array
groceries.append("Tomato")
groceries.append("Potato")
groceries.append("Beans")
 
// How many items in array
println("Number of groceries : \(groceries.count)")
 
// Insert an item at an index
groceries.insert("Flour", atIndex: 1)
println(groceries)
 
// Replace an item
groceries[1] = "Whole Wheat Flour"
println(groceries)
 
// Remove an item at index
groceries.removeAtIndex(0)
println(groceries)
 
// Remove item by value
if let match = find(groceries,"Beans") {
    groceries.removeAtIndex(match)
}
println(groceries)
 
// Sort from lowest to highest
groceries = sorted(groceries, <)
println(groceries)
 
// Reverse array
groceries.reverse()
 
// Multidimensional Array
var array: [[Int]] = [[00,10,20],[01,11,21]]
 
for column in array {
    for row in column {
        println("\(row) : \(column)")
    }
}
 
println(array[1][0])
 
 
// ---------- DICTIONARIES ----------
// Use key value pairs for storing
// The key can be an Int, Double, String, Enum
 
// Create a dictionary
var superHeroes = [String : String]()
 
// Add value associated with key in brackets
superHeroes["Superman"] = "Clark Kent"
 
// Number of items
println("Number of Heroes : \(superHeroes.count)")
 
// Remove using the key
superHeroes.removeValueForKey("Superman")
 
// ---------- TUPLES ----------
// Tuples are normally used when you want to return
// many values from a function
 
var stats = (height:6.25, weight:179, name:"Derek")
println("Height : \(stats.height)")
println("Weight : \(stats.weight)")
println("Name : \(stats.name)")
 
// ---------- LOOPING ----------
 
for var i: Int = 1; i <= 10; i++ {
    
    // If is odd skip the rest of the code in the loop
    if Bool(i % 2){
        continue
    }
    
    // If i == 10 jump out of the loop completely
    if i == 10 {
        break
    }
    
    println("\(i)")
}
 
// For In Loop with Range
for j in -5...5 {
    println("\(j)")
}
 
var quote = "I dream of a better tomorrow, where chickens can cross the road and not be questioned about their motives."
 
// You can cycle through strings
var numOfAs = 0
for singleChar in quote {
    if singleChar == "a"{
        numOfAs++
    }
}
println("Number of a's \(numOfAs)")
 
// Cycle through array with for in
 
let people: Array<String> = ["Bob", "Fred", "Paul"]
 
for person in people {
    println(person)
}
 
// Cycle through a Dictionary
 
let heroes = ["Superman" : "Clark Kent",
    "Flash" : "Barry Allen", "Batman" : "Bruce Wayne"]
 
for (pubName, sIdent) in heroes {
    println("\(pubName) is \(sIdent)")
}
 
// While Loop
 
var k = 0
 
while k <= 10 {
    println(k)
    k++
}
 
// Do While Loop
 
var l = 0
 
do {
    println(l)
    l++
} while l <= 10
 
// ---------- FUNCTIONS ----------
 
// Function receives no attributes and returns nothing
func sayHello(){
    println("Hello")
}
 
sayHello()
 
// Function receives an attribute
func sayHello2(name: String){
    println("Hello \(name)")
}
 
sayHello2("Derek")
 
// Receives 2 attributes and returns an Int
// Attributes are given default values
func getSum(num1: Int = 1, num2: Int = 1) -> Int {
    return num1 + num2
}
 
println("5 + 6 = \(getSum(num1: 5, num2: 6))")
 
// Variadic parameters have an unknown number of attributes
func getSum2(nums: Int...) -> Int {
    
    var sum: Int = 0
    
    for num in nums{
        sum += num
    }
    return sum
}
 
println("Sum : \(getSum2(1,2,3,4,5))")
 
// How to effect variable values outside of the function
var str1: String = "happy"
var str2: String = "sad"
 
func makeUppercase(inout str1: String, inout str2: String){
    str1 = str1.uppercaseString
    str2 = str2.uppercaseString
}
 
makeUppercase(&str1, &str2)
 
println(str1 + " " + str2)
 
// Return multiple types from function (TUPLE)
func getMult(number: Int) -> (x2: Int, x3: Int){
    var x2 = number * 2
    var x3 = number * 3
    
    return (x2, x3)
}
 
var answer = getMult(50)
 
println(answer.x2)
println(answer.x3)
 
// Returning functions
// Receive an unknown number of Ints and return a Double
func average(nums: Int...) -> Double{
    var sum = 0
    
    for num in nums {
        sum += num
    }
    
    return Double(sum) / Double(nums.count)
}
 
func sum(nums: Int...) -> Double{
    var sum = 0
    
    for num in nums {
        sum += num
    }
    
    return Double(sum)
}
 
func doMath (mathOption: String) -> (Int...) -> Double{
    if mathOption == "average"{
        return average
    } else {
        return sum
    }
}
 
var mathFunc = doMath("average")
println(mathFunc(1,2,3,4,5,6))
 
mathFunc = doMath("sum")
println(mathFunc(1,2,3,4,5,6))
 
// Return an inner function that receives 2 Ints and
// returns a String
func multiplyIt () -> ((Int, Int) -> String) {
    func multiply(num1: Int, num2: Int) -> (String) {
        
        return "\(num1) * \(num2) = \(num1 * num2)"
    }
    return multiply
}
 
// Get a reference to a function that you can use to
// execute an inner function
let getValue = multiplyIt()
println(getValue(5, 3))
 
// ---------- CLOSURES ----------
 
// A Closure is self contained code like a function
// They differ in that they can be anonymous and have
// no name
 
// in seperates the header from the body

// feels to me to be like inline function in c++
 
//{ (param: paramType, param2: paramType) -> returnType in
//    statements
//    return value
//}
 
// A closure that excepts and returns an Int
var square: (Int) -> (Int) = { num in
    return num * num
}
 
println("\(square(15))")
 
// Assign a closure to another variable
var squareCopy = square
 
println("\(squareCopy(15))")
 
// No attributes or returns
var sayGoodbye: () -> () = {
    println("Goodbye")
}
 
sayGoodbye()
 
// No attributes with return
 
var sayHappy: () -> (String) = {
    "Happy Birthday"
}
 
println(sayHappy())
 
// Reference variables outside the closure. Functions can’t do this. Implicit returns from single-expression closures
 
var num3 = 3
 
var incrementNum = {
    println("num3 : \(++num3)")
}
 
incrementNum()
 
// An Array has a map method that excepts a closure that
// performs an action on every item in the array
let numsToSquare = [1,2,3,4,5,6]
 
let squaredNums = numsToSquare.map {
    (num: Int) -> String in
    "\(num * num)"
}
 
println(squaredNums)
 
 
// ---------- STRUCTS ----------
// You can create custom data types using Structs
// Structs are used when you don't want to inherit and
// you are modeling a simple data structure
 
struct Runner {
    var name: String
    var milePace: Double
    
    func displayMP() -> String {
        let absPace = Int(self.milePace)
        let prctMin = self.milePace - Double(absPace)
        let seconds = prctMin * 60
        
        return "\(absPace) min : \(seconds) sec"
    }
    
    // A computed property returns versus stores a value
    var marathonTime: Double {
        get {
            return (milePace * 26.2) / 60;
        }
    }
    
    // You can store static constants in a Struct
    static let marathonDist = 26.2;
    
}
 
let dennisKimetto = Runner(name: "Dennis Kimetto", milePace: 4.68)
let emmanuelMutai = Runner(name: "Emmanuel Mutai", milePace: 4.7)
 
println("\(dennisKimetto.name) : \(dennisKimetto.displayMP())")
 
println("\(emmanuelMutai.name) : \(emmanuelMutai.displayMP())")
 
println("Time to finish marathon : \(dennisKimetto.marathonTime) hours")
 
// Get a static value without initialization
println("Marathon Distance : \(Runner.marathonDist)")
 
// ---------- CLASSES ----------
 
class Animal {
    var name: String = "No Name"
    var height: Double = 0.0
    var weight: Double = 0.0
    var sound: String = "No Sound"
    
    // Assigns default values when an object is created
    // You can have many inits with different attributes
    
    // self is used to refer to attributes of the object
    // that called for this method to execute
    init(name: String, height: Double, weight: Double, sound: String){
        self.name = name
        self.height = height
        self.weight = weight
        self.sound = sound
    }
    
    func getInfo(){
        println("\(self.name) is \(self.height) cms tall and weighs \(self.weight) kgs and likes to say \(self.sound)")
    }
    
    // You can create overloaded methods if you change
    // the attributes
    func getSum(num1: Int, num2: Int) -> Int{
        return num1 + num2
    }
    
    func getSum(num1: Double, num2: Double) -> Double{
        return num1 + num2
    }
    
}
 
var rover = Animal(name: "Rover", height: 38, weight: 12.7, sound: "Ruff")
 
rover.getInfo()
 
 
// Inheritance
class Dog: Animal{
    
    // Dog can extend or override methods in Animal
    // A func marked as final can't be overridden by
    // subclasses
    
    final func digHole(){
        println("\(self.name) digs a hole")
    }
    
    override func getInfo(){
        
        // You can call a method in the superclass
        super.getInfo()
        println("and dig holes")
    }
    
}
 
var spot = Dog(name: "Spot", height: 38, weight: 12.7, sound: "Ruff")
 
// Dog inherits everything in Animal
spot.getInfo()
 
spot.digHole()
 
// You can pass any subclass type and the right method
// is automatically called
func printGetInfo(animal: Animal){
    animal.getInfo()
}
 
printGetInfo(rover)
printGetInfo(spot)
 
 
// You can set and get values with the dot operator
spot.name = "Doug"
println(spot.name)
 
// Testing overloaded methods
println("2 + 5 = \(spot.getSum(2,num2: 5))")
println("2.2 + 5.6 = \(spot.getSum(2.2,num2: 5.6))")
 
// Check the class type
println("Is Spot a Dog : \(spot is Animal)")
 
// ---------- PROTOCOLS ----------
 


// Protocols are like interfaces in other languages
// When you adopt a protocol you agree to define the
// behavior it describes
 
protocol Flyable {
    // Define if getters and setters are available
    // Put optional before var if you want it to be
    // optional
    var flies: Bool { get set }
    
    // You define the header for a func but nothing else
    func fly(distMiles: Double) -> String
    
}
 
// Adopt multiple protocols class ClassName : prot1, prot2
class Vehicle : Flyable{
    var flies: Bool = false
    var name: String = "No Name"
    
    func fly(distMiles: Double) -> String {
        if (self.flies){
            return "\(self.name) flies \(distMiles) miles"
        } else {
            return "\(self.name) can't fly"
        }
    }
}
 
var fordF150 = Vehicle()
fordF150.name = "Ford F-150"
fordF150.flies = false
println(fordF150.fly(10))
 
// ---------- EXTENSIONS ----------
// Extensions provide a way to add functionality without
// overidding existing functionality to a type being one
// you create or even Int, Double, String, Array
 
// Output a String as an array
extension String {
    // Array of characters, a computed property
    var asArray: [Character]{
    
        // Create an empty array of characters
        var result = [Character]()
        
        // Cycle through the string and store each
        // character in the array
        for char in self {
            result.append(char)
        }
        return result
    }
    
    // We can add functions as well
    func letterOccurence(theChar: Character) -> Int{
        var numOfChars = 0
        for letter in self {
            if letter == theChar{
                numOfChars++
            }
        }
        return numOfChars
    }
    
}
 
var characters = "A Random string".asArray
println(characters)
 
var numberOfAs: Int = "a Random string".letterOccurence("a")
println("Number of As \(numberOfAs)")
 
// ---------- GENERICS ----------
// Generics allow you to avoid repetitive code that exists
// because of type requirements
 
// If we wanted to print anything other then strings
// we'd have to create many of these
func printElements(randStr: String){
    for element in randStr{
        print("\(element), ")
    }
    println()
}
 
printElements("A Random String")
 
// The <T> indicates this is a generic function
// This excepts an array of anything now
 
func printAnyArray<T>(anything: [T]){
    for element in anything{
        print("\(element), ")
    }
    println()
}
 
printAnyArray(["Paul", "Jake"])
printAnyArray([1, 2, 3])
 
// Now we can print out any sequence type
func printAnySeq<T: SequenceType>(anything: T){
    for element in anything{
        print("\(element), ")
    }
    println()
}
 
printAnySeq("A random string")
 
// Equatable allows you to evaluate for equality. I think Equatable is confining what types are acceptable to this function.
func areTheyEqual<T: Equatable>(val1: T, val2: T) -> Bool {
    return val1 == val2
}
 
println(areTheyEqual(1,"b"))
 
// Comparable allows you to compare any data type
func compareThem<T: Comparable>(val1: T, val2: T) -> Bool {
    return val1 < val2
}
 
println(compareThem("a","b"))
 
// ---------- ENUMS ----------
// Enums structure related values and are very useful when
// you are working with a limited number of options
 
// Swift enums are not integer based like other languages
// They can store multiple data types
 
// If you want to map an enum to a value you must define
// the data type and a value unless it is Int
enum Color: Int {
    case blue // You could also: case blue = 1
    case green
    case red
    case purple
    case yellow
    
    // Set default value to blue
    init () {
        self = .blue
    }
    
    // Create a function that returns the color
    func getData() -> String {
        switch(self){
        case .blue: return "Blue"
        case .green: return "Green"
        case .red: return "Red"
        case .purple: return "Purple"
        case .yellow: return "Yellow"
        default: return "Not Found"
        }
    }
}
 
var someColor = Color()
 
println(someColor.rawValue)
 
var favColor = Color.purple
 
// Access the value associated
println(favColor.rawValue)
 
if(favColor == Color.purple){
    println("Favorite Color is Purple")
}
 
// Call an enum function
println(favColor.getData())