Swift Notes For Professionals
Swift Notes For Professionals
Swift
Notes for Professionals
™
200+ pages
of professional hints and tricks
Disclaimer
GoalKicker.com This is an unocial free book created for educational purposes and is
not aliated with ocial Swift™ group(s) or company(s).
Free Programming Books All trademarks and registered trademarks are
the property of their respective owners
Contents
About ................................................................................................................................................................................... 1
Chapter 1: Getting started with Swift Language .......................................................................................... 2
Section 1.1: Your first Swift program ............................................................................................................................ 2
Section 1.2: Your first program in Swift on a Mac (using a Playground) ................................................................. 3
Section 1.3: Your first program in Swift Playgrounds app on iPad ........................................................................... 7
Section 1.4: Installing Swift ............................................................................................................................................ 8
Section 1.5: Optional Value and Optional enum ......................................................................................................... 8
Chapter 2: Switch ........................................................................................................................................................ 10
Section 2.1: Switch and Optionals .............................................................................................................................. 10
Section 2.2: Basic Use ................................................................................................................................................. 10
Section 2.3: Matching a Range .................................................................................................................................. 10
Section 2.4: Partial matching ..................................................................................................................................... 11
Section 2.5: Using the where statement in a switch ................................................................................................ 12
Section 2.6: Matching Multiple Values ....................................................................................................................... 12
Section 2.7: Switch and Enums ................................................................................................................................... 13
Section 2.8: Switches and tuples ................................................................................................................................ 13
Section 2.9: Satisfy one of multiple constraints using switch ................................................................................. 14
Section 2.10: Matching based on class - great for prepareForSegue ................................................................... 14
Section 2.11: Switch fallthroughs ................................................................................................................................. 15
Chapter 3: Reading & Writing JSON ................................................................................................................. 16
Section 3.1: JSON Serialization, Encoding, and Decoding with Apple Foundation and the Swift Standard
Library .................................................................................................................................................................. 16
Section 3.2: SwiftyJSON .............................................................................................................................................. 19
Section 3.3: Freddy ...................................................................................................................................................... 20
Section 3.4: JSON Parsing Swift 3 .............................................................................................................................. 22
Section 3.5: Simple JSON parsing into custom objects ........................................................................................... 24
Section 3.6: Arrow ........................................................................................................................................................ 25
Chapter 4: Enums ....................................................................................................................................................... 28
Section 4.1: Basic enumerations ................................................................................................................................. 28
Section 4.2: Enums with associated values .............................................................................................................. 28
Section 4.3: Indirect payloads .................................................................................................................................... 29
Section 4.4: Raw and Hash values ............................................................................................................................. 30
Section 4.5: Initializers ................................................................................................................................................. 31
Section 4.6: Enumerations share many features with classes and structures ..................................................... 32
Section 4.7: Nested Enumerations ............................................................................................................................. 33
Chapter 5: Protocols ................................................................................................................................................. 34
Section 5.1: Protocol Basics ........................................................................................................................................ 34
Section 5.2: Delegate pattern .................................................................................................................................... 36
Section 5.3: Associated type requirements .............................................................................................................. 37
Section 5.4: Class-Only Protocols .............................................................................................................................. 39
Section 5.5: Protocol extension for a specific conforming class ............................................................................ 40
Section 5.6: Using the RawRepresentable protocol (Extensible Enum) ................................................................ 40
Section 5.7: Implementing Hashable protocol ......................................................................................................... 41
Chapter 6: Optionals ................................................................................................................................................. 43
Section 6.1: Types of Optionals .................................................................................................................................. 43
Section 6.2: Unwrapping an Optional ....................................................................................................................... 43
Section 6.3: Nil Coalescing Operator ......................................................................................................................... 44
Section 6.4: Optional Chaining ................................................................................................................................... 45
Section 6.5: Overview - Why Optionals? ................................................................................................................... 46
Chapter 7: Structs ...................................................................................................................................................... 48
Section 7.1: Structs are value types ........................................................................................................................... 48
Section 7.2: Accessing members of struct ................................................................................................................ 48
Section 7.3: Basics of Structs ...................................................................................................................................... 48
Section 7.4: Mutating a Struct .................................................................................................................................... 49
Section 7.5: Structs cannot inherit ............................................................................................................................. 49
Chapter 8: Closures ................................................................................................................................................... 50
Section 8.1: Closure basics .......................................................................................................................................... 50
Section 8.2: Syntax variations .................................................................................................................................... 51
Section 8.3: Passing closures into functions ............................................................................................................. 51
Section 8.4: Captures, strong/weak references, and retain cycles ....................................................................... 53
Section 8.5: Using closures for asynchronous coding ............................................................................................. 54
Section 8.6: Closures and Type Alias ........................................................................................................................ 55
Chapter 9: Error Handling ...................................................................................................................................... 56
Section 9.1: Error handling basics .............................................................................................................................. 56
Section 9.2: Catching dierent error types .............................................................................................................. 56
Section 9.3: Catch and Switch Pattern for Explicit Error Handling ......................................................................... 58
Section 9.4: Disabling Error Propagation .................................................................................................................. 58
Section 9.5: Create custom Error with localized description .................................................................................. 59
Chapter 10: Arrays ...................................................................................................................................................... 60
Section 10.1: Basics of Arrays ..................................................................................................................................... 60
Section 10.2: Extracting values of a given type from an Array with flatMap(_:) .................................................. 61
Section 10.3: Combining an Array's elements with reduce(_:combine:) ................................................................ 61
Section 10.4: Flattening the result of an Array transformation with flatMap(_:) .................................................. 62
Section 10.5: Lazily flattening a multidimensional Array with flatten() ................................................................. 62
Section 10.6: Filtering out nil from an Array transformation with flatMap(_:) ...................................................... 63
Section 10.7: Subscripting an Array with a Range ................................................................................................... 63
Section 10.8: Removing element from an array without knowing it's index ......................................................... 64
Section 10.9: Sorting an Array of Strings .................................................................................................................. 64
Section 10.10: Accessing indices safely ...................................................................................................................... 65
Section 10.11: Filtering an Array .................................................................................................................................. 66
Section 10.12: Transforming the elements of an Array with map(_:) .................................................................... 66
Section 10.13: Useful Methods ..................................................................................................................................... 67
Section 10.14: Sorting an Array ................................................................................................................................... 67
Section 10.15: Finding the minimum or maximum element of an Array ................................................................ 68
Section 10.16: Modifying values in an array .............................................................................................................. 69
Section 10.17: Comparing 2 Arrays with zip .............................................................................................................. 69
Section 10.18: Grouping Array values ........................................................................................................................ 70
Section 10.19: Value Semantics ................................................................................................................................... 71
Section 10.20: Accessing Array Values ...................................................................................................................... 71
Chapter 11: Dictionaries ........................................................................................................................................... 73
Section 11.1: Declaring Dictionaries ............................................................................................................................ 73
Section 11.2: Accessing Values .................................................................................................................................... 73
Section 11.3: Change Value of Dictionary using Key ................................................................................................ 74
Section 11.4: Get all keys in Dictionary ....................................................................................................................... 74
Section 11.5: Modifying Dictionaries ........................................................................................................................... 74
Section 11.6: Merge two dictionaries .......................................................................................................................... 75
Chapter 12: Strings and Characters .................................................................................................................. 76
Section 12.1: String & Character Literals .................................................................................................................... 76
Section 12.2: Concatenate strings .............................................................................................................................. 77
Section 12.3: String Encoding and Decomposition ................................................................................................... 77
Section 12.4: Examine and compare strings ............................................................................................................. 78
Section 12.5: Reversing Strings .................................................................................................................................. 79
Section 12.6: Check if String contains Characters from a Defined Set .................................................................. 79
Section 12.7: String Iteration ....................................................................................................................................... 80
Section 12.8: Splitting a String into an Array ............................................................................................................ 82
Section 12.9: Unicode .................................................................................................................................................. 82
Section 12.10: Converting Swift string to a number type ......................................................................................... 83
Section 12.11: Convert String to and from Data / NSData ....................................................................................... 83
Section 12.12: Formatting Strings ............................................................................................................................... 84
Section 12.13: Uppercase and Lowercase Strings .................................................................................................... 84
Section 12.14: Remove characters from a string not defined in Set ....................................................................... 85
Section 12.15: Count occurrences of a Character into a String ............................................................................... 85
Section 12.16: Remove leading and trailing WhiteSpace and NewLine ................................................................. 85
Chapter 13: Extensions .............................................................................................................................................. 87
Section 13.1: What are Extensions? ............................................................................................................................ 87
Section 13.2: Variables and functions ........................................................................................................................ 87
Section 13.3: Initializers in Extensions ......................................................................................................................... 88
Section 13.4: Subscripts ............................................................................................................................................... 88
Section 13.5: Protocol extensions ............................................................................................................................... 88
Section 13.6: Restrictions ............................................................................................................................................. 89
Section 13.7: What are extensions and when to use them ...................................................................................... 89
Chapter 14: Sets .......................................................................................................................................................... 91
Section 14.1: Declaring Sets ......................................................................................................................................... 91
Section 14.2: Performing operations on sets ............................................................................................................ 91
Section 14.3: CountedSet ............................................................................................................................................. 92
Section 14.4: Modifying values in a set ...................................................................................................................... 92
Section 14.5: Checking whether a set contains a value ........................................................................................... 92
Section 14.6: Adding values of my own type to a Set .............................................................................................. 92
Chapter 15: Working with C and Objective-C ................................................................................................ 94
Section 15.1: Use a module map to import C headers ............................................................................................. 94
Section 15.2: Using Objective-C classes from Swift code ........................................................................................ 94
Section 15.3: Specify a bridging header to swiftc ..................................................................................................... 96
Section 15.4: Use the C standard library ................................................................................................................... 96
Section 15.5: Fine-grained interoperation between Objective-C and Swift ........................................................... 96
Section 15.6: Using Swift classes from Objective-C code ........................................................................................ 97
Chapter 16: Functions ................................................................................................................................................ 99
Section 16.1: Basic Use ................................................................................................................................................. 99
Section 16.2: Functions with Parameters ................................................................................................................... 99
Section 16.3: Subscripts ............................................................................................................................................. 100
Section 16.4: Methods ................................................................................................................................................ 101
Section 16.5: Variadic Parameters ........................................................................................................................... 102
Section 16.6: Operators are Functions .................................................................................................................... 102
Section 16.7: Passing and returning functions ........................................................................................................ 103
Section 16.8: Function types ..................................................................................................................................... 103
Section 16.9: Inout Parameters ................................................................................................................................ 103
Section 16.10: Throwing Errors ................................................................................................................................. 103
Section 16.11: Returning Values ................................................................................................................................. 104
Section 16.12: Trailing Closure Syntax ..................................................................................................................... 104
Section 16.13: Functions With Closures .................................................................................................................... 105
Chapter 17: Numbers .............................................................................................................................................. 107
Section 17.1: Number types and literals ................................................................................................................... 107
Section 17.2: Convert numbers to/from strings ..................................................................................................... 108
Section 17.3: Rounding .............................................................................................................................................. 108
Section 17.4: Random number generation ............................................................................................................. 109
Section 17.5: Convert one numeric type to another .............................................................................................. 110
Section 17.6: Exponentiation ..................................................................................................................................... 110
Chapter 18: Classes .................................................................................................................................................. 111
Section 18.1: Defining a Class ................................................................................................................................... 111
Section 18.2: Properties and Methods ..................................................................................................................... 111
Section 18.3: Reference Semantics .......................................................................................................................... 111
Section 18.4: Classes and Multiple Inheritance ....................................................................................................... 112
Section 18.5: deinit ..................................................................................................................................................... 113
Chapter 19: Conditionals ....................................................................................................................................... 114
Section 19.1: Optional binding and "where" clauses ............................................................................................... 114
Section 19.2: Using Guard ......................................................................................................................................... 115
Section 19.3: Basic conditionals: if-statements ....................................................................................................... 115
Section 19.4: Ternary operator ................................................................................................................................ 116
Section 19.5: Nil-Coalescing Operator ..................................................................................................................... 117
Chapter 20: Variables & Properties ................................................................................................................ 118
Section 20.1: Creating a Variable ............................................................................................................................. 118
Section 20.2: Property Observers ............................................................................................................................ 118
Section 20.3: Lazy Stored Properties ...................................................................................................................... 119
Section 20.4: Property Basics .................................................................................................................................. 119
Section 20.5: Computed Properties ......................................................................................................................... 120
Section 20.6: Local and Global Variables ............................................................................................................... 120
Section 20.7: Type Properties .................................................................................................................................. 121
Chapter 21: Tuples .................................................................................................................................................... 122
Section 21.1: What are Tuples? ................................................................................................................................. 122
Section 21.2: Decomposing into individual variables ............................................................................................. 122
Section 21.3: Tuples as the Return Value of Functions .......................................................................................... 123
Section 21.4: Using a typealias to name your tuple type ...................................................................................... 123
Section 21.5: Swapping values ................................................................................................................................. 124
Section 21.6: Tuples as Case in Switch .................................................................................................................... 124
Chapter 22: Booleans ............................................................................................................................................. 126
Section 22.1: What is Bool? ....................................................................................................................................... 126
Section 22.2: Booleans and Inline Conditionals ..................................................................................................... 126
Section 22.3: Boolean Logical Operators ............................................................................................................... 127
Section 22.4: Negate a Bool with the prefix ! operator ......................................................................................... 127
Chapter 23: Memory Management .................................................................................................................. 128
Section 23.1: Reference Cycles and Weak References ......................................................................................... 128
Section 23.2: Manual Memory Management ......................................................................................................... 129
Chapter 24: Generics .............................................................................................................................................. 130
Section 24.1: The Basics of Generics ....................................................................................................................... 130
Section 24.2: Constraining Generic Placeholder Types ........................................................................................ 131
Section 24.3: Generic Class Examples ..................................................................................................................... 132
Section 24.4: Using Generics to Simplify Array Functions .................................................................................... 133
Section 24.5: Advanced Type Constraints .............................................................................................................. 133
Section 24.6: Generic Class Inheritance .................................................................................................................. 134
Section 24.7: Use generics to enhance type-safety .............................................................................................. 135
Chapter 25: Advanced Operators .................................................................................................................... 136
Section 25.1: Bitwise Operators ................................................................................................................................ 136
Section 25.2: Custom Operators .............................................................................................................................. 137
Section 25.3: Overflow Operators ........................................................................................................................... 138
Section 25.4: Commutative Operators .................................................................................................................... 138
Section 25.5: Overloading + for Dictionaries .......................................................................................................... 139
Section 25.6: Precedence of standard Swift operators ......................................................................................... 139
Chapter 26: Access Control ................................................................................................................................. 141
Section 26.1: Basic Example using a Struct ............................................................................................................. 141
Section 26.2: Subclassing Example ......................................................................................................................... 142
Section 26.3: Getters and Setters Example ............................................................................................................. 142
Chapter 27: Associated Objects ........................................................................................................................ 143
Section 27.1: Property, in a protocol extension, achieved using associated object ........................................... 143
Chapter 28: Loops .................................................................................................................................................... 146
Section 28.1: For-in loop ............................................................................................................................................ 146
Section 28.2: Repeat-while loop .............................................................................................................................. 148
Section 28.3: For-in loop with filtering ..................................................................................................................... 148
Section 28.4: Sequence Type forEach block .......................................................................................................... 149
Section 28.5: while loop ............................................................................................................................................ 149
Section 28.6: Breaking a loop .................................................................................................................................. 150
Chapter 29: Reflection ........................................................................................................................................... 151
Section 29.1: Basic Usage for Mirror ........................................................................................................................ 151
Section 29.2: Getting type and names of properties for a class without having to instantiate it .................... 151
Chapter 30: OptionSet ........................................................................................................................................... 155
Section 30.1: OptionSet Protocol .............................................................................................................................. 155
Chapter 31: Method Swizzling ............................................................................................................................. 156
Section 31.1: Extending UIViewController and Swizzling viewDidLoad ................................................................. 156
Section 31.2: Basics of Swift Swizzling ..................................................................................................................... 157
Section 31.3: Basics of Swizzling - Objective-C ....................................................................................................... 157
Chapter 32: Concurrency ...................................................................................................................................... 159
Section 32.1: Obtaining a Grand Central Dispatch (GCD) queue ......................................................................... 159
Section 32.2: Concurrent Loops ............................................................................................................................... 159
Section 32.3: Running tasks in a Grand Central Dispatch (GCD) queue ............................................................. 160
Section 32.4: Running Tasks in an OperationQueue ............................................................................................. 162
Section 32.5: Creating High-Level Operations ....................................................................................................... 163
Chapter 33: Initializers ............................................................................................................................................ 165
Section 33.1: Convenience init .................................................................................................................................. 165
Section 33.2: Setting default property values ........................................................................................................ 167
Section 33.3: Customizing initialization with paramaters ...................................................................................... 168
Section 33.4: Throwable Initilizer ............................................................................................................................. 169
Chapter 34: Getting Started with Protocol Oriented Programming ............................................. 170
Section 34.1: Using protocols as first class types ................................................................................................... 170
Section 34.2: Leveraging Protocol Oriented Programming for Unit Testing ...................................................... 173
Chapter 35: Functional Programming in Swift .......................................................................................... 175
Section 35.1: Extracting a list of names from a list of Person(s) .......................................................................... 175
Section 35.2: Traversing ........................................................................................................................................... 175
Section 35.3: Filtering ................................................................................................................................................ 175
Section 35.4: Using Filter with Structs ..................................................................................................................... 176
Section 35.5: Projecting ............................................................................................................................................ 177
Chapter 36: Style Conventions .......................................................................................................................... 179
Section 36.1: Fluent Usage ........................................................................................................................................ 179
Section 36.2: Clear Usage ......................................................................................................................................... 180
Section 36.3: Capitalization ...................................................................................................................................... 181
Chapter 37: Type Casting ..................................................................................................................................... 183
Section 37.1: Downcasting ........................................................................................................................................ 183
Section 37.2: Type casting in Swift Language ........................................................................................................ 183
Section 37.3: Upcasting ............................................................................................................................................. 185
Section 37.4: Example of using a downcast on a function parameter involving subclassing .......................... 185
Section 37.5: Casting with switch ............................................................................................................................. 186
Chapter 38: Logging in Swift .............................................................................................................................. 187
Section 38.1: dump .................................................................................................................................................... 187
Section 38.2: Debug Print ......................................................................................................................................... 188
Section 38.3: print() vs dump() ................................................................................................................................ 189
Section 38.4: print vs NSLog ..................................................................................................................................... 189
Chapter 39: Performance ..................................................................................................................................... 191
Section 39.1: Allocation Performance ...................................................................................................................... 191
Chapter 40: RxSwift ................................................................................................................................................ 193
Section 40.1: Disposing ............................................................................................................................................. 193
Section 40.2: RxSwift basics ..................................................................................................................................... 193
Section 40.3: Creating observables ......................................................................................................................... 194
Section 40.4: Bindings ............................................................................................................................................... 195
Section 40.5: RxCocoa and ControlEvents ............................................................................................................. 195
Chapter 41: The Defer Statement ................................................................................................................... 198
Section 41.1: When to use a defer statement .......................................................................................................... 198
Section 41.2: When NOT to use a defer statement ................................................................................................ 198
Chapter 42: Design Patterns - Creational ................................................................................................... 199
Section 42.1: Singleton .............................................................................................................................................. 199
Section 42.2: Builder Pattern .................................................................................................................................... 199
Section 42.3: Factory Method .................................................................................................................................. 205
Section 42.4: Observer .............................................................................................................................................. 206
Section 42.5: Chain of responsibility ....................................................................................................................... 207
Section 42.6: Iterator ................................................................................................................................................. 209
Chapter 43: Swift Package Manager ............................................................................................................. 210
Section 43.1: Creation and usage of a simple Swift package ............................................................................... 210
Chapter 44: NSRegularExpression in Swift ................................................................................................ 212
Section 44.1: Extending String to do simple pattern matching ............................................................................. 212
Section 44.2: Basic Usage ........................................................................................................................................ 213
Section 44.3: Replacing Substrings ......................................................................................................................... 213
Section 44.4: Special Characters ............................................................................................................................. 214
Section 44.5: Validation ............................................................................................................................................ 214
Section 44.6: NSRegularExpression for mail validation ........................................................................................ 214
Chapter 45: Documentation markup ............................................................................................................. 216
Section 45.1: Class documentation .......................................................................................................................... 216
Section 45.2: Documentation styles ........................................................................................................................ 216
Chapter 46: AES encryption ................................................................................................................................ 220
Section 46.1: AES encryption in CBC mode with a random IV (Swift 3.0) ............................................................ 220
Section 46.2: AES encryption in CBC mode with a random IV (Swift 2.3) ........................................................... 222
Section 46.3: AES encryption in ECB mode with PKCS7 padding ......................................................................... 224
Chapter 47: PBKDF2 Key Derivation .............................................................................................................. 226
Section 47.1: Password Based Key Derivation 2 (Swift 3) ..................................................................................... 226
Section 47.2: Password Based Key Derivation 2 (Swift 2.3) ................................................................................. 227
Section 47.3: Password Based Key Derivation Calibration (Swift 2.3) ................................................................. 228
Section 47.4: Password Based Key Derivation Calibration (Swift 3) ................................................................... 228
Chapter 48: Typealias ........................................................................................................................................... 230
Section 48.1: typealias for closures with parameters ............................................................................................ 230
Section 48.2: typealias for empty closures ............................................................................................................ 230
Section 48.3: typealias for other types ................................................................................................................... 230
Chapter 49: Cryptographic Hashing .............................................................................................................. 231
Section 49.1: HMAC with MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3) ............................................. 231
Section 49.2: MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3) ............................................. 232
Chapter 50: Dependency Injection .................................................................................................................. 234
Section 50.1: Dependency Injection with View Controllers .................................................................................... 234
Section 50.2: Dependency Injection Types ............................................................................................................ 237
Chapter 51: Function as first class citizens in Swift ................................................................................. 240
Section 51.1: Assigning function to a variable ......................................................................................................... 240
Section 51.2: Passing function as an argument to another function, thus creating a Higher-Order Function
............................................................................................................................................................................. 241
Section 51.3: Function as return type from another function ............................................................................... 241
Chapter 52: Blocks ................................................................................................................................................... 242
Section 52.1: Non-escaping closure ......................................................................................................................... 242
Section 52.2: Escaping closure ................................................................................................................................ 242
Chapter 53: Caching on disk space ................................................................................................................. 244
Section 53.1: Reading ................................................................................................................................................ 244
Section 53.2: Saving .................................................................................................................................................. 244
Chapter 54: Algorithms with Swift .................................................................................................................. 245
Section 54.1: Sorting .................................................................................................................................................. 245
Section 54.2: Insertion Sort ....................................................................................................................................... 248
Section 54.3: Selection sort ...................................................................................................................................... 248
Section 54.4: Asymptotic analysis ........................................................................................................................... 249
Section 54.5: Quick Sort - O(n log n) complexity time .......................................................................................... 249
Section 54.6: Graph, Trie, Stack ............................................................................................................................... 250
Chapter 55: (Unsafe) Buer Pointers ............................................................................................................ 264
Section 55.1: UnsafeMutablePointer ........................................................................................................................ 264
Section 55.2: Practical Use-Case for Buer Pointers ............................................................................................ 265
Chapter 56: Swift Advance functions ............................................................................................................. 266
Section 56.1: Flatten multidimensional array .......................................................................................................... 266
Section 56.2: Introduction with advance functions ................................................................................................ 266
Chapter 57: Completion Handler ...................................................................................................................... 268
Section 57.1: Completion handler with no input argument ................................................................................... 268
Section 57.2: Completion handler with input argument ........................................................................................ 268
Chapter 58: Design Patterns - Structural .................................................................................................... 270
Section 58.1: Adapter ................................................................................................................................................ 270
Section 58.2: Facade ................................................................................................................................................. 270
Chapter 59: Swift HTTP server by Kitura ..................................................................................................... 272
Section 59.1: Hello world application ....................................................................................................................... 272
Chapter 60: Generate UIImage of Initials from String .......................................................................... 275
Section 60.1: InitialsImageFactory ........................................................................................................................... 275
Credits ............................................................................................................................................................................ 276
You may also like ...................................................................................................................................................... 280
About
Please feel free to share this PDF with anyone for free,
latest version of this book can be downloaded from:
http://GoalKicker.com/SwiftBook
This Swift™ Notes for Professionals book is compiled from Stack Overflow
Documentation, the content is written by the beautiful people at Stack Overflow.
Text content is released under Creative Commons BY-SA, see credits at the end
of this book whom contributed to the various chapters. Images may be copyright
of their respective owners unless otherwise specified
This is an unofficial free book created for educational purposes and is not
affiliated with official Swift™ group(s) or company(s) nor Stack Overflow. All
trademarks and registered trademarks are the property of their respective
company owners
print("Hello, world!")
To compile and run a script in one step, use swift from the terminal (in a directory where this file is located):
To launch a terminal, press CTRL + ALT + T on Linux, or find it in Launchpad on macOS. To change
directory, enter cddirectory_name (or cd .. to go back)
A compiler is a computer program (or a set of programs) that transforms source code written in a
programming language (the source language) into another computer language (the target language), with
the latter often having a binary form known as object code. (Wikipedia)
$ swiftc hello.swift
This will compile your code into hello file. To run it, enter ./, followed by a filename.
Or use the swift REPL (Read-Eval-Print-Loop), by typing swift from the command line, then entering your
code in the interpreter:
Code:
func greet(name: String, surname: String) { print("Greetings \(name) \(surname)") } let myName = "Homer" let
mySurname = "Simpson" greet(name: myName, surname: mySurname)
print("Greetings \(name) \(surname)") - This prints out to the console "Greetings ", then name,
then surname. Basically \(variable_name) prints out that variable's value.
let myName = "Homer" and let mySurname = "Simpson" - create constants (variables which value
you can't change) using let with names: myName, mySurname and values: "Homer", "Simpson"
respectively.
greet(name: myName, surname: mySurname) - calls a function that we created earlier supplying the
values of constants myName, mySurname.
$ swift Welcome to Apple Swift. Type :help for assistance. 1> func greet(name: String, surname: String) { 2.
print("Greetings \(name) \(surname)") 3. } 4> 5> let myName = "Homer" myName: String = "Homer" 6> let
mySurname = "Simpson" mySurname: String = "Simpson" 7> greet(name: myName, surname: mySurname)
Greetings Homer Simpson 8> ^D
After the installation is complete, open Xcode and select Get started with a Playground:
On the next panel, you can give your Playground a name or you can leave it MyPlayground and press Next:
print("Hello world")
You should see 'Hello world' in the Debug Area and "Hello world\n" in the right Sidebar:
3- In the My Playgrounds tab, tap + on the top left corner and then select Blank template.
6- At the front of each line, the result will be stored in a small square. Tap it to reveal the result.
7- To step slowly through code to trace it, tap the button next to Run My Code.
Next, add Swift to your path. On macOS, the default location for the downloadable toolchain is
/Library/Developer/Toolchains. Run the following command in Terminal:
export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:"${PATH}"
If you installed the Swift toolchain to a directory other than the system root, you will need to run the following
command, using the actual path of your Swift installation:
$ export PATH=/path/to/Swift/usr/bin:"${PATH}"
You can verify you have the current version of Swift by running this command:
$ swift --version
if let y = x {
print(y)
}
In fact if you add a print(x.dynamicType) statement in the code above you'll see this in the console:
Optional<String>
String? is actually syntactic sugar for Optional, and Optional is a type in its own right.
Here's a simplified version of the header of Optional, which you can see by command-clicking on the word Optional
in your code from Xcode:
enum Optional<Wrapped> {
Optional is actually an enum, defined in relation to a generic type Wrapped. It has two cases: .none to represent the
absence of a value, and .some to represent the presence of a value, which is stored as its associated value of type
Wrapped.
Let me go through it again: String? is not a String but an Optional<String>.The fact that Optional is a type
means that it has its own methods, for example map and flatMap.
switch result {
case nil:
print("result is nothing")
case is String:
print("result is a String")
case _ as Double:
print("result is not nil, any value that is a Double")
case let myInt as Int where myInt > 0:
print("\(myInt) value is not nil but an int and greater than 0")
case let a?:
print("\(a) - value is unwrapped")
}
switch statements also work with data types other than integers. They work with any data type.Here's an example
of switching on a string:
switch (coordinates) {
case (0, 0, 0): // 1
print("Origin")
case (_, 0, 0): // 2
print("On the x-axis.")
case (0, _, 0): // 3
print("On the y-axis.")
case (0, 0, _): // 4
print("On the z-axis.")
default: // 5
print("Somewhere in space")
}
1. Matches precisely the case where the value is (0,0,0). This is the origin of 3D space.
2. Matches y=0, z=0 and any value of x. This means the coordinate is on the x- axis.
3. Matches x=0, z=0 and any value of y. This means the coordinate is on they- axis.
4. Matches x=0, y=0 and any value of z. This means the coordinate is on the z- axis.
5. Matches the remainder of coordinates.
Note: using the underscore to mean that you don't care about the value.
If you don't want to ignore the value, then you can use it in your switch statement, like this:
switch (coordinates) {
case (0, 0, 0):
print("Origin")
case (let x, 0, 0):
print("On the x-axis at x = \(x)")
case (0, let y, 0):
print("On the y-axis at y = \(y)")
case (0, 0, let z):
print("On the z-axis at z = \(z)")
case (let x, let y, let z):
print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}
Here, the axis cases use the let syntax to pull out the pertinent values. The code then prints the values using string
Note: you don't need a default in this switch statement. This is because the final case is essentially the default—it
matches anything, because there are no constraints on any part of the tuple. If the switch statement exhausts all
possible values with its cases, then no default is necessary.
We can also use the let-where syntax to match more complex cases. For example:
switch (coordinates) {
case (let x, let y, _) where y == x:
print("Along the y = x line.")
case (let x, let y, _) where y == x * x:
print("Along the y = x^2 line.")
default:
break
}
Here, We match the "y equals x" and "y equals x squared" lines.
switch (temperature) {
case 0...49 where temperature % 2 == 0:
print("Cold and even")
default:
print("Temperature out of range or odd")
}
let number = 3
switch number {
case 1, 2:
print("One or Two!")
case 3:
print("Three!")
case 4, 5, 6:
print("Four, Five or Six!")
default:
print("Not One, Two, Three, Four, Five or Six")
}
enum CarModel {
case Standard, Fast, VeryFast
}
switch car {
case .Standard: print("Standard")
case .Fast: print("Fast")
case .VeryFast: print("VeryFast")
}
Since we provided a case for each possible value of car, we omit the default case.
switch theMDY
{
//You can match on a literal tuple:
case (fredsBirthday):
message = "\(date) \(prefix) the day Fred was born"
//You can match on parts of a literal tuple, and copy other elements
//into a constant that you use in the body of the case:
case (bobsBirthday.month, bobsBirthday.day, let year) where year > bobsBirthday.year:
message = "\(date) \(prefix) Bob's \(possessiveNumber(year - bobsBirthday.year))" +
"birthday"
//You can copy one or more elements of the tuple into a constant and then
//add a where clause that further qualifies the case:
case (susansBirthday.month, susansBirthday.day, let year)
where year > susansBirthday.year:
message = "\(date) \(prefix) Susan's " +
"\(possessiveNumber(year - susansBirthday.year)) birthday"
switch (str, x) {
case (.Some,.Some):
print("Both have values")
case (.Some, nil):
print("String has a value")
case (nil, .Some):
print("Int has a value")
case (nil, nil):
print("Neither have values")
}
An example where this is useful is in prepareForSegue. I used to switch based on the segue identifier, but that's
fragile. if you change your storyboard later and rename the segue identifier, it breaks your code. Or, if you use
segues to multiple instances same view controller class (but different storyboard scenes) then you can't use the
segue identifier to figure out the class of the destination.
default:
break
}
}
Version ≥ 3.0
default:
switch(value) {
case 'one':
// do operation one
fallthrough
case 'two':
// do this either independant, or in conjunction with first case
default:
// default operation
}
Version = 2.2
Read JSON
The JSONObjectWithData function takes NSData, and returns AnyObject. You can use as? to convert the result to
your expected type.
do {
guard let jsonData = "[\"Hello\", \"JSON\"]".dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("couldn't encode string as UTF-8")
}
You can pass options: .AllowFragments instead of options: [] to allow reading JSON when the top-level object
isn't an array or dictionary.
Write JSON
Calling dataWithJSONObject converts a JSON-compatible object (nested arrays or dictionaries with strings,
numbers, and NSNull) to raw NSData encoded as UTF-8.
do {
// Convert object to JSON as NSData
let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: [])
print("JSON data: \(jsonData)")
Version = 3.0
do {
guard let jsonData = "[\"Hello\", \"JSON\"]".data(using: String.Encoding.utf8) else {
do {
// Convert object to JSON as NSData
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
print("JSON data: \(jsonData)")
Note: The Following is currently available only in Swift 4.0 and later.
As of Swift 4.0, the Swift standard library includes the protocols Encodable and Decodable to define a standardized
approach to data encoding and decoding. Adopting these protocols will allow implementations of the Encoder and
Decoder protocols take your data and encode or decode it to and from an external representation such as JSON.
Conformance to the Codable protocol combines both the Encodable and Decodable protocols. This is now the
recommended means to handle JSON in your program.
The easiest way to make a type codable is to declare its properties as types that are already Codable. These types
include standard library types such as String, Int, and Double; and Foundation types such as Date, Data, and URL. If
a type's properties are codable, the type itself will automatically conform to Codable by simply declaring the
conformance.
Consider the following example, in which the Book structure conforms to Codable.
Note that standard collections such as Array and Dictionary conform to Codable if they contain codable
types.
By adopting Codable, the Book structure can now be encoded to and decoded from JSON using the Apple
Foundation classes JSONEncoder and JSONDecoder, even though Book itself contains no code to specifically handle
Set encoder.outputFormatting = .prettyPrinted for easier reading. ## Decode from JSON data
In the above example, Book.self informs the decoder of the type to which the JSON should be decoded.
Sometimes you may not need data to be both encodable and decodable, such as when you need only read JSON
data from an API, or if your program only submits JSON data to an API.
If you intend only to write JSON data, conform your type to Encodable.
If you intend only to read JSON data, conform your type to Decodable.
APIs frequently use naming conventions other than the Swift-standard camel case, such as snake case. This can
become an issue when it comes to decoding JSON, since by default the JSON keys must align exactly with your
type's property names. To handle these scenarios you can create custom keys for your type using the CodingKey
protocol.
CodingKeys are generated automatically for types which adopt the Codable protocol, but by creating our own
implementation in the example above we're allow our decoder to match the local camel case publicationDate with
the snake case publication_date as it's delivered by the API.
Without SwiftyJSON, your code would look like this to find the name of the first book in a JSON object:
It removes the need to check every field, as it will return nil if any of them are invalid.
To use SwiftyJSON, download the correct version from the Git repository - there is a branch for Swift 3. Simply drag
the "SwiftyJSON.swift" into your project and import into your class:
import SwiftyJSON
You can create your JSON object using the following two initializers:
or
let jsonObject = JSON(jsonObject) //This could be a string in a JSON format for example
You can then parse your value to a certain data type, which will return an optional value:
If you need to write to your JSON object, you can use subscripts again:
Should you need the original String for the JSON, for example if you need to write it to a file, you can get the raw
value out:
1. Type Safety: Helps you work with sending and receiving JSON in a way that prevents runtime crashes.
2. Idiomatic: Takes advantage of Swift's generics, enumerations, and functional features, without complicated
documentation or magical custom operators.
3. Error Handling: Provides informative error information for commonly occurring JSON errors.
Let's define some example JSON data for use with these examples.
{
"success": true,
"people": [
{
"name": "Matt Mathias",
"age": 32,
"spouse": true
},
{
"name": "Sergeant Pepper",
To deserialize the data, we initialize a JSON object then access a particular key.
do {
let json = try JSON(data: jsonData)
let success = try json.bool("success")
} catch {
// do something with the error
}
We try here because accessing the json for the key "success" could fail--it might not exist, or the value might not
be a boolean.
We can also specify a path to access elements nested in the JSON structure. The path is a comma-separated list of
keys and indices that describe the path to a value of interest.
do {
let json = try JSON(data: jsonData)
let georgiaZipCodes = try json.array("states", "Georgia")
let firstPersonName = try json.string("people", 0, "name")
} catch {
// do something with the error
}
JSON can be directly parsed to a model class that implements the JSONDecodable protocol.
do {
let json = try JSON(data: jsonData)
let people = try json.arrayOf("people", type: Person.self)
} catch {
// do something with the error
}
Any model class that implements the JSONEncodable protocol can be serialized directly to NSData.
{
"Sea Animals": [
{
"name": "Fish",
"question": "How many species of fish are there?" },
{
"name": "Sharks",
"question": "How long do sharks live?"
},
{
"name": "Squid",
"question": "Do squids have brains?"
},
{
"name": "Octopus",
"question": "How big do octopus get?"
},
{
You can perform this simple function to print out your JSON file
func jsonParsingMethod() {
//get the file
let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
let content = try! String(contentsOfFile: filePath!)
If you want to put it in a table view, I would create a dictionary first with an NSObject.
Create a new swift file called ParsingObject and create your string variables.
Make sure that the variable name is the same as the JSON File
. For example, in our project we have name and question so in our new swift file, we will use
Initialize the NSObject we made back into our ViewController.swift var array = ParsingObject Then we would
perform the same method we had before with a minor modification.
func jsonParsingMethod() {
//get the file
let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
let content = try! String(contentsOfFile: filePath!)
struct Todo {
let comment: String
}
And making your Todo struct conforming to JSONDecodable does the trick
{
"todos": [
{
"comment" : "The todo comment"
}
]
}
When you got it from the API, you can serialize it as the previous examples shown in an AnyObject instance. After
that, you can check if the instance is a JSONDictionary instance
The other thing to check, specific for this case because you have an array of Todo in the JSON, is the todos
dictionary
Now that you got the array of dictionaries, you can convert each of them in a Todo object by using flatMap (it will
automatically delete the nil values from the array)
It allows to parse JSON and map it to custom model classes with help of an
<--
operator:
identifier <-- json["id"]
name <-- json["name"]
Example:
Swift model
struct Profile {
var identifier = 0
var name = ""
var link: NSURL?
var weekday: WeekDay = .Monday
var stats = Stats()
var phoneNumbers = [PhoneNumber]()
}
JSON file
{
"id": 15678,
"name": "John Doe",
"link": "https://apple.com/steve",
"weekdayInt" : 3,
"stats": {
"numberOfFriends": 163,
"numberOfFans": 10987
},
"phoneNumbers": [{
"label": "house",
"number": "9809876545"
}, {
"label": "cell",
"number": "0908070656"
}, {
"label": "work",
"number": "0916570656"
}]
}
Mapping
Usage
Installation:
Carthage
CocoaPods
pod 'Arrow'
use_frameworks!
Manually
https://github.com/s4cha/Arrow
As A Framework
Download Arrow from the GitHub repository and build the Framework target on the example project. Then Link
against this framework.
enum Direction {
case up
case down
case left
case right
}
Enum values can be used by their fully-qualified name, but you can omit the type name when it can be inferred:
obj.dir = Direction.up
obj.dir = .up
The most fundamental way of comparing/extracting enum values is with a switch statement:
switch dir {
case .up:
// handle the up case
case .down:
// handle the down case
case .left:
// handle the left case
case .right:
// handle the right case
}
Simple enums are automatically Hashable, Equatable and have string conversions:
enum Action {
case jump
case kick
performAction(.jump)
performAction(.kick)
performAction(.move(distance: 3.3))
performAction(.move(distance: 0.5))
switch action {
case .jump:
...
case .kick:
...
case .move(let distance): // or case let .move(distance):
print("Moving: \(distance)")
}
The guard case syntax can be used for later use extraction:
Enums with associated values are not Equatable by default. Implementation of the == operator must be done
manually:
enum Tree<T> {
case leaf(T)
case branch(Tree<T>, Tree<T>) // error: recursive enum 'Tree<T>' is not marked 'indirect'
}
enum Tree<T> {
case leaf(T)
indirect case branch(Tree<T>, Tree<T>)
}
indirect also works on the whole enum, making any case indirect when necessary:
Enums without any specific type do not expose the rawValue property
enum Rotation {
case up
case right
case down
case left
}
A raw-valued enum automatically conforms to RawRepresentable. You can get an enum value's corresponding raw
You can also create an enum from a raw value using init?(rawValue:):
If you wish to get the hash value of a specific enum you can access its hashValue, The hash value will return the
index of the enum starting from zero.
enum CompassDirection {
case north(Int)
case south(Int)
case east(Int)
case west(Int)
init?(degrees: Int) {
switch degrees {
case 0...45:
self = .north(degrees)
case 46...135:
self = .east(degrees)
case 136...225:
self = .south(degrees)
case 226...315:
self = .west(degrees)
case 316...360:
self = .north(degrees)
default:
return nil
}
}
protocol ChangesDirection {
mutating func changeDirection()
}
enum Direction {
// enumeration cases
case up, down, left, right
dir.changeDirection() // Direction.left
enum Orchestra {
enum Strings {
case violin
case viola
case cello
case doubleBasse
}
enum Keyboards {
case piano
case celesta
case harp
}
enum Woodwinds {
case flute
case oboe
case clarinet
case bassoon
case contrabassoon
}
}
A Protocol specifies initialisers, properties, functions, subscripts and associated types required of a Swift object type
(class, struct or enum) conforming to the protocol. In some languages similar ideas for requirement specifications
of subsequent objects are known as ‘interfaces’.
A declared and defined Protocol is a Type, in and of itself, with a signature of its stated requirements, somewhat
similar to the manner in which Swift Functions are a Type based on their signature of parameters and returns.
Swift Protocol specifications can be optional, explicitly required and/or given default implementations via a facility
known as Protocol Extensions. A Swift Object Type (class, struct or enum) desiring to conform to a Protocol that’s
fleshed out with Extensions for all its specified requirements needs only state its desire to conform to be in full
conformance. The default implementations facility of Protocol Extensions can suffice to fulfil all obligations of
conforming to a Protocol.
Protocols can be inherited by other Protocols. This, in conjunction with Protocol Extensions, means Protocols can
and should be thought of as a significant feature of Swift.
Protocols and Extensions are important to realising Swift’s broader objectives and approaches to program design
flexibility and development processes. The primary stated purpose of Swift’s Protocol and Extension capability is
facilitation of compositional design in program architecture and development. This is referred to as Protocol
Oriented Programming. Crusty old timers consider this superior to a focus on OOP design.
Protocols define interfaces which can be implemented by any struct, class, or enum:
protocol MyProtocol {
init(value: Int) // required initializer
func doSomething() -> Bool // instance method
var message: String { get } // instance read-only property
var value: Int { get set } // read-write instance property
subscript(index: Int) -> Int { get } // instance subscript
static func instructions() -> String // static method
static var max: Int { get } // static read-only property
static var total: Int { get set } // read-write static property
}
Properties defined in protocols must either be annotated as { get } or { get set }. { get } means that the
property must be gettable, and therefore it can be implemented as any kind of property. { get set } means that
the property must be settable as well as gettable.
A protocol may also define a default implementation for any of its requirements through an extension:
extension MyProtocol {
You may also define an abstract type that conforms to multiple protocols:
Version ≥ 3.0
With Swift 3 or better, this is done by separating the list of protocols with an ampersand (&):
Older versions have syntax protocol<...> where the protocols are a comma-separated list between the angle
brackets <>.
protocol AnotherProtocol {
func doSomethingElse()
}
// MyStruct, MyClass & MyEnum must now conform to both MyProtocol & AnotherProtocol
let items : [protocol<MyProtocol, AnotherProtocol>] = [MyStruct(), MyClass(), MyEnum.caseA]
Another way to look into delegate pattern is in terms of object communication. Objects often needs to talks to each
other and to do so an object need conform to a protocol in order to become a delegate of another Object. Once
this setup has been done, the other object talks back to its delegates when interesting things happens.
For example, A view in userinterface to display a list of data should be responsible only for the logic of how data is
displayed, not for deciding what data should be displayed.
Let's dive into a more concrete example. if you have two classes, a parent and a child:
class Parent { }
class Child { }
And you want to notify the parent of a change from the child.
In Swift, delegates are implemented using a protocol declaration and so we will declare a protocol which the
delegate will implement. Here delegate is the parent object.
The child needs to declare a property to store the reference to the delegate:
class Child {
weak var delegate: ChildDelegate?
}
Notice the variable delegate is an optional and the protocol ChildDelegate is marked to be only implemented by
class type (without this the delegate variable can't be declared as a weak reference avoiding any retain cycle. This
means that if the delegate variable is no longer referenced anywhere else, it will be released). This is so the parent
class only registers the delegate when it is needed and available.
Also in order to mark our delegate as weak we must constrain our ChildDelegate protocol to reference types by
adding class keyword in protocol declaration.
In this example, when the child does something and needs to notify its parent, the child will call:
delegate?.childDidSomething()
If the delegate has been defined, the delegate will be notified that the child has done something.
The parent class will need to extend the ChildDelegate protocol to be able to respond to its actions. This can be
done directly on the parent class:
func childDidSomething() {
print("Yay!")
}
}
Or using an extension:
The parent also needs to tell the child that it is the child's delegate:
// In the parent
let child = Child()
child.delegate = self
By default a Swift protocol does not allow an optional function be implemented. These can only be specified if your
protocol is marked with the @objc attribute and the optional modifier.
For example UITableView implements the generic behavior of a table view in iOS, but the user must implement two
delegate classes called UITableViewDelegate and UITableViewDataSource that implement how the specific cells
look like and behave.
You can implement this protocol by changing your class definition, for example:
Any methods not marked optional in the protocol definition (UITableViewDelegate in this case) must be
implemented.
protocol Container {
ciatedtype Element var count: Int { get } subscript(index: Int) -> Element { get set } }
Protocols with associated type requirements can only be used as generic constraints:
// These are allowed, because Container has associated type requirements: func displayValues(container:
Container) { ... } class MyClass { let container: Container } // > error: protocol 'Container' can only be used as a
A type which conforms to the protocol may satisfy an associatedtype requirement implicitly, by providing a given
type where the protocol expects the associatedtype to appear:
> { get { precondition(index == 0) return value } set { precondition(index == 0) value = newValue } } } let container =
ContainerOfOne(value: "Hello")
(Note that to add clarity to this example, the generic placeholder type is named T – a more suitable name would be
Element, which would shadow the protocol's associatedtype Element. The compiler will still infer that the generic
placeholder Element is used to satisfy the associatedtype Element requirement.)
// Expose an 8-bit integer as a collection of boolean values (one for each bit).
extension UInt8: Container {
Other protocols may inherit from the ClassOnlyProtocol, but they will have the same class-only requirement.
Using a class-only protocol allows for reference semantics when the conforming type is unknown.
func takesAFoo(foo:Foo) {
In this example, as Foo is a class-only protocol, the assignment to bar is valid as the compiler knows that foo is a
class type, and therefore has reference semantics.
If Foo was not a class-only protocol, a compiler error would be yielded – as the conforming type could be a value
type, which would require a var annotation in order to be mutable.
protocol Foo {
var bar : String { get set }
}
func takesAFoo(foo:Foo) {
foo.bar = "new value" // error: Cannot assign to property: 'foo' is a 'let' constant
}
func takesAFoo(foo:Foo) {
foo = foo // mutable copy of foo foo.bar = "new value" // no error – satisfies both reference and value semantics }
When applying the weak modifier to a variable of protocol type, that protocol type must be class-only, as weak can
only be applied to reference types.
protocol MyProtocol {
func doSomething()
}
let vc = MyViewController()
vc.doSomething() // Prints "UIViewController default protocol implementation"
extension NotificationName {
static let documentationLaunched = NotificationNames(rawValue:
"DocumentationLaunchedNotification")
}
And an interface can design around any RawRepresentable type or specifically your enum struct
At call site, you can use dot syntax shorthand for the typesafe NotificationName
struct Cell {
var row: Int
var col: Int
Note: It is not necessary that different values in custom type have different hash values, collisions are acceptable. If
hash values are equal, equality operator will be used to determine real equality.
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 3.1 Edition).” iBooks. https://itun.es/us/k5SW7.l
Basic optional use cases include: for a constant (let), use of an optional within a loop (if-let), safely unwrapping an
optional value within a method (guard-let), and as part of switch loops (case-let), defaulting to a value if nil, using
the coalesce operator (??)
This ability is particularly important in Swift because one of the stated design objectives of the language is to work
well with Apple's frameworks. Many (most) of Apple's frameworks utilize nil due to its ease of use and significance
to programming patterns and API design within Objective-C.
In Swift, for a variable to have a nil value, it must be an optional. Optionals can be created by appending either a !
or a ? to the variable type. For example, to make an Int optional, you could use
? optionals must be explicitly unwrapped, and should be used if you aren't certain whether or not the variable will
have a value when you access it. For example, when turning a string into an Int, the result is an optional Int?,
because nil will be returned if the string is not a valid number
! optionals are automatically unwrapped, and should only be used when you are certain that the variable will have a
value when you access it. For example, a global UIButton! variable that is initialized in viewDidLoad()
You can conditionally unwrap an Optional using optional binding and force unwrap an Optional using the ! operator.
Conditionally unwrapping effectively asks "Does this variable have a value?" while force unwrapping says "This
If you force unwrap a variable that is nil, your program will throw an unexpectedly found nil while unwrapping an
optional exception and crash, so you need to consider carefully if using ! is appropriate.
For safe unwrapping, you can use an if-let statement, which will not throw an exception or crash if the wrapped
value is nil:
Note that the scope of the unwrappedNumber variable is inside the if-let statement and outside of the guard block.
You can chain unwrapping of many optionals, this is mainly useful in cases that your code requires more then
variable to run correctly:
var firstName:String?
var lastName:String?
Note that all the variables have to be unwrapped in order to pass successfully the test, otherwise you would have
no way to determine which variables were unwrapped and which weren't.
You can chain conditional statements using your optionals immediately after it is unwrapped. This means no
nested if - else statements!
This operator is able to short-circuit, meaning that if the left operand is non-nil, the right operand will not be
evaluated:
In this example baz will be assigned the unwrapped value of foo if it is non-nil, otherwise it will be assigned the
unwrapped value of bar if it is non-nil, otherwise it will be assigned the fallback value.
struct Foo {
func doSomething() {
print("Hello World!")
}
}
If foo contains a value, doSomething() will be called on it. If foo is nil, then nothing bad will happen – the code will
simply fail silently and continue executing.
The reason that Optional Chaining is named as such is because ‘optionality’ will be propagated through the
members you call/access. What this means is that the return values of any members used with optional chaining
will be optional, regardless of whether they are typed as optional or not.
struct Foo {
var bar : Int
Here foo?.bar is returning an Int? even though bar is non-optional, as foo itself is optional.
As optionality is propagated, methods returning Void will return Void? when called with optional chaining. This can
be useful in order to determine whether the method was called or not (and therefore if the optional has a value).
if foo?.doSomething() != nil {
print("foo is non-nil, and doSomething() was called")
} else {
print("foo is nil, therefore doSomething() wasn't called")
}
Here we’re comparing the Void? return value with nil in order to determine whether the method was called (and
therefore whether foo is non-nil).
To address this, Swift allows any variable to be declared as an optional. This is indicated by the use of a ? or ! after
the type (See Types of optionals)
For example,
The special value nil indicates that no value is currently assigned to this variable.
if possiblyInt != nil {
print("possiblyInt has the value \(possiblyInt!)")
}
Note the use of ! in the print statement to unwrap the optional value.
As an example of a common use of optionals, consider a function that returns an integer from a string containing
digits; It is possible that the string may contain non-digit characters, or may even be empty.
How can a function that returns a simple Int indicate failure? It cannot do so by returning any specific value as this
would preclude that value from being parsed from the string.
In Swift, however, that function can simply return an optional Int. Then failure is indicated by return value of nil.
var someInt?
someInt = parseInt("not an integer") // This function returns nil if parsing fails
if someInt == nil {
print("That isn't a valid integer")
}
first = "Hello"
second = first
first += " World!"
// first == "Hello World!"
// second == "Hello"
Every two structure instances are deemed identical if they compare equal.
Collectively, these traits that differentiate structures from classes are what makes structures value types.
For example:
struct DeliveryRange {
var range: Double
let center: Location
}
let storeLocation = Location(latitude: 44.9871,
longitude: -93.2758)
var pizzaRange = DeliveryRange(range: 200,
center: storeLocation)
print(pizzaRange.range) // 200
print(pizzaRange.center.latitude) // 44.9871
Similar to how you can read values with dot syntax, you can also assign them.
pizzaRange.range = 250
This defines a Repository struct with three stored properties, an integer identifier, a string name, and an optional
string description. The identifier and name are constants, as they've been declared using the let-keyword. Once
set during initialization, they cannot be modified. The description is a variable. Modifying it updates the value of the
structure.
Structure types automatically receive a memberwise initializer if they do not define any of their own custom
initializers. The structure receives a memberwise initializer even if it has stored properties that do not have default
values.
Repository contains three stored properties of which only description has a default value (nil). Further it defines
no initializers of its own, so it receives a memberwise initializer for free:
struct Counter {
private var value = 0
The mutating methods are only available on struct values inside variables.
On the other hand, mutating methods are NOT available on struct values inside constants
Like other functions, closures can accept arguments and return results or throw errors:
let squares = (1...10).map({ $0 * $0 }) // returns [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
let squares = (1...10).map { $0 * $0 }
NSURLSession.sharedSession().dataTaskWithURL(myURL,
completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in
if let data = data {
print("Request succeeded, data: \(data)")
} else {
print("Request failed: \(error)")
}
}).resume()
Many of these parts can be omitted, so there are several equivalent ways to write simple closures:
// The closure's type is specified, so we can omit the parameters' type annotations.
let addInts: (Int, Int) -> Int = { x, y in x + y }
let addInts: (Int, Int) -> Int = { $0 + $1 }
If a function's last parameter is a closure, the closure braces {/} may be written after the function invocation:
foo(3.5) { print("Hello") }
dispatch_async(dispatch_get_main_queue(), {
print("Hello from the main queue")
dispatch_async(dispatch_get_main_queue()) {
print("Hello from the main queue")
}
If a function's only argument is a closure, you may also omit the pair of parentheses () when calling it with the
trailing closure syntax:
bar() { print("Hello") }
bar { print("Hello") }
@noescape parameters
Closure parameters marked @noescape are guaranteed to execute before the function call returns, so using self. is
not required inside the closure body:
func executeNow(scape block: () -> Void) { // Since `block` is @noescape, it's illegal to store it to an external
variable. // We can only call it right here. block() } func executeLater(block: () -> Void) {
dispatch_async(dispatch_get_main_queue()) { // Some time in the future... block() } }
class MyClass {
var x = 0
func showExamples() {
// error: reference to property 'x' in closure requires explicit 'self.' to make capture
semantics explicit
executeLater { x = 1 }
Swift 3 note:
Note that in Swift 3, you no longer mark blocks as @noescape. Blocks are now not escaping by default. In Swift 3,
instead of marking a closure as non-escaping, you mark a function parameter that is an escaping closure as
escaping using the "@escaping" keyword.
The function may, of course, pass the error along to its caller:
However, if the block passed in doesn't throw, the caller is still stuck with a throwing function:
The solution is rethrows, which designates that the function can only throw if its closure parameter throws:
func executeNowOrRethrow(block: () ws -> Void) rethrows { try block() } // "try" is not required here, because the
block can't throw an error. executeNowOrRethrow { print("No errors are thrown from this closure") } // This block
can throw an error, so "try" is required. try executeNowOrRethrow { throw MyError.Example }
Many standard library functions use rethrows, including map(), filter(), and indexOf().
When a closure captures a reference type (a class instance), it holds a strong reference by default:
The closure's capture list can be used to specify a weak or unowned reference:
For more information, see the Memory Management topic, and the Automatic Reference Counting section of The
Swift Programming Language.
Retain cycles
class Game {
var score = 0
let controller: GCController
init(controller: GCController) {
self.controller = controller
// BAD: the block captures self strongly, but self holds the controller
// (and thus the block) strongly, which is a cycle.
self.controller.controllerPausedHandler = {
let curScore = self.score
print("Pause button pressed; current score: \(curScore)")
}
callback(result: data)
}
task.resume()
}
This function is asynchronous, so will not block the thread it is being called on (it won't freeze the interface if called
on the main thread of your GUI application).
Because the task is asynchronous, the output will usually look like this:
Because the code inside of the closure, print("2. Fetched data"), will not be called until the data from the URL is
fetched.
public func closureFunction(closure: ureType) { let z = closure(1, 2) } closureFunction() { (x: Int, y: Int) -> Int in
return x + y }
nt // always returns a value func reticulateSplines() throws // no return value, but may throw an error func
reticulateSplines() throws -> Int // may either return a value or throw an error
Any value which conforms to the ErrorType protocol (including NSError objects) can be thrown as an error.
Enumerations provide a convenient way to define custom errors:
An error indicates a non-fatal failure during program execution, and is handled with the specialized control-flow
constructs do/catch, throw, and try.
func fetchResource(resource: NSURL) ws -> String { if let (statusCode, responseString) = /* ...from elsewhere...*/
{ if case 500..<600 = statusCode { throw NetworkError.serverError(responseString) } else { return responseString }
} else { throw NetworkError.offline } }
b> { let response = try fetchResource(resURL) // If fetchResource() didn't throw an error, execution continues here:
print("Got response: \(response)") ... } catch { // If an error is thrown, we can handle it here. print("Whoops, couldn't
fetch resource: \(error)") }
Any function which can throw an error must be called using try, try?, or try!:
b> { let response = try fetchResource(resURL) } catch { // Handle the error } func foo() throws { // If an error is
thrown, continue passing it up to the caller. let response = try fetchResource(resURL) } // "try?" wraps the function's
return value in an Optional (nil if an error was thrown). if let response = try? fetchResource(resURL) { // no error
was thrown } // "try!" crashes the program at runtime if an error occurs. let response = try! fetchResource(resURL)
The Do-Catch syntax allows to catch a thrown error, and automatically creates a constant named error available in
the catch block:
do {
try throwing()
} catch {
print(error)
}
do {
try throwing()
} catch let oops {
print(oops)
}
It's also possible to chain different catch statements. This is convenient if several types of errors can be thrown in
the Do block.
Here the Do-Catch will first attempt to cast the error as a CustomError, then as an NSError if the custom type was
not matched.
Version = 2.2
do {
try somethingMayThrow()
} catch let custom as CustomError {
print(custom)
} catch let error as NSError {
print(error)
}
Version = 3.0
do {
try somethingMayThrow()
} catch let custom as CustomError {
print(custom)
For example, the following code uses a loadImage(atPath:) function, which loads the image resource at a given path
or throws an error if the image can’t be loaded. In this case, because the image is shipped with the application, no
error will be thrown at runtime, so it is appropriate to disable error propagation.
Handle error:
As Array is a value type, its mutability is defined by whether it is annotated as a var (mutable) or let (immutable).
The type [Int] (meaning: an array containing Ints) is syntactic sugar for Array<T>.
Empty arrays
Array literals
The compiler can usually infer the type of an array based on the elements in the literal, but explicit type
annotations can override the default:
// An immutable array of type [(String, Int)], containing [("bar", 6), ("foo", 4)]
let arrayOfKeyValuePairs = Array(dictionary)
Multi-dimensional arrays
In Swift, a multidimensional array is created by nesting arrays: a 2-dimensional array of Int is [[Int]] (or
Array<Array<Int>>).
let array2x3 = [
[1, 2, 3],
To create a multidimensional array of repeated values, use nested calls of the array initializer:
We can extract values of a given type and create a new Array of that specific type. Let's say we want to extract all
the Int(s) and put them into an Int Array in a safe way.
Now numbers is defined as [Int]. The flatMap function discard all nil elements and the result thus contains only
the following values:
[1, 2, 3]
print(sum) // 36
We're passing 0 into the initial value, as that's the logical initial value for a summation. If we passed in a value of N,
the resulting sum would be N + 36. The closure passed to reduce has two arguments. accumulator is the current
accumulated value, which is assigned the value that the closure returns at each iteration. element is the current
element in the iteration.
As in this example, we're passing an (Int, Int) -> Int closure to reduce, which is simply outputting the addition
of the two inputs – we can actually pass in the + operator directly, as operators are functions in Swift:
extension SequenceType {
public func flatMap<S : SequenceType>(transform: (Self.Generator.Element) throws -> S) rethrows
-> [S.Generator.Element]
}
Each sequence from the transformation will be concatenated, resulting in an array containing the combined
elements of each sequence – [S.Generator.Element].
For example, we can use it to take an array of prime strings and combine their characters into a single array:
let primes = ["2", "3", "5", "7", "11", "13", "17", "19"]
let allCharacters = primes.flatMap { $0.characters }
// => "["2", "3", "5", "7", "1", "1", "1", "3", "1", "7", "1", "9"]"
As flatMap(_:) will concatenate the sequences returned from the transformation closure calls, it can be used to
flatten a multidimensional array – such as a 2D array into a 1D array, a 3D array into a 2D array etc.
This can simply be done by returning the given element $0 (a nested array) in the closure:
print(lazilyFlattenedArray.contains(4)) // true
In the above example, flatten() will return a FlattenBidirectionalCollection, which will lazily apply the
flattening of the array. Therefore contains(_:) will only require the first two nested arrays of array2D to be
flattened – as it will short-circuit upon finding the desired element.
extension SequenceType {
public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows ->
[T]
}
The difference with this version of flatMap(_:) is that it expects the transform closure to return an Optional value
T? for each of the elements. It will then safely unwrap each of these optional values, filtering out nil – resulting in
an array of [T].
For example, you can this in order to transform a [String] into a [Int] using Int's failable String initializer,
filtering out any elements that cannot be converted:
print(numbersThatCanBeConverted) // [1, 3, 4, 6]
You can also use flatMap(_:)'s ability to filter out nil in order to simply convert an array of optionals into an array
of non-optionals:
print(numbers) // [1, 2, 3]
Subscripting an Array with a Range returns an ArraySlice. It's a subsequence of the Array.
Although an ArraySlice conforms to CollectionType and can be used with sort, filter, etc, its purpose is not for
But what if we don't know the index but we know the value of element to be removed!
So here is the simple extension to an array which will allow us to remove an element from array easily without
knowing it's index:
Swift3
extension Array where Element: Equatable {
e.g.
array.remove("nonexistent")
print("\(array)") //["abc", "pqr", "stu", "xyz"]
//if provided element value is not present, then it will do nothing!
Also if, by mistake, we did something like this: array.remove(25) i.e. we provided value with different data type,
compiler will throw an error mentioning-
cannot convert value to expected argument type
But there will be unexpected results if the elements in the array are not consistent:
To properly sort Strings by the numeric value they contain, use compare with the .numeric option:
extension Array {
subscript (safe index: Int) -> Element? {
return indices ~= index ? self[index] : nil
}
}
example:
struct Person {
var age : Int
}
let people = [Person(age: 22), Person(age: 41), Person(age: 23), Person(age: 30)]
For example, we could use it to transform an array of Ints into an array of Strings like so:
map(_:) will iterate through the array, applying the given closure to each element. The result of that closure will be
used to populate a new array with the transformed elements.
Since String has an initialiser that receives an Int we can also use this clearer syntax:
A map(_:) transform need not change the type of the array – for example, it could also be used to multiply an array
of Ints by two:
Reverse an Array Note: The result is not performed on the array the method is called on and must be put
into its own variable.
exampleArray = exampleArray.reverse()
//exampleArray = [9, 8, 7, 6, 5, 3, 2]
As Array conforms to SequenceType, we can generate a new array of the sorted elements using a built in sort
method.
array.sortInPlace() // [1, 2, 3]
Version ≥ 3.0
array.sort() // [1, 2, 3]
Note: In order to use the above methods, the elements must conform to the Comparable protocol.
You may also sort an array using a closure to define whether one element should be ordered before another –
which isn't restricted to arrays where the elements must be Comparable. For example, it doesn't make sense for a
struct Landmark {
let name : String
let metersTall : Int
}
Note: String comparison can yield unexpected results if the strings are inconsistent, see Sorting an Array
of Strings.
You can use the minElement() and maxElement() methods to find the minimum or maximum element in a given
sequence. For example, with an array of numbers:
As of Swift 3, the methods have been renamed to min() and max() respectively:
The returned values from these methods are Optional to reflect the fact that the array could be empty – if it is, nil
will be returned.
You may also use the above methods with a custom closure, defining whether one element should be ordered
before another, allowing you to find the minimum or maximum element in an array where the elements aren't
necessarily Comparable.
struct Vector2 {
let dx : Double
let dy : Double
let vectors = [Vector2(dx: 3, dy: 2), Vector2(dx: 1, dy: 1), Vector2(dx: 2, dy: 2)]
exampleArray.removeAtIndex(3)
//exampleArray = [1, 2, 3, 5, 6, 7, 8, 9, 10]
exampleArray.removeLast()
//exampleArray = [1, 2, 3, 5, 6, 7, 8, 9]
exampleArray.removeFirst()
//exampleArray = [2, 3, 5, 6, 7, 8, 9]
Example
sequence1 sequence1
1 "Dog"
2 "Cat"
3 "Tiger"
This is useful when you want to perform some kind of comparation between the n-th element of each Array.
Example
you want to check whether each value into list1 is the double of the related value in list0.
struct Box {
let name: String
let thingsInside: Int
}
let boxes = [
Box(name: "Box 0", thingsInside: 1),
Box(name: "Box 1", thingsInside: 2),
Box(name: "Box 2", thingsInside: 3),
Box(name: "Box 3", thingsInside: 1),
Box(name: "Box 4", thingsInside: 2),
Box(name: "Box 5", thingsInside: 3),
Box(name: "Box 6", thingsInside: 1)
]
we can group the boxes by the thingsInside property in order to get a Dictionary where the key is the number of
things and the value is an array of boxes.
Changing the new array will not change the original array.
Copied arrays will share the same space in memory as the original until they are changed. As a result of this there is
a performance hit when the copied array is given its own space in memory as it is changed for the first time.
Note: The value at index two is the third value in the Array. Arrays use a zero based index which means the first
element in the Array is at index 0.
Filters can have complex conditions like filtering only even numbers:
exampleArray.indexOf(3) // Optional(2)
There are methods for the first, last, maximum or minimum value in an Array. These methods will return nil if the
Array is empty.
exampleArray.first // Optional(1)
exampleArray.last // Optional(5)
exampleArray.maxElement() // Optional(5)
exampleArray.minElement() // Optional(1)
Declare a dictionary with keys and values by specifying them in a comma separated list. The types can be inferred
from the types of keys and values.
The values of a dictionary can be iterated through using the values property:
Similarly, the keys of a dictionary can be iterated through using its keys property:
To get all key and value pair corresponding to each other (you will not get in proper order since it is a Dictionary)
Note that a Dictionary, unlike an Array, in inherently unordered-that is, there is no guarantee on the order during
iteration.
If you want to access multiple levels of a Dictionary use a repeated subscript syntax.
books[5] = nil
//books [:]
books[6] = "Deleting from Dictionaries"
//books = [6: "Deleting from Dictionaries"]
let removedBook = books.removeValueForKey(6)
//books = [:]
//removedValue = "Deleting from Dictionaries"
Characters can be initialized from string literals, as long as the literal contains only one grapheme cluster:
String Interpolation
String interpolation allows injecting an expression directly into a string literal. This can be done with all types of
values, including strings, integers, floating point numbers and more.
The syntax is a backslash followed by parentheses wrapping the value: \(value). Any valid expression may appear
in the parentheses, including function calls.
let number = 5
let interpolatedNumber = "\(number)" // string is "5"
let fortyTwo = "\(6 * 7)" // string is "42"
For custom types, the default behavior of string interpolation is that "\(myobj)" is equivalent to String(myobj), the
same representation used by print(myobj). You can customize this behavior by implementing the
CustomStringConvertible protocol for your type.
Version ≥ 3.0
For Swift 3, in accordance with SE-0089, String.init<T>(_:) has been renamed to String.init<T>(describing:).
The string interpolation "\(myobj)" will prefer the new String.init<T: LosslessStringConvertible>(_:)
initializer, but will fall back to init<T>(describing:) if the value is not LosslessStringConvertible.
Special Characters
Certain characters require a special escape sequence to use them in string literals:
Character Meaning
\0 the null character
\\ a plain backslash, \
\t a tab character
\v a vertical tab
\r a carriage return
\n a line feed ("newline")
\" a double quote, "
\' a single quote, '
\u{n} the Unicode code point n (in hexadecimal)
Append to a mutable string using the += compound assignment operator, or using a method:
The separator is the empty string by default, so ["a", "b", "c"].joined() == "abc".
Decomposing Strings
The unicodeScalars are the Unicode code points that make up a string (notice that ??? is one grapheme cluster,
but 3 code points — 3607, 3637, 3656 — so the length of the resulting array is not the same as with characters):
You can encode and decompose strings as UTF-8 (a sequence of UInt8s) or UTF-16 (a sequence of UInt16s):
Array(str.utf8) // [224, 184, 151, 224, 184, 181, 224, 185, 136, 240, 159, 145, 140, 226, 145,
160, 33]
Array(str.utf16) // [3607, 3637, 3656, 55357, 56396, 9312, 33]
A string's characters, unicodeScalars, utf8, and utf16 are all Collections, so you can get their count and iterate
over them:
str.characters.count // 4
str.unicodeScalars.count // 6
str.utf8.count // 17
str.utf16.count // 7
if str.isEmpty {
// do something if the string is empty
}
Check whether two strings are equal (in the sense of Unicode canonical equivalence):
// "LATIN SMALL LETTER A WITH ACUTE" == "LATIN SMALL LETTER A" + "COMBINING ACUTE ACCENT"
"\u{e1}" == "a\u{301}" // true
Version = 3.0
let letters = CharacterSet.letters
The new CharacterSet struct that is also bridged to the Objective-C NSCharacterSet class define several predefined
sets as:
decimalDigits
capitalizedLetters
alphanumerics
Version = 3.0
let phrase = "Test case"
let charset = CharacterSet(charactersIn: "t")
Version = 3.0
let phrase = "Test case"
let charset = CharacterSet(charactersIn: "t")
Note: endIndex is after the end of the string (i.e. string[string.endIndex] is an error, but
string[string.startIndex] is fine). Also, in an empty string (""), string.startIndex == string.endIndex is true.
Be sure to check for empty strings, since you cannot call startIndex.successor() on an empty string.
Version = 3.0
Instead, those operations are moved to the collection, which is now responsible for incrementing and
decrementing its indices.
Note: we're using currentIndex as a variable name to avoid confusion with the .index method.
(Or you could just reverse the string first, but if you don't need to go all the way through the string you probably
would prefer a method like this)
Version = 3.0
var currentIndex: String.Index? = string.index(before: string.endIndex)
Note, Index is an object type, and not an Int. You cannot access a character of string as follows:
If you might exceed the string's bounds, or you want to specify a limit you can use:
Alternatively one can just iterate through the characters in a string, but this might be less useful depending on the
context:
for c in string.characters {
print(c)
}
Version = 3.0
let startDate = "23:51"
Version = 3.0
let myText = "MyText"
Note that the Swift Character can be composed of multiple Unicode code points, but appears to be a single
character. This is called an Extended Grapheme Cluster.
Conversions
Note that for UTF-8 and UTF-16 the conversion is not always this easy because things like emoji cannot be encoded
with a single UTF-16 value. It takes a surrogate pair.
Note that doing this returns an Optional value, which should be unwrapped accordingly before being used.
String to Data/NSData
Version = 3.0
let data = string.data(using: .utf8)
Version = 2.2
let data = string.dataUsingEncoding(NSUTF8StringEncoding)
Data/NSData to String
Version = 3.0
let string = String(data: data, encoding: .utf8)
Version = 2.2
let string = String(data: data, encoding: NSUTF8StringEncoding)
Decimal to Hexadecimal
let number: Int = 13627
let str1 = String(format: "%2X", number) // 353B
let str2 = String(format: "%2x", number) // 353b (notice the lowercase b)
Alternatively one could use specialized initializer that does the same:
Version = 2.2
let text = "AaBbCc"
let uppercase = text.uppercaseString // "AABBCC"
let lowercase = text.lowercaseString // "aabbcc"
Version = 3.0
let text = "AaBbCc"
let uppercase = text.uppercased() // "AABBCC"
We can count the number of times the Character appears into the String using
Method stringByTrimmingCharactersInSet returns a new string made by removing from both ends of the String
characters contained in a given character set.
let trimmedWhiteSpace =
someString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
// "Swift Language \n"
Note: all these methods belong to Foundation. Use import Foundation if Foundation isn't already imported via other
libraries like Cocoa or UIKit.
Suppose you want to be able to compute the factorial of an Int. You can add a computed property in an extension:
extension Int {
var factorial: Int {
return (1..<self+1).reduce(1, combine: *)
}
}
Then you can access the property just as if it had been included in original Int API.
extension ExtensionOf {
//new functions and get-variables
}
To reference the instance of the extended object, self can be used, just as it could be used
To create an extension of String that adds a .length() function which returns the length of the string, for example
extension String {
func length() -> Int {
return self.characters.count
}
}
"Hello, World!".length() // 13
Extensions can also contain get variables. For example, adding a .length variable to the string which returns the
length of the string
extension String {
var length: Int {
get {
return self.characters.count
}
}
}
"Hello, World!".length // 13
extension Int {
init?(_ string: NSString) {
self.init(string as String) // delegate to the existing Int.init(String) initializer
}
}
This example gets the character inside a String using the given index:
Version = 2.2
extension String {
subscript(index: Int) -> Character {
let newIndex = startIndex.advancedBy(index)
return self[newIndex]
}
}
It works pretty much like abstract classes when regarding a functionality you want to be available in all the classes
that implements some protocol (without having to inherit from a base common class).
protocol FooProtocol {
func doSomething()
}
extension FooProtocol {
func doSomething() {
Example of use
extension Bool {
public mutating func toggle() -> Bool {
self = !self
return self
}
}
Source
You can declare a set with values by using the array literal syntax.
You can use the intersect(_:) method to create a new set containing all the values common to both sets.
You can use the union(_:) method to create a new set containing all the unique values from each set.
Notice how the value "Green" only appears once in the new set.
You can use the exclusiveOr(_:) method to create a new set containing the unique values from either but not
both sets.
Notice how the value "Green" doesn't appear in the new set, since it was in both sets.
You can use the subtract(_:) method to create a new set containing values that aren't in a specific set.
Notice how the value "Green" doesn't appear in the new set, since it was also in the second set.
Swift 3 introduces the CountedSet class (it's the Swift version of the NSCountedSet Objective-C class).
CountedSet, as suggested by the name, keeps track of how many times a value is present.
countedSet.count(for: 1) // 3
countedSet.count(for: 2) // 1
You can use the insert(_:) method to add a new item into a set.
favoriteColors.insert("Orange")
//favoriteColors = {"Red", "Green", "Orange", "Blue"}
You can use the remove(_:) method to remove an item from a set. It returns optional containing value that was
removed or nil if value was not in the set.
You can use the contains(_:) method to check whether a set contains a value. It will return true if the set contains
that value.
if favoriteColors.contains("Blue") {
print("Who doesn't like blue!")
}
// Prints "Who doesn't like blue!"
// mymodule/module.modulemap
module mymodule {
header "defs.h"
}
// demo.swift
import mymodule
print("Empty color: \(Color())")
Use the -I ctory flag to tell swiftc where to find the module:
swiftc -I . demo.swift # "-I ." means "search for modules in the current directory"
For more information about the module map syntax, see the Clang documentation about module maps.
Bridging headers
A bridging header makes additional Objective-C and C declarations visible to Swift code. When adding project files,
Xcode may offer to create a bridging header automatically:
Inside the bridging header, import whichever files are necessary to use from code:
// MyApp-Bridging-Header.h
#import "MyClass.h" // allows code in this module to use MyClass
Generated Interface
Click the Related Items button (or press ?1), then select Generated Interface to see the Swift interface that will be
generated from an Objective-C header.
// defs.h
struct Color {
int red, green, blue;
};
// demo.swift
extension Color: CustomStringConvertible { // extension on a C struct
public var description: String {
return "Color(red: \(red), green: \(green), blue: \(blue))"
}
}
print("MAX_VALUE is: \(MAX_VALUE)") // C macro becomes a constant
let color = Color(red: 0xCA, green: 0xCA, blue: 0xD0) // C struct initializer
print("The color is \(color)")
$ swiftc demo.swift -import-objc-header defs.h && ./demo MAX_VALUE is: 255 The color is Color(red: 202, green:
202, blue: 208)
On Linux, the C standard library is exposed via the Glibc module; on Apple platforms it's called Darwin.
EFINED_FOR_SWIFT; @end
Now you can replace the API with a more "Swifty" extension. In this case, we can use an optional return value,
filtering out NSNotFound:
xOfObject(obj: AnyObject) -> Int? { let idx = __indexOfObject(obj) if idx == NSNotFound { return nil } return idx } } //
Swift code, using "if let" as it should be: let myobj = MyClass() if let idx = myobj.indexOfObject(something) { // do
something with idx }
In most cases you might want to restrict whether or not an argument to an Objective-C function could be nil. This
is done using _Nonnull keyword, which qualifies any pointer or block reference:
void
doStuff(const void *const _Nonnull data, void (^_Nonnull completion)())
{
// complex asynchronous code
}
With that written, the compiler shall emit an error whenever we try to pass nil to that function from our Swift code:
doStuff(
nil, // error: nil is not compatible with expected argument type 'UnsafeRawPointer'
nil) // error: nil is not compatible with expected argument type '() -> Void'
The opposite of _Nonnull is _Nullable, which means that it is acceptable to pass nil in this argument. _Nullable is
also the default; however, specifying it explicitly allows for more self-documented and future-proof code.
To further help the compiler with optimising your code, you also might want to specify if the block is escaping:
void
callNow(__attribute__((noescape)) void (^_Nonnull f)())
{
// f is not stored anywhere
}
With this attribute we promise not to save the block reference and not to call the block after the function has
finished execution.
Inside a module named "MyModule", Xcode generates a header named MyModule-Swift.h which exposes public
Swift classes to Objective-C. Import this header in order to use the Swift classes:
// MySwiftClass.swift in MyApp
import Foundation
// The class must be `public` to be visible, unless this target also has a bridging header
#import "MyViewController.h"
Objective-C Generated Interface Header Name: controls the name of the generated Obj-C header.
Install Objective-C Compatibility Header: whether the -Swift.h header should be a public header (for
framework targets).
In another module
Using @import MyFramework; imports the whole module, including Obj-C interfaces to Swift classes (if the
aforementioned build setting is enabled).
func hello()
{
print("Hello World")
}
Call a function with no parameters by writing its name followed by an empty pair of parenthesis.
hello()
//output: "Hello World"
Note: The \(number1) syntax is basic String Interpolation and is used to insert the integer into the String.
Functions with parameters are called by specifying the function by name and supplying an input value of the type
used in the function declaration.
magicNumber(5)
//output: "5 Is the magic number
let example: Int = 10
magicNumber(example)
//output: "10 Is the magic number"
When a function uses multiple parameters the name of the first parameter is not required for the first but is on
subsequent parameters.
Setting the default value in the function declaration allows you to call the function without giving any input values.
magicNumber()
//output: "15 Is the magic number"
Example
struct DaysOfWeek {
Subscript Usage
Subscripts Options:
Subscripts can take any number of input parameters, and these input parameters can be of any type. Subscripts
can also return any type. Subscripts can use variable parameters and variadic parameters, but cannot use in-out
parameters or provide default parameter values.
Example:
struct Food {
Usage
Instance Methods
Instance methods are defined with a func declaration inside the definition of the type, or in an extension.
class Counter {
var count = 0
func increment() {
count += 1
}
}
Type Methods
Type methods are defined with the static func keywords. (For classes, class func defines a type method that can
be overridden by subclasses.)
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod() // type method is called on the SomeClass type itself
This works fine for finding the sum of two numbers, but for finding the sum of three we'd have to write another
function:
and one with four parameters would need another one, and so on. Swift makes it possible to define a function with
a variable number of parameters using a sequence of three periods: .... For example,
Notice how the numbers parameter, which is variadic, is coalesced into a single Array of type [Int]. This is true in
general, variadic parameters of type T... are accessible as a [T].
let a = sum(1, 2) // a == 3
let b = sum(3, 4, 5, 6, 7) // b == 25
A variadic parameter in Swift doesn't have to come at the end of the parameter list, but there can only be one in
each function signature.
Sometimes, it's convenient to put a minimum size on the number of parameters. For example, it doesn't really
make sense to take the sum of no values. An easy way to enforce this is by putting some non-variadic required
parameters and then adding the variadic parameter after. To make sure that sum can only be called with at least
two parameters, we can write
func sum(_ n1: Int, _ n2: Int, _ numbers: Int...) -> Int {
return numbers.reduce(n1 + n2, combine: +)
}
sum(1, 2) // ok
sum(3, 4, 5, 6, 7) // ok
sum(1) // not ok
sum() // not ok
Prefix: >x
Infix: x > y
Postfix: xb>
Function types can thus be used as parameters types or as return types for nesting functions.
updateFruit(fruit: &apples)
This allows reference semantics to be applied to types which would normally have value semantics.
If you want to call a function that can throw an error, you need to use the try keyword in a do block:
do {
try errorThrower()
}
let c = findHypotenuse(3, b: 5)
//c = 5.830951894845301
loadData("123") { result in
print(result)
}
Now that our function has been defined, let's call it and pass in some code:
closedFunc() { Void in
print("Over already")
}
By using a trailing closure with our function call, we can pass in code (in this case, print) to be executed at some
point within our closedFunc() function.
Just beginning
Over already
A more specific use case of this could include the execution of code between two classes:
class A: NSObject {
var closure : ()?
Literals
Underscores (_) may be used to separate digits in numeric literals. Leading zeros are ignored.
Floating point literals may be specified using significand and exponent parts (gnificand» e «exponent» for decimal;
b> «significand» p «exponent» for hexadecimal).
Rounds the value to the nearest whole number with x.5 rounding up (but note that -x.5 rounds down).
round(3.000) // 3
round(3.001) // 3
round(3.499) // 3
round(3.500) // 4
round(3.999) // 4
round(-3.000) // -3
round(-3.001) // -3
round(-3.499) // -3
round(-3.500) // -4 *** careful here ***
round(-3.999) // -4
ceil
Rounds any number with a decimal value up to the next larger whole number.
ceil(3.000) // 3
ceil(3.001) // 4
ceil(3.999) // 4
floor
Rounds any number with a decimal value down to the next smaller whole number.
floor(3.000) // 3
floor(3.001) // 3
floor(3.999) // 3
floor(-3.000) // -3
floor(-3.001) // -4
floor(-3.999) // -4
Int
Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3
Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3
Notes
The maximum value for UInt32 is 4,294,967,295 (that is, 2^32 - 1).
Examples:
Coin flip
Dice roll
Notes
let x = 42 // x is an Int
doSomething1(Double(x)) // convert x to a Double
doSomething2(UInt(x)) // convert x to a UInt
Int8(-129.0) // fatal error: floating point value cannot be converted to Int8 because it is less
than Int8.min
Int8(-129) // crash: EXC_BAD_INSTRUCTION / SIGILL
Int8(-128) // ok
Int8(-2) // ok
Int8(17) // ok
Int8(127) // ok
Int8(128) // crash: EXC_BAD_INSTRUCTION / SIGILL
Int8(128.0) // fatal error: floating point value cannot be converted to Int8 because it is greater
than Int8.max
Int(-2.2) // -2
Int(-1.9) // -1
Int(-0.1) // 0
Int(1.0) // 1
Int(1.2) // 1
Int(1.9) // 1
Int(2.0) // 2
Int(Float(1_000_000_000_000_000_000)) // 999999984306749440
pow(BASE, EXPONENT)
In the code below, the base (5) is set to the power of the exponent (2) :
class Dog {}
class Animal {}
class Dog: Animal {}
In this example, Animal could also be a protocol that Dog conforms to.
class Dog {
var name = ""
var dogYearAge = 0
}
Classes can also define methods that can be called on the instances, they are declared similar to normal functions,
just inside the class:
class Dog {
func bark() {
print("Ruff!")
}
}
dog.bark()
class Dog {
var name = ""
}
same Dog instance otherDog.name = "Rover" // modifying otherDog also modifies firstDog print(firstDog.name) //
prints "Rover"
Because classes are reference types, even if the class is a constant, its variable properties can still be modified.
class Dog {
var name: String // name is a variable property.
let age: Int // age is a constant property.
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Test whether two objects are identical (point to the exact same instance) using
===
:
class Dog: Equatable {
let name: String
init(name: String) { self.name = name }
}
spot1 === spot2 // false, because the dogs are different instances
spot1 !== spot2 // true
class Dog: Animal, Pet { ... } // This will result in a compiler error.
Instead you are encouraged to use composition when creating your types. This can be accomplished by using
protocols.
init() {
// initialize timer
}
deinit {
// code
timer.invalidate()
}
}
You can reuse the same name for the newly bound variable, shadowing the original:
Apply further constraints after the optional binding using a where clause:
if let unwrappedNum = num e unwrappedNum % 2 == 0 { print("num is non-nil, and it's an even number") }
If you're feeling adventurous, interleave any number of optional bindings and where clauses:
In Swift 3, where clauses have been replaced (SE-0099): simply use another , to separate optional bindings and
boolean conditions.
Guard checks for a condition, and if it is false, it enters the branch. Guard check branches must leave its enclosing
block either via return, break, or continue (if applicable); failing to do so results in a compiler error. This has the
advantage that when a guard is written it's not possible to let the flow continue accidentally (as would be possible
with an if).
Using guards can help keep nesting levels low, which usually improves the readability of the code.
Guard can also check if there is a value in an optional, and then unwrap it in the outer scope:
Guard can combine optional unwrapping and condition check using where keyword:
let num = 10
if num == 10 {
// Code inside this block only executes if the condition was true.
print("num is 10")
}
if statements accept else if and else blocks, which can test alternate conditions and provide a fallback:
let num = 10
if num < 10 { // Execute the following code if the first condition is true.
print("num is less than 10")
} else if num == 10 { // Or, if not, check the next condition...
print("num is 10")
} else { // If all else fails...
print("all other conditions were false, so num is greater than 10")
}
Basic operators like && and || can be used for multiple conditions:
If num == 10 was false, the second value wouldn't be evaluated. This is known as short-circuit evaluation.
If you wanted to determine the minimum and maximum of two variables, you could use if statements, like so:
let a = 5
let b = 10
let min: Int
if a < b {
min = a
} else {
min = b
}
if a > b {
max = a
The ternary conditional operator takes a condition and returns one of two values, depending on whether the
condition was true or false. The syntax is as follows: This is equivalent of having the expression:
The above code can be rewritten using ternary conditional operator as below:
let a = 5
let b = 10
let min = a < b ? a : b
let max = a > b ? a : b
In the first example, the condition is a < b. If this is true, the result assigned back to min will be of a; if it's false, the
result will be the value of b.
Note: Because finding the greater or smaller of two numbers is such a common operation, the Swift standard
library provides two functions for this purpose: max and min.
The nil-coalescing operator is shorthand for the code below that uses a ternary operator:
a != nil ? a! : b
userEnteredSpeed = "Fast"
print(userEnteredSpeed ?? defaultSpeed) // ouputs "Fast"
Swift infers the type of variable, so you don't always have to declare variable type:
Variable names aren't restricted to letters and numbers - they can also contain most other unicode characters,
although there are some restrictions
Constant and variable names cannot contain whitespace characters, mathematical symbols, arrows,
private-use (or invalid) Unicode code points, or line- and box-drawing characters. Nor can they begin with
a number
Source developer.apple.com
var myProperty = 5 {
willSet {
print("Will set to \(newValue). It was previously \(myProperty)")
}
didSet {
print("Did set to \(myProperty). It was previously \(oldValue)")
}
}
myProperty = 6
// prints: Will set to 6, It was previously 5
// prints: Did set to 6. It was previously 5
willSet is called before myProperty is set. The new value is available as newValue, and the old value is still
available as myProperty.
didSet is called after myProperty is set. The old value is available as oldValue, and the new value is now
Note: didSet and willSet will not be called in the following cases:
The parameter names for oldValue and newValue of didSet and willSet can also be declared to increase
readability:
var myFontSize = 10 {
willSet(newFontSize) {
print("Will set font to \(newFontSize), it was \(myFontSize)")
}
didSet(oldFontSize) {
print("Did set font to \(myFontSize), it was \(oldFontSize)")
}
}
Caution: While it is supported to declare setter parameter names, one should be cautious not to mix
names up:
willSet(oldValue) and didSet(newValue) are entirely legal, but will considerably confuse readers
of your code.
class Dog {
var name = ""
}
In the above case, instances of Dog have a property named name of type String. The property can be accessed and
modified on instances of Dog:
These types of properties are considered stored properties, as they store something on an object and affect its
memory.
var pi = 3.14
class Circle {
var radius = 0.0
var circumference: Double {
get {
return pi * radius * 2
}
set {
radius = newValue / pi / 2
}
}
}
func printSomething() {
let localString = "I'm local!"
print(localString)
}
func printSomethingAgain() {
print(localString) // error
}
func useGlobalString() {
print(globalString) // works!
}
for i in 0..<2 {
print(globalString) // works!
}
class GlobalStringUser {
var computeGlobalString {
return globalString // works!
}
}
struct Dog {
static var noise = "Bark!"
}
In a class, you can use the class keyword instead of static to make it overridable. However, you can only apply
this on computed properties:
class Animal {
class var noise: String {
return "Animal noise!"
}
}
class Pig: Animal {
override class var noise: String {
return "Oink oink!"
}
}
This list of types also can have name of the elements and use those names to refer to the values of the individual
elements.
Common use -
We can use a tuple type as the return type of a function to enable the function to return a single tuple containing
multiple values
They can also be named when being used as a variable and even have the ability to have optional values inside:
//Later On
numbers = (nil, "dos", 3)
print(numbers.optionalFirst)// nil
print(numbers.middle)//"dos"
print(numbers.last)//3
This syntax can be used regardless of if the tuple has unnamed properties:
If you assign parameter names, they can be used from the return value:
func doubleRadius(ofCircle circle: (center: (x: CGFloat, y: CGFloat), radius: CGFloat)) -> (center:
(x: CGFloat, y: CGFloat), radius: CGFloat) {
return (circle.center, circle.radius * 2.0)
}
If you use a certain tuple type in more than one place, you can use the typealias keyword to name your tuple type.
If you find yourself doing this too often, however, you should consider using a struct instead.
Given 2 variables
(a, b) = (b, a)
Result:
(a, b, c, d) = (d, c, b, a)
print(a, b, c, d) // 3, 2, 1, 0
switch switchTuple {
case (true, false):
// do something
case (true, true):
// do something
case (false, true):
// do something
case (false, false):
// do something
}
Bools are used in control-flow statements as conditions. The if statement uses a Boolean condition to determine
which block of code to run:
where question is a boolean that is evaluated and answerIfTrue is the value returned if the question is true, and
answerIfFalse is the value returned if the question is false.
if question {
answerIfTrue
} else {
answerIfFalse
}
func actionDark() {
func actionJedi() {
print("Welcome to the Jedi order")
}
The AND (&&) operator returns true only if both operands evaluate to be true. The following example will return
false because only one of the two operand expressions evaluates to true:
The XOR (^) operator returns true if one and only one of the two operands evaluates to true. For example, the
following code will return true since only one operator evaluates to be true:
Each arrow indicates one object retaining another (a strong reference). Unless the cycle is broken, the memory for
these objects will never be freed.
A retain cycle is created when two instances of classes reference each other:
let a = A()
let b = B()
a.b = b // a retains b
b.a = a // b retains a -- a reference cycle
Both instances they will live on until the program terminates. This is a retain cycle.
Weak References
To avoid retain cycles, use the keyword weak or unowned when creating references to break retain cycles.
a.b = b // a retains b
b.a = a // b holds a weak reference to a -- not a reference cycle
When working with closures, you can also use weak and unowned in capture lists.
If you need to supply a type-punned pointer to a C function, use toOpaque method of the Unmanaged structure to
obtain a raw pointer, and fromOpaque to recover the original instance:
setupDisplayLink() {
let pointerToSelf: UnsafeRawPointer = Unmanaged.passUnretained(self).toOpaque()
CVDisplayLinkSetOutputCallback(self.displayLink, self.redraw, pointerToSelf)
}
Note that, if using passUnretained and counterparts, it's necessary to take all precautions as with unowned
references.
To interact with legacy Objective-C APIs, one might want to manually affect reference count of a certain object. For
that Unmanaged has respective methods retain and release. Nonetheless, it is more desired to use passRetained
and takeRetainedValue, which perform retaining before returning the result:
These solutions should always be the last resort, and language-native APIs sould always be preferred.
Generic Functions
In this case, the generic placeholder is T. When you come to call the function, Swift can infer the type of T for you (as
it simply acts as a placeholder for an actual type).
Here we’re passing two integers to the function. Therefore Swift is inferring T == Int – thus the function signature
is inferred to be (Int, Int) -> Int.
Because of the strong type safety that generics offer – both the arguments and return of the function must be the
same type. Therefore the following will not compile:
struct Foo {}
let randomOutput = pickRandom(foo, 5) // error: cannot convert value of type 'Int' to expected
argument type 'Foo'
Generic Types
In order to use generics with classes, structs or enums, you can define the generic placeholder after the type name.
This generic placeholder will require a type when you come to use the class Bar. In this case, it can be inferred from
the initialiser init(baz:T).
Here the generic placeholder T is inferred to be of type String, thus creating a Bar<String> instance. You can also
specify the type explicitly:
When used with a type, the given generic placeholder will keep its type for the entire lifetime of the given instance,
and cannot be changed after initialisation. Therefore when you access the property baz, it will always be of type
String for this given instance.
When you come to pass around generic types, in most cases you have to be explicit about the generic placeholder
type you expect. For example, as a function input:
This function will only accept a Bar<Int>. Attempting to pass in a Bar instance where the generic placeholder type is
not Int will result in a compiler error.
Generic placeholder names are not just limited to single letters. If a given placeholder represents a meaningful
concept, you should give it a descriptive name. For example, Swift’s Array has a generic placeholder called Element,
which defines the element type of a given Array instance.
Whenever we create a new MyGenericClass, the type parameter has to implement the Equatable protocol
(ensuring the type parameter can be compared to another variable of the same type using ==)
class MyGenericClass<Type>{
myStringGeneric.setValue("Another String")
myIntGeneric.setValue(1024)
Usage
// Prints [1,2,3]
Use the function to remove an element without need for an index. Just pass the object to remove.
myArray.remove(2)
print(myArray)
// Prints [1,3]
It's also valid to write the where clause after the argument list:
Extensions can be restricted to types that satisfy conditions. The function is only available to instances which satisfy
the type conditions:
// Models
class MyFirstModel {
}
// Generic classes
class MyFirstGenericClass<T: MyFirstModel> {
func doSomethingWithModel(model: T) {
// Do something here
}
protocol JSONDecodable {
static func from(_ json: [String: Any]) -> Any?
}
The protocol declaration seems fine unless you actually use it.
Why do you have to cast the result to TestObject? Because of the Any return type in the protocol declaration.
By using generics you can avoid this problem that can cause runtime errors (and we don't want to have them!)
protocol JSONDecodable {
associatedtype Element
static func from(_ json: [String: Any]) -> Element?
}
Bitwise NOT ~:
Here, each bit get changed to its opposite. Declaring the number as explicitly UInt8 ensures that the number is
positive (so that we don't have to deal with negatives in the example) and that it is only 8 bits. If 0b01101100 was a
larger UInt, there would be leading 0s that would be converted to 1s and become significant upon inversion:
0 -> 1
1 -> 0
Here, a given bit will be 1 if and only if the binary numbers on both sides of the & operator contained a 1 at that bit
location.
0 & 0 -> 0
0 & 1 -> 0
1 & 1 -> 1
Bitwise OR |:
Here, a given bit will be 1 if and only if the binary number on at least one side of the | operator contained a 1 at
that bit location.
0 | 0 -> 0
0 | 1 -> 1
1 | 1 -> 1
Here, a given bit will be 1 if and only if the bits in that position of the two operands are different.
0 ^ 0 -> 0
0 ^ 1 -> 1
1 ^ 1 -> 0
For all binary operations, the order of the operands makes no difference on the result.
The operator's structure is defined by three parts: operand placement, precedence, and associativity.
1. The prefix, infix and postfix modifiers are used to start an custom operator declaration. The prefix and
postfix modifiers declare whether the operator must be before or after, respectively, the value on which it
acts. Such operators are urnary, like 8 and 3++ **, since they can only act on one target. The infix declares a
binary operator, which acts on the two values it is between, such as 2+3.
2. Operators with higher precedence are calculated first. The default operator precedence is just higher than
?...: (a value of 100 in Swift 2.x). The precedence of standard Swift operators can be found here.
3. Associativity defines the order of operations between operators of the same precedence. Left associative
operators are calculated from left to right (reading order, like most operators), while right associative
operators calculate from right to left.
Version ≥ 3.0
Starting from Swift 3.0, one would define the precedence and associativity in a precedence group instead of the
operator itself, so that multiple operators can easily share the same precedence without referring to the cryptic
numbers. The list of standard precedence groups is shown below.
Operators return values based on the calculation code. This code acts as a normal function, with parameters
specifying the type of input and the return keyword specifying the calculated value that the operator returns.
Here is the definition of a simple exponential operator, since standard Swift does not have an exponential operator.
import Foundation
The infix says that the ** operator works in between two values, such as 9**2. Because the function has left
associativity, 3**3**2 is calculated as (3**3)**2. The precedence of 170 is higher than all standard Swift operations,
meaning that 3+2**4 calculates to 19, despite the left associativity of **.
Version ≥ 3.0
Instead of specifying the precedence and associativity explicitly, on Swift 3.0 we could use the built-in precedence
group BitwiseShiftPrecedence that gives the correct values (same as <<, >>).
**: The increment and decrement are deprecated and will be removed in Swift 3.
Due to the way binary arithmetic works, after a number becomes too large for its bits, the number overflows down
to the smallest possible number (for the bit size) and then continues counting up from there. Similarly, when a
number becomes too small, it underflows up to the largest possible number (for its bit size) and continues counting
down from there.
Because this behavior is not often desired and can lead to serious security issues, the Swift arithmetic operators +,
-, and * will throw errors when an operation would cause an overflow or underflow. To explicitly allow overflow and
underflow, use &+, &-, and &* instead.
Example usage:
The DefaultPrecedence precedence group is higher than TernaryPrecedence, but is unordered with the rest
of the operators. Other than this group, the rest of the precedences are linear.
In Swift 3 there are multiple access-levels. This example uses them all except for open:
Car.make (public)
print(myCar.make)
This print will work everywhere, including targets that import Car.
Car.model (internal)
print(myCar.model)
Car.otherName (fileprivate)
print(myCar.otherName)
This will only work if the code is in the same file as Car.
Car.fullName (private)
print(myCar.fullName)
This won't work in Swift 3. private properties can only be accessed within the same struct/class.
If the entity has multiple associated access levels, Swift looks for the lowest level of access. If a private variable
exists in a public class, the variable will still be considered private.
However, in practice you can use the "associated object" technique. The result is almost exactly like a "real"
property.
Here is the exact technique for adding an "associated object" to a protocol extension:
get {
return objc_getAssociatedObject(self, & _Handle) as! YourType
}
set {
objc_setAssociatedObject(self, & _Handle, newValue, .OBJC_ASSOCIATION_RETAIN)
}
1. In the protocol, you must use ": class" to avoid the mutation problem.
2. In the extension, you must use "where Self:UIViewController" (or whatever appropriate class) to give the
confirming type.
import Foundation
import UIKit
import ObjectiveC // don't forget this
In any conforming class, you have now "added" the property "p":
You can use "p" just as you would use any ordinary property in the conforming class. Example:
func blah() {
u = ...
... = u
// use "p" as you would any normal property
p = ...
... = p
}
Xcode will not enforce you initializing "p" in the conforming class.
It is essential that you initialize "p", perhaps in viewDidLoad of the confirming class.
It is worth remembering that p is actually just a computed property. p is actually just two functions, with syntactic
sugar. There is no p "variable" anywhere: the compiler does not "assign some memory for p" in any sense. For this
reason, it is meaningless to expect Xcode to enforce "initializing p".
Indeed, to speak more accurately, you must remember to "use p for the first time, as if you were initializing it".
(Again, that would very likely be in your viewDidLoad code.)
Note that it will crash if the getter is called before a value for "p" is set.
get {
let g = objc_getAssociatedObject(self, &_Handle)
if (g == nil) {
objc_setAssociatedObject(self, &_Handle, _default initial value_, .OBJC_ASSOCIATION)
return _default initial value_
}
return objc_getAssociatedObject(self, &_Handle) as! YourType
}
To repeat. Xcode will not enforce you initializing p in the conforming class. It is essential that you initialize p, say in
Note that they do nothing, whatsoever, other than save typing and make the code more readable. (They are
essentially macros or inline functions.)
var p:P {
get {
return _aoGet(self, &_pHandle, P() ) as! P
}
set {
_aoSet(self, &_pHandle, newValue)
__pmSetter()
}
}
func __pmSetter() {
click!.text = String(p)
}
func someFunction() {
p.blah()
}
}
(In the example at _aoGet, P is initalizable: instead of P() you could use "", 0, or any default value.)
for i in 0..<3 {
print(i)
}
for i in 0...2 {
print(i)
}
// Both print:
// 0
// 1
// 2
// James
// Emily
// Miles
If you need the index for each element in the array, you can use the enumerate() method on SequenceType.
enumerate() returns a lazy sequence containing pairs of elements with consecutive Ints, starting from 0. Therefore
with arrays, these numbers will correspond to the given index of each element – however this may not be the case
with other kinds of collections.
Version ≥ 3.0
Iterating in reverse
Version = 2.1 Version = 2.2
You can use the reverse() method on SequenceType in order to iterate over any sequence in reverse:
for i in (0..<3).reverse() {
print(i)
}
for i in (0...2).reverse() {
print(i)
}
// Both print:
// 2
// 1
// 0
// Miles
// Emily
// James
Version ≥ 3.0
for i in (0..<3).reversed() {
print(i)
}
By using the stride(_:_:) methods on Strideable you can iterate over a range with a custom stride:
// 4
// 2
// 4
In Swift 3, the stride(_:_:) methods on Stridable have been replaced by the global stride(_:_:_:) functions:
var i: Int = 0
repeat {
print(i)
i += 1
} while i < 3
// 0
// 1
// 2
By adding a where clause you can restrict the iterations to ones that satisfy the given condition.
// 0
// 2
// 4
// James
// Miles
2. case clause
It's useful when you need to iterate only through the values that match some pattern:
//point on x-axis
//point on x-axis
Also you can filter optional values and unwrap them if appropriate by adding ? mark after binding constant:
//31
//5
collection.forEach { print($0) }
collection.forEach { item in
print(item)
}
*Note: Control flow statements (such as break or continue) may not be used in these blocks. A return can be called,
and if called, will immediately return the block for the current iteration (much like a continue would). The next
iteration will then execute.
arr.forEach {
var count = 1
var peopleArray = ["John", "Nicole", "Thomas", "Richard", "Brian", "Novak", "Vick", "Amanda",
"Sonya"]
var positionOfNovak = 0
class Project {
var title: String = ""
var id: Int = 0
var platform: String = ""
var version: Int = 0
var info: String?
}
Creating an instance that will actually be the subject of the mirror. Also here you can add values to the properties of
the Project class.
The code below shows the creating of Mirror instance. The children property of the mirror is a
AnyForwardCollection<Child> where Child is typealias tuple for subject's property and value. Child had a label:
String and value: Any.
print(properties.count) //5
print(properties.first?.label) //Optional("title")
print(properties.first!.value) //MirrorMirror
print()
title:MirrorMirror
id:199
platform:iOS
version:2
info:Optional("test app for Reflection")
Where primitiveDataTypes is a Dictionary mapping a letter in the attribute string to a value type:
It can extract the NSObject.Type of all properties which class type inherits from NSObject such as NSDate (Swift3:
Date), NSString(Swift3: String?) and NSNumber, however it is store in the type Any (as you can see as the type of the
value of the Dictionary returned by the method). This is due to the limitations of value types such as Int, Int32,
init(title: String, author: String?, numberOfPages: Int, released: Date, isPocket: Bool) {
self.title = title
self.author = author
self.numberOfPages = numberOfPages
self.released = released
self.isPocket = isPocket
}
}
You can also try to cast the Any to NSObject.Type, which will succeed for all properties inheriting from NSObject,
then you can check the type using standard == operator:
func checkPropertiesOfBook() {
guard let types = getTypesOfProperties(in: Book.self) else { return }
for (name, type) in types {
if let objectType = type as? NSObject.Type {
if objectType == NSDate.self {
print("Property named '\(name)' has type 'NSDate'")
} else if objectType == NSString.self {
print("Property named '\(name)' has type 'NSString'")
}
}
}
}
You can then even check the type of value types like this:
LIMITATIONS This solution does not work when value types are optionals. If you have declared a property in you
NSObject subclass like this: var myOptionalInt: Int?, the code above won't find that property because the
method class_copyPropertyList does not contain optional value types.
Features.feature1.rawValue //2
Features.all.rawValue //63
options.contains(.feature1) //true
options.contains(.feature4) //false
options.insert(.feature4)
options.contains(.feature4) //true
options.contains(.feature5) //false
options.formUnion(otherOptions)
options.contains(.feature5) //true
options.remove(.feature5)
options.contains(.feature5) //false
Pure Swift methods are not dynamically dispatched by the Objective-C runtime, but we can still take advantage of
these tricks on any class that inherits from NSObject.
Here, we will extend UIViewController and swizzle viewDidLoad to add some custom logging:
extension UIViewController {
// Make a static struct for our dispatch token so only one exists in memory
struct Static {
static var token: dispatch_once_t = 0
}
extension TestSwizzling {
struct Inner {
static let i: () = {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
let _ = Inner.i
}
func methodTwo()->Int{
// It will not be a recursive call anymore after the swizzling
return methodTwo()+1
}
}
var c = TestSwizzling()
print(c.methodOne())
print(c.methodTwo())
+ (void)swizzleMethods {
static BOOL swizzled = NO;
if (!swizzled) {
swizzled = YES;
Method initWithFrameMethod =
class_getInstanceMethod([UIView class], @selector(initWithFrame:));
original_initWithFrame = method_setImplementation(
initWithFrameMethod, (IMP)replacement_initWithFrame);
}
}
// Bonus: This is how you would call the original initWithFrame method
UIView *view =
((id (*)(id, SEL, CGRect))original_initWithFrame)(self, _cmd, rect);
return view;
}
Serial Dispatch Queues (aka private dispatch queues) execute one task at a time, in order. They are
frequently used to synchronize access to a resource.
Concurrent Dispatch Queues (aka global dispatch queues) execute one or more tasks concurrently.
The Main Dispatch Queue executes tasks on the main thread.
Version = 3.0
let mainQueue = DispatchQueue.main
Version < 3.0
let mainQueue = dispatch_get_main_queue()
The system provides concurrent global dispatch queues (global to your application), with varying priorities. You can
access these queues using the DispatchQueue class in Swift 3:
Version = 3.0
let globalConcurrentQueue = DispatchQueue.global(qos: .default)
equivalent to
In iOS 8 or later, the possible quality of service values which may be passed are .userInteractive,
.userInitiated, .default, .utility, and .background. These replace the DISPATCH_QUEUE_PRIORITY_ constants.
You can also create your own queues with varying priorities:
Version = 3.0
let myConcurrentQueue = DispatchQueue(label: "my-concurrent-queue", qos: .userInitiated,
attributes: [.concurrent], autoreleaseFrequency: .workItem, target: nil)
let mySerialQueue = DispatchQueue(label: "my-serial-queue", qos: .background, attributes: [],
autoreleaseFrequency: .workItem, target: nil)
Version < 3.0
let myConcurrentQueue = dispatch_queue_create("my-concurrent-queue", DISPATCH_QUEUE_CONCURRENT)
let mySerialQueue = dispatch_queue_create("my-serial-queue", DISPATCH_QUEUE_SERIAL)
In Swift 3, queues created with this initializer are serial by default, and passing .workItem for autorelease frequency
ensures an autorelease pool is created and drained for each work item. There is also .never, which means you will
be managing your own autorelease pools yourself, or .inherit which inherits the setting from the environment. In
most cases you probably won't use .never except in cases of extreme customization.
You can perform those calculations concurrently using concurrentPerform (in Swift 3) or dispatch_apply (in Swift
2):
Version = 3.0
DispatchQueue.concurrentPerform(iterations: iterations) { index in
// Do something computationally expensive here
}
Version < 3.0
dispatch_apply(iterations, queue) { index in
// Do something computationally expensive here
}
The loop closure will be invoked for each index from 0 to, but not including, iterations. These iterations will be
run concurrently with respect to each other, and thus the order that they run is not guaranteed. The actual number
of iterations that happen concurrently at any given time is generally dictated by the capabilities of the device in
question (e.g. how many cores does the device have).
The concurrentPerform/dispatch_apply may run the loops concurrently with respect to each other, but this
all happens synchronously with respect to the thread from which you call it. So, do not call this from the main
thread, as this will block that thread until the loop is done.
Because these loops happen concurrently with respect to each other, you are responsible for ensuring the
thread-safety of the results. For example, if updating some dictionary with the results of these
computationally expensive calculations, make sure to synchronize those updates yourself.
Note, there is some overhead associated in running concurrent loops. Thus, if the calculations being
performed inside the loop are not sufficiently computationally intensive, you may find that any performance
gained by using concurrent loops may be diminished, if not be completely offset, by the overhead associated
with the synchronizing all of these concurrent threads.
So, you are responsible determining the correct amount of work to be performed in each iteration of the
loop. If the calculations are too simple, you may employ "striding" to include more work per loop. For
example, rather than doing a concurrent loop with 1 million trivial calculations, you may do 100 iterations in
your loop, doing 10,000 calculations per loop. That way there is enough work being performed on each
thread, so the overhead associated with managing these concurrent loops becomes less significant.
To run tasks on a dispatch queue, use the sync, async, and after methods.
queue.async {
//do something
DispatchQueue.main.async {
//this will be called in main thread
//any UI updates should be placed here
}
}
// ... code here will execute immediately, before the task finished
queue.sync {
// Do some task
}
// ... code here will not execute until the task is finished
queue.asyncAfter(deadline: .now() + 3) {
//this will be executed in a background-thread after 3 seconds
}
// ... code here will execute immediately, before the task finished
NOTE: Any updates of the user-interface should be called on the main thread! Make sure, that you put
the code for UI updates inside DispatchQueue.main.async { ... }
Version = 2.0
Types of queue:
dispatch_async(queue) {
// Your code run run asynchronously. Code is queued and executed
// at some point in the future.
}
// Code after the async block will execute immediately
dispatch_sync(queue) {
// Your sync code
}
// Code after the sync block will wait until the sync task finished
To dispatch a task to after a time interval (use NSEC_PER_SEC to convert seconds to nanoseconds):
dispatch_async(queue) {
// Your time consuming code here
dispatch_async(dispatch_get_main_queue()) {
// Update the UI code
}
}
NOTE: Any updates of the user-interface should be called on the main thread! Make sure, that you put
the code for UI updates inside dispatch_async(dispatch_get_main_queue()) { ... }
Version ≥ 3.0
let mainQueue = OperationQueue.main
Version ≥ 3.0
let queue = OperationQueue()
queue.name = "My Queue"
queue.qualityOfService = .default
Quality of Service specifies the importance of the work, or how much the user is likely to be counting on immediate
results from the task.
Version ≥ 3.0
// An instance of some Operation subclass
let operation = BlockOperation {
// perform task here
}
queue.addOperation(operation)
Version ≥ 3.0
myQueue.addOperation {
// some task
}
myQueue.addOperation(operations)
Adjust how many Operations may be run concurrently within the queue:
Suspending a queue will prevent it from starting the execution of any existing, unstarted operations or of any new
operations added to the queue. The way to resume this queue is to set the isSuspended back to false:
Version ≥ 3.0
myQueue.isSuspended = true
// Re-enable execution
myQueue.isSuspended = false
Suspending an OperationQueue does not stop or cancel operations that are already executing. One should only
attempt suspending a queue that you created, not global queues or the main queue.
Operations become ready to execute when all of its dependencies are finished executing. The isReady property
then changes to true.
Version ≥ 3.0
class MyOperation: Operation {
init(<parameters>) {
// Do any setup work here
}
}
Version ≤ 2.3
class MyOperation: NSOperation {
init(<parameters>) {
// Do any setup work here
}
Version ≥ 1.0
myQueue.addOperation(operation)
Dependencies define other Operations that must execute on a queue before that Operation is considered ready to
execute.
Version ≥ 1.0
operation2.addDependency(operation1)
operation2.removeDependency(operation1)
Version ≥ 1.0
operation.start()
Dependencies will be ignored. If this is a concurrent operation, the task may still be executed concurrently if its
start method offloads work to background queues.
Concurrent Operations.
If the task that an Operation is to perform is, itself, asynchronous, (e.g. a URLSession data task), you should
implement the Operation as a concurrent operation. In this case, your isAsynchronous implementation should
return true, you'd generally have start method that performs some setup, then calls its main method which
actually executes the task.
When implementing an asynchronous Operation begins you must implement isExecuting, isFinished methods
and KVO. So, when execution starts, isExecuting property changes to true. When an Operation finishes its task,
isExecuting is set to false, and isFinished is set to true. If the operation it is cancelled both isCancelled and
isFinished change to true. All of these properties are key-value observable.
Cancel an Operation.
Calling cancel simply changes the isCancelled property to true. To respond to cancellation from within your own
Operation subclass, you should check the value of isCancelled at least periodically within main and respond
appropriately.
Version ≥ 1.0
operation.cancel()
1. A designated initializer must call a designated initializer from its immediate superclass.
2. A convenience initializer must call another initializer from the same class.
3. A convenience initializer must ultimately call a designated initializer.
// Designated Initializer
init(someString: String, someValue: Int, someBool: Bool)
{
self.someString = someString
self.someValue = someValue
self.someBool = someBool
}
// A convenience initializer must call another initializer from the same class.
convenience init()
{
self.init(otherString: "")
}
// Designed initializer
init(someFloat: Float)
{
self.someFloat = someFloat
// A convenience initializer must call another initializer from the same class.
convenience init()
{
self.init(someFloat: 0)
}
}
Designated Initializer
let c = Foo(someString: "Some string", someValue: 10, someBool: true)
Convenience init()
let a = Foo()
Convenience init()
let e = Baz()
struct Example {
var upvotes: Int
init() {
upvotes = 42
}
}
let myExample = Example() // call the initializer
print(myExample.upvotes) // prints: 42
Classes and structs must set all stored properties to an appropriate initial value by the time an instance is created.
This example will not compile, because the initializer did not give an initial value for downvotes:
struct Example {
var upvotes: Int
var downvotes: Int
init() {
upvotes = 0
} // error: Return from initializer without initializing all stored properties
}
let myBadDistance = MetricDistance(42) // error: argument labels do not match any available
overloads
struct MetricDistance {
var distanceInMeters: Double
init(_ meters: Double) {
distanceInMeters = meters
}
}
let myDistance = MetricDistance(42) // distanceInMeters = 42
If your argument labels share names with one or more properties, use self to explicitly set the property values:
struct Color {
var red, green, blue: Double
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
You can use Error Handling enum to check the parameter for the Struct(or class) meet expected requirement
struct User {
let name: String
self.name = name
}
}
do {
let user = try User(name: "Sample name")
// success
}
catch ValidationError.invalid {
// handle error
}
Different types are able to conform to the same protocol, value types can even conform to multiple protocols and
even provide default method implementation.
Initially protocols are defined that can represent commonly used properties and/or methods with either specific or
generic types.
protocol ItemData {
protocol DisplayItem {
protocol GetAPIItemDataOperation {
A default implementation for the get method can be created, though if desired conforming types may override the
implementation.
extension GetAPIItemDataOperation {
completed([item])
}
}
A value type that conforms to the ItemData protocol, this value type is also able to conform to other protocols.
ItemOperation.get(NSURL()) { (itemData) in
// self.items = itemData
})
Different use cases will require different implementations. The main idea here is to show conformance from
extension LocalItem {
Here the Core Data backed class can also conform to the DisplayItem protocol.
do {
print(displayItems)
}
1. Define a protocol that exposes the public interface of the class ViewModel, with all the properties and
methods needed by the UIViewController.
2. Implement the real ViewModel class, conforming to that protocol.
3. Use a dependency injection technique to let the view controller use the implementation we want, passing it
as the protocol and not the concrete instance.
protocol ViewModelType {
var title : String {get}
func confirm()
}
init(title: String) {
self.title = title
}
func confirm() { ... }
}
// With DI we setup the view controller and assign the view model.
// The view controller doesn't know the concrete class of the view model,
// but just relies on the declared interface on the protocol.
let viewController = //... Instantiate view controller
viewController.viewModel = ViewModel(title: "MyTitle")
viewModel = FakeViewModel()
sut = // ... initialization for view controller
sut.viewModel = viewModel
func testTitleLabel() {
XCTAssertEqual(self.sut.titleLabel.text, "FakeTitle")
}
func testTapOnButton() {
sut.didTapOnButton(UIButton())
XCTAssertTrue(self.viewModel.didConfirm)
}
}
struct Person {
let name: String
let birthYear: Int?
}
let persons = [
Person(name: "Walter White", birthYear: 1959),
Person(name: "Jesse Pinkman", birthYear: 1984),
Person(name: "Skyler White", birthYear: 1970),
Person(name: "Saul Goodman", birthYear: nil)
]
we can retrieve an array of String containing the name property of each Person.
// functional
numbers.enumerate().map { (index, element) in
print((index, element))
}
var newReleases = [
[
"id": 70111470,
"title": "Die Hard",
"boxart": "http://cdn-0.nflximg.com/images/2891/DieHard.jpg",
"uri": "http://api.netflix.com/catalog/titles/movies/70111470",
"rating": 4.0,
"bookmark": []
],
[
"id": 654356453,
"title": "Bad Boys",
print(videos1)
print(videos2)
struct Painter {
enum Type { case Impressionist, Expressionist, Surrealist, Abstract, Pop }
var firstName: String
var lastName: String
var type: Type
let painters = [
Painter(firstName: "Claude", lastName: "Monet", type: .Impressionist),
Painter(firstName: "Edgar", lastName: "Degas", type: .Impressionist),
Painter(firstName: "Egon", lastName: "Schiele", type: .Expressionist),
Painter(firstName: "George", lastName: "Grosz", type: .Expressionist),
Painter(firstName: "Mark", lastName: "Rothko", type: .Abstract),
Painter(firstName: "Jackson", lastName: "Pollock", type: .Abstract),
Painter(firstName: "Pablo", lastName: "Picasso", type: .Surrealist),
Painter(firstName: "Andy", lastName: "Warhol", type: .Pop)
]
// combine filter and map for more complex operations, for example listing all
// non-impressionist and non-expressionists by surname
dump(painters.filter({$0.type != .Impressionist && $0.type != .Expressionist})
.map({$0.lastName}).joinWithSeparator(", "))
// prints "Rothko, Pollock, Picasso, Warhol"
/// Projection
var newReleases = [
[
"id": 70111470,
"title": "Die Hard",
"boxart": "http://cdn-0.nflximg.com/images/2891/DieHard.jpg",
"uri": "http://api.netflix.com/catalog/titles/movies/70111470",
"rating": [4.0],
"bookmark": []
],
[
"id": 654356453,
"title": "Bad Boys",
"boxart": "http://cdn-0.nflximg.com/images/2891/BadBoys.jpg",
"uri": "http://api.netflix.com/catalog/titles/movies/70111470",
"rating": [5.0],
"bookmark": [[ "id": 432534, "time": 65876586 ]]
],
[
"id": 65432445,
"title": "The Chamber",
"boxart": "http://cdn-0.nflximg.com/images/2891/TheChamber.jpg",
"uri": "http://api.netflix.com/catalog/titles/movies/70111470",
"rating": [4.0],
"bookmark": []
],
[
"id": 675465,
"title": "Fracture",
"boxart": "http://cdn-0.nflximg.com/images/2891/Fracture.jpg",
"uri": "http://api.netflix.com/catalog/titles/movies/70111470",
print(videoAndTitlePairs)
Example:
instead of
Example:
factory.makeObject()
Example:
factory.makeObject(key: value)
Instead of:
factory.makeObject(havingProperty: value)
Functions with side effects (mutating functions) should be named using verbs or nouns prefixed with form- .
Functions without side effects (nonmutating functions) should be named using nouns or verbs with the suffix
-ing or -ed.
Nonmutating functions:
Example:
set.isEmpty
line.intersects(anotherLine)
Example:
Collection // describes that something is a collection
ProgressReporting // describes that something has the capability of reporting progress
Equatable // describes that something has the capability of being equal to something
Example:
Example:
extension List {
public mutating func remove(at position: Index) -> Element {
// implementation
}
}
The function call to this function will then look like this:
list.remove(at: 42)
This way, ambiguity is avoided. If the function call would be just list.remove(42) it would be unclear, if an Element
equal to 42 would be removed or if the Element at Index 42 would be removed.
Avoid Redundancy
The name of functions should not contain redundant information.
extension List {
public mutating func removeElement(element: Element) -> Element? {
// implementation
}
}
A call to the function may look like list.removeElement(someObject). The variable someObject already indicates,
that an Element is removed. It would be better for the function signature to look like this:
extension List {
public mutating func remove(_ member: Element) -> Element? {
// implementation
}
instead of
Example:
protocol Collection {}
struct String {}
class UIView {}
struct Int {}
enum Color {}
Everything else...
Variables, constants, functions and enumeration cases should start with a lowercase letter.
Example:
enum Color {
case red
case green
case blue
}
Camel Case:
Abbreviations
Abbreviations should be avoided unless commonly used (e.g. URL, ID). If an abbreviation is used, all letters should
have the same case.
Example:
let age = value as! Double // crash: "Could not cast value…"
Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass
from somewhere else in its own class hierarchy.
Type casting in Swift is implemented with the is and as operators. These two operators provide a simple and
expressive way to check the type of a value or cast a value to a different type.
Downcasting
A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes.
Where you believe this is the case, you can try to downcast to the subclass type with a type cast operator (as? or
as!).
Use the conditional form of the type cast operator (as?) when you are not sure if the downcast will succeed. This
form of the operator will always return an optional value, and the value will be nil if the downcast was not possible.
This enables you to check for a successful downcast.
Use the forced form of the type cast operator (as!) only when you are sure that the downcast will always succeed.
This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type. Know more.
class Rat {
var color = "white"
}
return petRat.name
}
print(nameOfRat(noName))
print(nameOfRat(spot))
// The `as` operator will cast. You do not need to use `as?` in a `switch`.
case let string as String:
return "value is the string: \(string)"
default:
return "value is something else"
}
Prints:
? 4 elements
- [0]: Joe
- [1]: Jane
- [2]: Jim
- [3]: Joyce
For a dictionary:
Prints:
? 3 key/value pairs
? [0]: (2 elements)
- .0: bar
- .1: 33
? [1]: (2 elements)
- .0: baz
- .1: 42
? [2]: (2 elements)
- .0: foo
- .1: 10
There's other parameters available, like name to set a label for the object being inspected:
Prints:
You can also choose to print only a certain number of items with maxItems:, to parse the object up to a certain
depth with maxDepth:, and to change the indentation of printed objects with indent:.
print("Hello")
debugPrint("Hello")
print(dict)
debugPrint(dict)
Yields
>>> Hello
>>> "Hello"
>>> [foo: 1, bar: 2]
>>> ["foo": 1, "bar": 2]
print(wordArray)
debugPrint(wordArray)
Yields
Notice how in the first output it appears that there are 4 elements in the array as opposed to 3. For reasons like
this, it is preferable when debugging to use debugPrint
print(foo)
class Abc {
let a = "aa"
let b = "bb"
}
App.Abc
App.Abc #0
- a: "aa"
- b: "bb"
As seen, dump() outputs the whole class hierarchy, while print() simply outputs the class name.
There is more info on the class with dump(), and so it is more useful in debugging the class itself.
But there are lot of differences in print() and NSLog() functions, such as:
1 TimeStamp: NSLog() will print timestamp along with the string we passed to it, but print() will not print
timestamp.
e.g.
Output:
[1, 2, 3, 4, 5]
2017-05-31 13:14:38.582 ProjetName[2286:7473287] [1, 2, 3, 4, 5]
2 Only String: NSLog() only takes String as an input, but print() can print any type of input passed to it.
e.g.
4 Synchronization: NSLog() handles simultaneous usage from multi-threading environment and prints output
without overlapping it. But print() will not handle such cases and jumbles while prating output.
5 Device Console: NSLog() outputs on device console also, we can see this output by connecting our device to
Xcode. print() will not print output to device's console.
Allocating and deallocating from the stack is a very efficient operation, however in comparison heap allocation is
costly. When designing for performance, you should keep this in mind.
Classes:
class MyClass {
Classes in Swift are reference types and therefore several things happen. First, the actual object will be allocated
onto the heap. Then, any references to that object must be added to the stack. This makes classes a more
expensive object for allocation.
Structs:
struct MyStruct {
Because structs are value types and therefore copied when passed around, they are allocated on the stack. This
makes structs more efficient than classes, however, if you do need a notion of identity and/or reference semantics,
a struct cannot provide you with those things.
Warning about structs with Strings and properties that are classes
While structs are generally cheeper than classes, you should be careful about structs with properties that are
classes:
struct MyStruct {
Here, due to reference counting and other factors, the performance is now more similar to a class. Further, if more
than one property in the struct is a class, the performance impact may be even more negative than if the struct
were a class instead.
Also, while Strings are structs, they internally store their characters on the heap, so are more expensive than most
If a sequence terminates in finite time, not calling dispose or not using addDisposableTo(disposeBag)
won't cause any permanent resource leaks. However, those resources will be used until the sequence
completes, either by finishing production of elements or returning an error.
In the first case you manually pass the subscription to the DisposeBag object, which correctly clears all taken
memory.
You don't actually need to create DisposeBags in every class that you create, just take a look at RxSwift Community's
project named NSObject+Rx. Using the framework the code above can be rewritten as follows:
Observable.just(1).subscribeNext {
print($0)
}.addDisposableTo(rx_disposeBag)
In the second case, if the subscription time coincides with the self object lifetime, it is possible to implement
disposing using takeUntil(rx_deallocated):
let _ = sequence
.takeUntil(rx_deallocated)
.subscribe {
print($0)
}
Every piece of data can be represented as Observable, which is an asynchronous data stream. The power of FRP is
in representation synchronous and asynchronous events as streams, Observables, and providing the same
interface to work with it.
Usually Observable holds several (or none) events that holds the date - .Next events, and then it can be terminated
successfully (.Success) or with an error (.Error).
In this example there is a stream of Int values. As time moves forward, three .Next events occurred, and then the
stream terminated successfully.
--X->
The diagram above shows a case where no data was emitted and .Error event terminates the Observable.
import RxSwift
So, the observables are created. They holds just one value and then terminates with success. Nevertheless, nothing
happening after it was created. Why?
There are two steps in working with Observables: you observe something to create a stream and then you
subscribe to the stream or bind it to something to interact with it.
Observable.just(12).subscribe {
print($0)
}
.Next(12)
.Completed()
And if I interested only in working with data, which take place in .Next events, I'd use subscribeNext operator:
Observable.just(12).subscribeNext {
print($0) // prints "12" now
}
Observable.of(1,2,3,4,5).subscribeNext {
print($0)
}
// 1
// 2
And finally, maybe I want an Observable that does some work. For example, it is convenient to wrap a network
operation into Observable<SomeResultType>. Let's take a look of do one can achieve this:
Using the combineLatest operator every time an item is emitted by either of two Observables, combine the latest
item emitted by each Observable. So in this way we combine the result of the two UITextField's creating a new
message with the text "Greetings, \($0)" using string interpolation to later bind to the text of a UILabel.
We can bind data to any UITableView and UICollectionView in an very easy way:
viewModel
.rows
.bindTo(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell", cellType:
WikipediaSearchCell.self)) { (_, viewModel, cell) in
cell.title = viewModel.title
cell.url = viewModel.url
}
.addDisposableTo(disposeBag)
That’s an Rx wrapper around the cellForRowAtIndexPath data source method. And also Rx takes care of the
implementation of the numberOfRowsAtIndexPath, which is a required method in a traditional sense, but you don’t
have to implement it here, it’s taken care of.
RxCocoa contains everything you need. It wraps most of the UI components' properties into Observables, but not
really. There are some upgraded Observables called ControlEvents (which represent events) and
This is very important to use: as long as you use Rx, forget about the @IBAction stuff, everything you need you can
bind and configure at once. For example, viewDidLoad method of your view controller is a good candidate to
describe how the UI-components work.
Ok, another example: suppose we have a textfield, a button, and a label. We want to validate text in the textfield
when we tap the button, and display the results in the label. Yep, seems like an another validate-email task, huh?
----()-----------------------()----->
Here empty parenthesis show user taps. Next, we take what's written in the textField with withLatestFrom operator
(take a look at it here, imagine that upper stream represents user taps, bottom one represents text in the text field).
button.rx_tap.withLatestFrom(textField.rx_text)
----("")--------------------("123")--->
// ^ tap ^ i wrote 123 ^ tap
Nice, we have a stream of strings to validate, emitted only when we need to validate.
Any Observable has such familiar operators as map or filter, we'll take map to validate the text. Create
validateEmail function yourself, use any regex you want.
button.rx_tap // ControlEvent<Void>
.withLatestFrom(textField.rx_text) // Observable<String>
.map(validateEmail) // Observable<Bool>
.map { (isCorrect) in
return isCorrect ? "Email is correct" : "Input the correct one, please"
} // Observable<String>
.bindTo(label.rx_text)
.addDisposableTo(bag)
Done! If you need more custom logic (like showing error views in case of error, making a transition to another
As Swift's guard statements encourage a style of early return, many possible paths for a return may exist. A defer
statement provides cleanup code, which then does not need to be repeated every time.
It can also save time during debugging and profiling, as memory leaks and unused open resources due to forgotten
cleanup can be avoided.
func doSomething() {
let data = UnsafeMutablePointer<UInt8>(allocatingCapacity: 42)
// this pointer would not be released when the function returns
// so we add a defer-statement
defer {
data.deallocateCapacity(42)
}
// it will be executed when the function returns.
Creational design patterns abstract the instantiation of objects to make a system more independent of the
process of creation, composition, and representation.
In the following example, we create a static property that holds an instance of the Foo class. Remember that a
static property is shared between all objects of a class and can't be overwritten by subclassing.
func doSomething()
{
print("Do something")
}
}
Usage:
Foo.shared.doSomething()
This makes sure your singletons are truly unique and prevents outside objects from creating their own
instances of your class through virtue of access control. Since all objects come with a default public
initializer in Swift, you need to override your init and make it private. KrakenDev
The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern
and the factory method pattern whose intention is to enable polymorphism, the intention of the builder
pattern is to find a solution to the telescoping constructor anti-pattern. The telescoping constructor anti-
pattern occurs when the increase of object constructor parameter combination leads to an exponential
list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a
builder, that receives each initialization parameter step by step and then returns the resulting
constructed object at once.
-Wikipedia
Example:
Consider that we have a Car class contains many options to create an object, such as:
Color.
Number of seats.
Number of wheels.
Type.
Gear type.
Motor.
Airbag availability.
import UIKit
enum CarType {
case
sportage,
saloon
}
enum GearType {
case
manual,
automatic
}
struct Motor {
var id: String
var name: String
var model: String
var numberOfCylinders: UInt8
}
self.color = color
self.numberOfSeats = numberOfSeats
self.numberOfWheels = numberOfWheels
}
}
print(aCar)
/* Printing
color: UIExtendedGrayColorSpace 0 1
Number of seats: 4
Number of Wheels: 4
Type: automatic
Motor: Motor(id: "101", name: "Super Motor", model: "c4", numberOfCylinders: 6)
Airbag Availability: true
*/
The problem arises when creating a car object is that the car requires many configuration data to be created.
For applying the Builder Pattern, the initializer parameters should have default values which are changeable if
needed.
CarBuilder class:
class CarBuilder {
var color: UIColor = UIColor.black
var numberOfSeats: UInt8 = 5
var numberOfWheels: UInt8 = 4
var type: CarType = .saloon
var gearType: GearType = .automatic
var motor: Motor = Motor(id: "111", name: "Default Motor",
model: "T9", numberOfCylinders: 4)
var shouldHasAirbags: Bool = false
The CarBuilder class defines properties that could be changed to to edit the values of the created car object.
builder.shouldHasAirbags = true
// now, the builder creates cars with default configuration,
// but with a small edit on making the airbags available
builder.color = UIColor.purple
// now, the builder creates cars with default configuration
// with some extra features: the airbags are available and the color is purple
The benefit of applying the Builder Pattern is the ease of creating objects that should contain much of
configurations by setting default values, also, the ease of changing these default values.
Take it Further:
As a good practice, all properties that need default values should be in a separated protocol, which should be
implemented by the class itself and its builder.
import UIKit
enum CarType {
case
sportage,
saloon
}
enum GearType {
manual,
automatic
}
struct Motor {
var id: String
var name: String
var model: String
var numberOfCylinders: UInt8
}
protocol CarBluePrint {
var color: UIColor { get set }
var numberOfSeats: UInt8 { get set }
var numberOfWheels: UInt8 { get set }
var type: CarType { get set }
var gearType: GearType { get set }
var motor: Motor { get set }
var shouldHasAirbags: Bool { get set }
}
self.color = color
self.numberOfSeats = numberOfSeats
self.numberOfWheels = numberOfWheels
self.type = type
self.gearType = gearType
self.motor = motor
self.shouldHasAirbags = shouldHasAirbags
}
}
The benefit of declaring the properties that need default value into a protocol is the forcing to implement any new
added property; When a class conforms to a protocol, it has to declare all its properties/methods.
Consider that there is a required new feature that should be added to the blueprint of creating a car called "battery
name":
protocol CarBluePrint {
var color: UIColor { get set }
var numberOfSeats: UInt8 { get set }
var numberOfWheels: UInt8 { get set }
var type: CarType { get set }
var gearType: GearType { get set }
var motor: Motor { get set }
var shouldHasAirbags: Bool { get set }
After adding the new property, note that two compile-time errors will arise, notifying that conforming to
CarBluePrint protocol requires to declare 'batteryName' property. That guarantees that CarBuilder will declare
and set a default value for batteryName property.
After adding batteryName new property to CarBluePrint protocol, the implementation of both Car and CarBuilder
classes should be:
self.color = color
self.numberOfSeats = numberOfSeats
self.numberOfWheels = numberOfWheels
self.type = type
self.gearType = gearType
self.motor = motor
self.shouldHasAirbags = shouldHasAirbags
self.batteryName = batteryName
}
In class-based programming, the factory method pattern is a creational pattern that uses factory
methods to deal with the problem of creating objects without having to specify the exact class of the
object that will be created. Wikipedia reference
protocol SenderProtocol
{
// Usage:
let package = ["Item 1", "Item 2"]
By doing that we don't depend on the real implementation of the class, making the sender() completely
transparent to who is consuming it.
In this case all we need to know is that a sender will handle the deliver and exposes a method called send(). There
are several other advantages: reduce classes coupling, easier to test, easier to add new behaviours without having
to change who is consuming it.
Within object-oriented design, interfaces provide layers of abstraction that facilitate conceptual
explanation of the code and create a barrier preventing dependencies.Wikipedia reference
The observer pattern is where an object, called the subject, maintains a list of its dependents, called
observers, and notifies them automatically of any state changes, usually by calling one of their methods.
It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part
in the familiar model–view–controller (MVC) architectural pattern.Wikipedia reference
First lets create a global reference (outside of a class) for the Notification Centre :
Great now we can call this from anywhere. We would then want to register a class as an observer...
This adds the class as an observer for "readForMyFunc". It also indicates that the function myFunc should be called
when that notification is received. This function should be written in the same class:
func myFunc(){
print("The notification has been received")
}
One of the advantages to this pattern is that you can add many classes as observers and thus perform
many actions after one notification.
The notification can now simply be sent(or posted if you prefer) from almost anywhere in the code with the line:
extension PurchasePower {
func process(request : PurchaseRequest){
if request.amount < self.allowable {
print(self.role + " will approve $ \(request.amount) for \(request.purpose)")
} else if successor != nil {
successor?.process(request: request)
}
}
}
struct PurchaseRequest {
var amount : Float
var purpose : String
}
manager.successor = director
director.successor = president
struct Turtle {
let name: String
}
struct Turtles {
let turtles: [Turtle]
}
init(turtles: [Turtle]) {
self.turtles = turtles
}
git init
Then create the package itself. One could create the package structure manually but there's a simple way using the
CLI command.
Several files will be generated. Among them, main.swift will be the entry point for your application.
The generated AwesomeProject.swift file will be used as the main file for this library.
In both cases you can add other Swift files in the Sources folder (usual rules for access control apply).
The Package.swift file itself will be automatically populated with this content:
import PackageDescription
Once pushed to a remote or local Git repository, your package will be available to other projects.
swift build
Your own package can also resolve dependencies to other packages. For example, if you want to include
"SomeOtherPackage" in your own project, change your Package.swift file to include the dependency:
import PackageDescription
Then build your project again: the Swift Package Manager will automatically resolve, download and build the
dependencies.
Below is another example which builds on the above to do something useful, which can't easily be done by any
other method and lends itself well to a regex solution.
In order to get an accurate range length that supports all character types the input string must be converted to a
NSString.
For safety matching against a pattern should be enclosed in a do catch block to handle failure
The example below replaces the cent symbol with the dollar symbol.
(){}[]/\+*$>.|^?
if matches.count > 0 {
validDate = true
}
validDate
extension String
{
func isValidEmail() -> Bool {
// Member description
var name: String
Note that with Xcode 8, you can generate the documentation snippet with command + option + / .
// Do something....
return true
}
/**
Repeats a string `times` times.
## Unordered Lists
- Lists are great,
- but perhaps don't nest
- Sub-list formatting
- isn't the best.
## Ordered Lists
1. Ordered lists, too
2. for things that are sorted;
3. Arabic numerals
4. are the only kind supported.
*/
func complexDocumentation() {
/**
Frame and construction style.
Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from
in the calling method.
The key should be exactly 128-bits (16-bytes), 192-bits (24-bytes) or 256-bits (32-bytes) in length. If another key size
is used an error will be thrown.
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.count = numBytesEncrypted + ivSize
}
else {
throw AESError.CryptorError(("Encryption failed", Int(cryptStatus)))
}
return cryptData;
}
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
clearData.count = numBytesDecrypted
}
else {
throw AESError.CryptorError(("Decryption failed", Int(cryptStatus)))
}
return clearData;
}
Example usage:
Example Output:
Notes:
One typical problem with CBC mode example code is that it leaves the creation and sharing of the random IV to the
user. This example includes generation of the IV, prefixed the encrypted data and uses the prefixed IV during
decryption. This frees the casual user from the details that are necessary for CBC mode.
For security the encrypted data also should have authentication, this example code does not provide that in order
to be small and allow better interoperability for other platforms.
Also missing is key derivation of the key from a password, it is suggested that PBKDF2 be used is text passwords are
used as keying material.
Updated to use throw/catch and multiple key sizes based on the provided key.
aesCBC128Encrypt will create a random IV and prefixed to the encrypted code. aesCBC128Decrypt will use the
prefixed IV during decryption.
Inputs are the data and key are Data objects. If an encoded form such as Base64 if required convert to and/or from
in the calling method.
This example requires Common Crypto It is necessary to have a bridging header to the project: #import
<CommonCrypto/CommonCrypto.h> Add the Security.framework to the project.
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeRange(numBytesEncrypted+ivLength..<cryptData.count)
}
else {
print("Error: \(cryptStatus)")
return nil;
}
return cryptData;
}
} else {
print("Error: \(cryptStatus)")
return nil;
}
return clearData;
}
Example usage:
print("clearData: \(toHex(clearData))")
print("keyData: \(toHex(keyData))")
let cryptData = aesCBC128Encrypt(data:clearData, keyData:keyData)!
print("cryptData: \(toHex(cryptData))")
let decryptData = aesCBC128Decrypt(data:cryptData, keyData:keyData)!
print("decryptData: \(toHex(decryptData))")
Example Output:
This parameter is ignored if ECB mode is used or if a stream cipher algorithm is selected.
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
return hexString
}
return nil
}
There are several hash algorithms that can be used including SHA1, SHA256, SHA512 which are provided by this
example code.
The rounds parameter is used to make the calculation slow so that an attacker will have to spend substantial time
on each attempt. Typical delay values fall in the 100ms to 500ms, shorter values can be used if there is
unacceptable performance.
Parameters:
func pbkdf2SHA1(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt,
keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2SHA256(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt,
keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2SHA512(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt,
keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: Data, keyByteCount: Int, rounds: Int)
-> Data? {
let passwordData = password.data(using:String.Encoding.utf8)!
var derivedKeyData = Data(repeating:0, count:keyByteCount)
CCKeyDerivationPBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password, passwordData.count,
saltBytes, salt.count,
hash,
UInt32(rounds),
return derivedKeyData
}
Example usage:
Example Output:
func pbkdf2SHA1(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt,
keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2SHA256(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt,
keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2SHA512(password: String, salt: [UInt8], keyCount: Int, rounds: Int) -> [UInt8]? {
return pbkdf2(CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt,
keyCount:keyCount, rounds:UInt32(rounds))
}
func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: [UInt8], keyCount: Int, rounds:
UInt32!) -> [UInt8]! {
let derivedKey = [UInt8](count:keyCount, repeatedValue:0)
let passwordData = password.dataUsingEncoding(NSUTF8StringEncoding)!
return derivedKey
}
Example usage:
Example Output:
Example usage:
let saltData = [UInt8]([0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec = 100
Example Output:
Several parameters are defaulted to representative values that should not materially affect the round count.
returns The number of iterations to use for the desired processing time.
Example usage:
let saltData = Data(bytes: [0x73, 0x61, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61])
let passwordString = "password"
let delayMsec = 100
Example Output:
This code block creates a type alias named SuccessHandler, just in the same way var string = "" creates a
variable with the name string.
This block creates a type alias that works as a Void to Void function (takes in no parameters and returns nothing).
func = {}
You can also use a type alias to give a type another name to make it easier to remember, or make your code more
elegant.
These functions will hash either String or Data input with one of eight cryptographic hash algorithms.
The name parameter specifies the hash function name as a String Supported functions are MD5, SHA1, SHA224,
SHA256, SHA384 and SHA512
These functions takes a hash name, message to be hashed, a key and return a digest:
hashName: name of a hash function as String message: message as Data key: key as Data returns: digest as Data
func hmac(hashName:String, message:Data, key:Data) -> Data? {
let algos = ["SHA1": (kCCHmacAlgSHA1, CC_SHA1_DIGEST_LENGTH),
"MD5": (kCCHmacAlgMD5, CC_MD5_DIGEST_LENGTH),
"SHA224": (kCCHmacAlgSHA224, CC_SHA224_DIGEST_LENGTH),
"SHA256": (kCCHmacAlgSHA256, CC_SHA256_DIGEST_LENGTH),
"SHA384": (kCCHmacAlgSHA384, CC_SHA384_DIGEST_LENGTH),
"SHA512": (kCCHmacAlgSHA512, CC_SHA512_DIGEST_LENGTH)]
guard let (hashAlgorithm, length) = algos[hashName] else { return nil }
var macData = Data(count: Int(length))
macData.withUnsafeMutableBytes {macBytes in
message.withUnsafeBytes {messageBytes in
key.withUnsafeBytes {keyBytes in
CCHmac(CCHmacAlgorithm(hashAlgorithm),
keyBytes, key.count,
messageBytes, message.count,
macBytes)
}
}
}
return macData
}
hashName: name of a hash function as String message: message as String key: key as String returns: digest as Data
func hmac(hashName:String, message:String, key:String) -> Data? {
let messageData = message.data(using:.utf8)!
let keyData = key.data(using:.utf8)!
return hmac(hashName:hashName, message:messageData, key:keyData)
}
hashName: name of a hash function as String message: message as String key: key as Data returns: digest as Data
func hmac(hashName:String, message:String, key:Data) -> Data? {
let messageData = message.data(using:.utf8)!
return hmac(hashName:hashName, message:messageData, key:key)
}
// Examples
Output:
clearString: clearData0123456
keyString: keyData8901234562
clearData: <636c6561 72446174 61303132 33343536>
keyData: <6b657944 61746138 39303132 33343536 32>
These functions will hash either String or Data input with one of eight cryptographic hash algorithms.
This function takes a hash name and Data to be hashed and returns a Data:
name: A name of a hash function as a String data: The Data to be hashed returns: the hashed result as Data
func hash(name:String, data:Data) -> Data? {
let algos = ["MD2": (CC_MD2, CC_MD2_DIGEST_LENGTH),
"MD4": (CC_MD4, CC_MD4_DIGEST_LENGTH),
"MD5": (CC_MD5, CC_MD5_DIGEST_LENGTH),
"SHA1": (CC_SHA1, CC_SHA1_DIGEST_LENGTH),
"SHA224": (CC_SHA224, CC_SHA224_DIGEST_LENGTH),
"SHA256": (CC_SHA256, CC_SHA256_DIGEST_LENGTH),
"SHA384": (CC_SHA384, CC_SHA384_DIGEST_LENGTH),
"SHA512": (CC_SHA512, CC_SHA512_DIGEST_LENGTH)]
guard let (hashAlgorithm, length) = algos[name] else { return nil }
var hashData = Data(count: Int(length))
This function takes a hash name and String to be hashed and returns a Data:
name: A name of a hash function as a String string: The String to be hashed returns: the hashed result as Data
func hash(name:String, string:String) -> Data? {
let data = string.data(using:.utf8)!
return hash(name:name, data:data)
}
Examples:
Output:
clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>
An application is composed of many objects that collaborate with each other. Objects usually depend on other
objects to perform some task. When an object is responsible for referencing its own dependencies it leads to a
highly coupled, hard-to-test and hard-to-change code.
Dependency injection is a software design pattern that implements inversion of control for resolving dependencies.
An injection is passing of dependency to a dependent object that would use it. This allows a separation of client's
dependencies from the client's behaviour, which allows the application to be loosely coupled.
Not to be confused with the above definition - a dependency injection simply means giving an object its
instance variables.
easier to test your code (using automated tests like unit and UI tests)
when used in tandem with protocol-oriented programming it makes it easy to change the implementation of
a certain class - easier to refactor
it makes the code more modular and reusable
There are three most commonly used ways Dependency Injection (DI) can be implemented in an application:
1. Initializer injection
2. Property injection
3. Using third party DI frameworks (like Swinject, Cleanse, Dip or Typhoon)
There is an interesting article with links to more articles about Dependency Injection so check it out if you want to
dig deeper into DI and Inversion of Control principle.
Let's show how to use DI with View Controllers - an every day task for an average iOS developer.
Example Without DI
We'll have two View Controllers: LoginViewController and TimelineViewController. LoginViewController is used
to login and upon successful loign, it will switch to the TimelineViewController. Both view controllers are dependent
on the FirebaseNetworkService.
LoginViewController
TimelineViewController
FirebaseNetworkService
class FirebaseNetworkService {
func logutCurrentUser() {
// Implementation not important for this example
}
}
This example is very simple, but let's assume you have 10 or 15 different view controller and some of them are also
dependent on the FirebaseNetworkService. At some moment you want to change Firebase as your backend service
with your company's in-house backend service. To do that you'll have to go through every view controller and
change FirebaseNetworkService with CompanyNetworkService. And if some of the methods in the
CompanyNetworkService have changed, you'll have a lot of work to do.
Unit and UI testing is not the scope of this example, but if you wanted to unit test view controllers with tightly
coupled dependencies, you would have a really hard time doing so.
Let's rewrite this example and inject Network Service to our view controllers.
To make the best out of the Dependency Injection, let's define the functionality of the Network Service in a protocol.
This way, view controllers dependent on a network service won't even have to know about the real implementation
of it.
protocol NetworkService {
func loginUser(username: String, passwordHash: String)
func logutCurrentUser()
}
func logutCurrentUser() {
// Firebase implementation
}
}
LoginViewController
TimelineViewController
Now, the question is: How do we inject the correct NetworkService implementation in the LoginViewController and
TimelineViewController?
Since LoginViewController is the starting view controller and will show every time the application starts, we can
inject all dependencies in the AppDelegate.
In the AppDelegate we are simply taking the reference to the first view controller (LoginViewController) and
injecting the NetworkService implementation using the property injection method.
Now, the next task is to inject the NetworkService implementation in the TimelineViewController. The easiest way is
to do that when LoginViewController is transitioning to the TimlineViewController.
We'll add the injection code in the prepareForSegue method in the LoginViewController (if you are using a different
approach to navigate through view controllers, place the injection code there).
Now imagine we want to switch our NetworkService implementation from Firebase to our custom company's
backend implementation. All we would have to do is:
func logutCurrentUser() {
// Company API implementation
}
}
That's it, we have switched the whole underlaying implementation of the NetworkService protocol without even
touching LoginViewController or TimelineViewController.
As this is a simple example, you might not see all the benefits right now, but if you try to use DI in your projects,
you'll see the benefits and will always use Dependency Injection.
func stopEngine() {
print("Engine stopped")
}
}
protocol TrainCar {
var numberOfSeats: Int { get }
func attachCar(attach: Bool)
}
class Train {
let engine: Engine?
var mainCar: TrainCar?
}
As the name says, all dependencies are injected through the class initializer. To inject dependencies through the
initializer, we'll add the initializer to the Train class.
class Train {
init(engine: Engine) {
self.engine = engine
}
}
When we want to create an instance of the Train class we'll use initializer to inject a specific Engine implementation:
NOTE: The main advantage of the initializer injection versus the property injection is that we can set the variable as
private variable or even make it a constant with the let keyword (as we did in our example). This way we can make
sure that no one can access it or change it.
DI using properties is even simpler that using an initializer. Let's inject a PassengerCar dependency to the train
object we already created using the properties DI:
train.mainCar = PassengerCar()
This type of dependency injection is a little different that the previous two because it won't affect the whole object,
but it will only inject a dependency to be used in the scope of one specific method. When a dependency is only used
in a single method, it's usually not good to make the whole object dependent on it. Let's add a new method to the
Train class:
Now, if we call the new Train's class method, we'll inject the TrainCar using the method dependency injection.
train.reparkCar(trainCar: RestaurantCar())
return processedArray
}
Output:
Output:
Output:
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after
the function returns. When you declare a function that takes a closure as one of its parameters, you can write
@escaping before the parameter’s type to indicate that the closure is allowed to escape.
In Swift 3, it’s the other way around: closure parameters are non-escaping by default. If you intend for it to escape
the function, you have to mark it with the @escaping attribute.
class ClassOne {
// @noescape is applied here as default
func methodOne(completion: () -> Void) {
//
}
}
class ClassTwo {
let obj = ClassOne()
var greeting = "Hello, World!"
func methodTwo() {
obj.methodOne() {
// self.greeting is required
print(greeting)
}
}
}
@escaping
Apply this attribute to a parameter’s type in a method or function declaration to indicate that the
parameter’s value can be stored for later execution. This means that the value is allowed to outlive the
lifetime of the call. Function type parameters with the escaping type attribute require explicit use of self.
for properties or methods.
class ClassThree {
In the above example the completion block is saved to closure and will literally live beyond the function call. So
complier will force to mark completion block as @escaping.
do {
let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl,
includingPropertiesForKeys: nil, options: [])
let cachedFiles = directoryContents.filter { $0.absoluteString.contains(searchQuery) }
// documentUrl is the local URL which we just downloaded and saved to the FileManager
}.resume()
This is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of
adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps
are needed. Although the algorithm is simple, it is too slow and impractical for most problems. It has complexity of
O(n2) but it is considered slower than insertion sort.
//mutated copy
var output: Array<Element> = self
return output
}
Insertion sort
Insertion sort is one of the more basic algorithms in computer science. The insertion sort ranks elements by
iterating through a collection and positions elements based on their value. The set is divided into sorted and
unsorted halves and repeats until all elements are sorted. Insertion sort has complexity of O(n2). You can put it in
an extension, like in an example below, or you can create a method for it.
//mutated copy
var output: Array<Element> = self
return output
}
}
Selection sort
Selection sort is noted for its simplicity. It starts with the first element in the array, saving it's value as a minimum
value (or maximum, depending on sorting order). It then itterates through the array, and replaces the min value
with any other value lesser then min it finds on the way. That min value is then placed at the leftmost part of the
array and the process is repeated, from the next index, until the end of the array. Selection sort has complexity of
O(n2) but it is considered slower than it's counterpart - Selection sort.
func selectionSort() -> Array { //check for trivial case guard self.count > 1 else { return self }
//mutated copy
var output: Array<Element> = self
return output
Quicksort is one of the advanced algorithms. It features a time complexity of O(n log n) and applies a divide &
conquer strategy. This combination results in advanced algorithmic performance. Quicksort first divides a large
array into two smaller sub-arrays: the low elements and the high elements. Quicksort can then recursively sort the
sub-arrays.
Reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with
values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its
final position. This is called the partition operation.
Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array
of elements with greater values.
//advance wall
wallIndex += 1
}
}
//move pivot to final position
if wallIndex != pivot {
swap(&self[wallIndex], &self[pivot])
}
return wallIndex
}
//mutated copy
var output: Array<Element> = self
return output
}
}
//mutated copy
var output: Array<Element> = self
return output
}
Linear time O(n): When each item in the array has to be evaluated in order for a function to achieve it's goal,
that means that the function becomes less efficent as number of elements is increasing. A function like this is
said to run in linear time because its speed is dependent on its input size.
Polynominal time O(n2): If complexity of a function grows exponentialy (meaning that for n elements of an
array complexity of a function is n squared) that function operates in polynominal time. These are usually
functions with nested loops. Two nested loops result in O(n2) complexity, three nested loops result in O(n3)
complexity, and so on...
Logarithmic time O(log n): Logarithmic time functions's complexity is minimized when the size of its inputs
(n) grows. These are the type of functions every programmer strives for.
2. Reorder the array so that all elements with values less than the pivot come before the pivot, while all
elements with values greater than the pivot come after it (equal values can go either way). After this
partitioning, the pivot is in its final position. This is called the partition operation.
3. Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-
array of elements with greater values.
//advance wall
wallIndex += 1
}
}
In computer science, a graph is an abstract data type that is meant to implement the undirected graph and directed
graph concepts from mathematics. A graph data structure consists of a finite (and possibly mutable) set of vertices
or nodes or points, together with a set of unordered pairs of these vertices for an undirected graph or a set of
ordered pairs for a directed graph. These pairs are known as edges, arcs, or lines for an undirected graph and as
arrows, directed edges, directed arcs, or directed lines for a directed graph. The vertices may be part of the graph
structure, or may be external entities represented by integer indices or references. A graph data structure may also
associate to each edge some edge value, such as a symbolic label or a numeric attribute (cost, capacity, length, etc.).
(Wikipedia, source)
//
// GraphFactory.swift
// SwiftStructures
//
// Created by Wayne Bishop on 6/7/14.
// Copyright (c) 2014 Arbutus Software Inc. All rights reserved.
//
init() {
canvas = Array<Vertex>()
isDirected = true
}
return childVertex
}
//mutated copy
var output = head
while(current != nil) {
next = current.previous
current.previous = prev
prev = current
current = next
}
sourcePath.destination = source
sourcePath.previous = prev
sourcePath.total = nil
output = sourcePath
return output
newPath.destination = e.neighbor
newPath.previous = nil
newPath.total = e.weight
while frontier.count != 0 {
for x in 0..<frontier.count {
newPath.destination = e.neighbor
newPath.previous = bestPath
newPath.total = bestPath.total + e.weight
} //end while
if (itemPath.destination.key == destination.key) {
return shortestPath
newPath.destination = e.neighbor
newPath.previous = nil
newPath.total = e.weight
while frontier.count != 0 {
newPath.destination = e.neighbor
newPath.previous = bestPath
newPath.total = bestPath.total + e.weight
} //end while
return shortestPath
while !graphQueue.isEmpty() {
/*
notes: this demonstrates how to invoke a closure with an inout parameter.
By passing by reference no return value is required.
*/
//invoke formula
formula(&vitem)
} //end while
while !graphQueue.isEmpty() {
vitem!.visited = true
print("traversed vertex: \(vitem!.key!)..")
} //end while
} //end function
while !graphQueue.isEmpty() {
//apply formula..
if formula(vitem!) == false {
print("formula unable to update: \(vitem!.key)")
}
else {
print("traversed vertex: \(vitem!.key!)..")
}
vitem!.visited = true
Trie
In computer science, a trie, also called digital tree and sometimes radix tree or prefix tree (as they can be searched
by prefixes), is a kind of search tree—an ordered tree data structure that is used to store a dynamic set or
associative array where the keys are usually strings. (Wikipedia, source)
//
// Trie.swift
// SwiftStructures
//
// Created by Wayne Bishop on 10/14/14.
// Copyright (c) 2014 Arbutus Software Inc. All rights reserved.
//
import Foundation
init(){
root = TrieNode()
}
//trivial case
guard keyword.length > 0 else {
return
}
if (child.key == searchKey) {
childToUse = child
break
}
//new node
if childToUse == nil {
childToUse = TrieNode()
childToUse.key = searchKey
childToUse.level = current.level + 1
current.children.append(childToUse)
}
current = childToUse
} //end while
} //end function
//trivial case
guard keyword.length > 0 else {
return nil
}
if (child.key == searchKey) {
childToUse = child
current = childToUse
break
}
if childToUse == nil {
return nil
}
} //end while
if (child.isFinal == true) {
wordList.append(child.key)
}
return wordList
} //end function
(GitHub, source)
Stack
In computer science, a stack is an abstract data type that serves as a collection of elements, with two principal
operations: push, which adds an element to the collection, and pop, which removes the most recently added
element that was not yet removed. The order in which elements come off a stack gives rise to its alternative name,
LIFO (for last in, first out). Additionally, a peek operation may give access to the top without modifying the stack.
(Wikipedia, source)
class Stack<T> {
init() {
top = Node<T>()
}
return x
if self.count > 1 {
top = top.next
}
else {
top.key = nil
}
//determine instance
if let topitem = top.key {
return topitem
}
else {
return nil
}
if self.count == 0 {
return true
}
else {
return false
}
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C (Swift 3.1 Edition).” iBooks.
https://itun.es/us/utTW7.l
You are responsible for handling the life cycle of any memory you work with through buffer pointers, to avoid leaks
or undefined behavior.
You use instances of the UnsafeMutablePointer type to access data of a specific type in memory. The type of data
that a pointer can access is the pointer's Pointee type. UnsafeMutablePointer provides no automated memory
management or alignment guarantees. You are responsible for handling the life cycle of any memory you work with
through unsafe pointers to avoid leaks or undefined behavior.
Memory that you manually manage can be either untyped or bound to a specific type. You use the
UnsafeMutablePointer type to access and manage memory that has been bound to a specific type. (Source)
import Foundation
let x = pointer.pointee[3]
print(x)
pointer.deinitialize()
pointer.deallocate(capacity: 4)
class A {
var x: String?
pointer2.pointee
let y = pointer2.pointee[1]
print(y)
pointer2.deinitialize()
pointer2.deallocate(capacity: 2)
Purpose:
Creates a new string by copying and validating the null-terminated UTF-8 data referenced by the given pointer.
This initializer does not try to repair ill-formed UTF-8 code unit sequences. If any are found, the result of the
initializer is nil. The following example calls this initializer with pointers to the contents of two different CChar
arrays---the first with well-formed UTF-8 code unit sequences and the second with an ill-formed sequence at the
end.
Source, Apple Inc., Swift 3 header file (For header access: In Playground, Cmd+Click on the word Swift)
in the line of code:
import Swift
Suppose We have an multidimensional array of cities & we want to sorted city name list in ascending order. In that
case we can use flatMap function like:
let arrStateName = [["Alaska", "Iowa", "Missouri", "New Mexico"], ["New York", "Texas",
"Washington", "Maryland"], ["New Jersey", "Virginia", "Florida", "Colorado"]]
For sorting array values, we can use chaining operation or sort flatten array. Here below example showing chaining
operation,
// Swift 3 syntax
let arrSortedStateList = arrStateName.flatMap({ $0 }).sorted(by: <) // ["Alaska", "Colorado",
"Florida", "Iowa", "Maryland", "Missouri", "New Jersey", "New Mexico", "New York", "Texas",
"Virginia", "Washington"]
struct User {
var name: String
var age: Int
var country: String?
}
//User's information
let user1 = User(name: "John", age: 24, country: "USA")
let user2 = User(name: "Chan", age: 20, country: nil)
let user3 = User(name: "Morgan", age: 30, country: nil)
let user4 = User(name: "Rachel", age: 20, country: "UK")
let user5 = User(name: "Katie", age: 23, country: "USA")
let user6 = User(name: "David", age: 35, country: "USA")
let user7 = User(name: "Bob",age: 22, country: nil)
Map Function:
Use map to loop over a collection and apply the same operation to each element in the collection. The map
function returns an array containing the results of applying a mapping or transform function to each item.
Flat-Map Function:
Filter Function:
Use filter to loop over a collection and return an Array containing only those elements that match an include
condition.
Reduce:
Use reduce to combine all items in a collection to create a single new value.
Swift 2.3:
Swift 3:
completion()
}
}
struct OutpuData {
var data = Data()
var result: ReadResult
var error: Error?
}
}
}
readData(from: "https://raw.githubusercontent.com/trev/bearcal/master/sample-data-large.json") {
(output) in
switch output.result {
case .Successful:
break
case .Failed:
}
}
Structural design patterns focus on the composition of classes and objects to create interfaces and achieve
greater functionality.
In Swift, Adapters can often be formed through the use of protocols. In the following example, a Client able to
communicate with the Target is provided with the ability to perform functions of the Adaptee class through the use
of an adapter.
// Adapter used to pass the request on the Target to a request on the Adaptee
extension Adaptee: TargetFunctionality {
func fooBar() {
foo()
}
}
Example flow of a one-way adapter: Client -> Target -> Adapter -> Adaptee
Adapters can also be bi-directional, and these are known as two-way adapters. A two-way adapter may be useful
when two different clients need to view an object differently.
The following is an example of a Facade used to set and retrieve objects in UserDefaults.
enum Defaults {
The complexities of accessing the shared instance and synchronizing UserDefaults are hidden from the client, and
this interface can be accessed from anywhere in the program.
Kitura is a web framework written in swift that is created for web services. It's very easy to set up for HTTP
requests. For environment, it needs either OS X with XCode installed, or Linux running swift 3.0.
First, create a file called Package.swift. This is the file that tells swift compiler where the libraries are located. In this
hello world example, we are using GitHub repos. We need Kitura and HeliumLogger. Put the following code inside
Package.swift. It specified the name of the project as kitura-helloworld and also the dependency urls.
import PackageDescription
let package = Package(
name: "kitura-helloworld",
dependencies: [
.Package(url: "https://github.com/IBM-Swift/HeliumLogger.git", majorVersion: 1, minor:
6),
.Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 6) ] )
Next, create a folder called Sources. Inside, create a file called main.swift. This is the file that we implement all the
logic for this application. Enter the following code into this main file.
import Kitura
import Foundation
import HeliumLogger
HeliumLogger.use()
Adding a router. Router specifies a path, type, etc of the HTTP request. Here we are adding a GET request handler
which prints Hello world, and then a post request that reads plain text from the request and then send it back.
router.get("/get") {
request, response, next in
response.send("Hello, World!")
next()
}
router.post("/post") {
request, response, next in
var string: String?
do{
string = try request.readString()
Bind the router and port together and add them as HTTP service
Execute
Navigate to the root folder with Package.swift file and Resources folder. Run the following command. Swift compiler
will automatically download the mentioned resources in Package.swift into Packages folder, and then compile these
resources with main.swift
swift build
When the build is finished, executable will be placed at this location. Double click this executable to start the server.
.build/debug/kitura-helloworld
Validate
Open a browser, type in localhost:8080/get as url and hit enter. The hello world page should come out.
Open a HTTP request app, post plain text to localhost:8080/post. The respond string will show the entered text
correctly.
}
if initialsArray.count > 1, let lastWord = initialsArray.last {
if let lastLetter = lastWord.characters.first {
initials += String(lastLetter).capitalized
}
}
} else {
return nil
}
nameLabel.text = initials
UIGraphicsBeginImageContext(frame.size)
if let currentContext = UIGraphicsGetCurrentContext() {
nameLabel.layer.render(in: currentContext)
let nameImage = UIGraphicsGetImageFromCurrentImageContext()
return nameImage
}
return nil
}
4444 Chapter 30
Abdul Yasin Chapter 45
Accepted Answer Chapters 5, 15, 21 and 23
Adam Bardon Chapter 38
Adda_25 Chapter 32
Ahmad F Chapter 42
Ajith R Nayak Chapter 16
Ajwhiteway Chapter 2
AK1 Chapters 2, 7 and 19
Akshit Soota Chapter 12
Alessandro Chapter 30
Alessandro Orrù Chapter 34
Alex Popov Chapter 4
Alexander Olferuk Chapter 40
AMAN77 Chapter 42
Anand Nimje Chapter 37
Andrea Antonioni Chapter 12
Andreas Chapter 22
Andrey Gordeev Chapter 24
Andy Ibanez Chapter 16
andyvn22 Chapter 37
antonio081014 Chapter 12
Asdrubal Chapters 26 and 29
AstroCB Chapter 12
atxe Chapter 19
Avi Chapter 4
avismara Chapter 25
Bartłomiej Semańczyk Chapter 48
Ben Trengrove Chapter 10
Brduca Chapters 13, 19, 33 and 42
Caleb Kleveter Chapters 6, 12, 16, 21, 28 and 48
Christopher Oezbek Chapter 20
Cory Wilhite Chapter 5
ctietze Chapter 8
Cyril Ivar Garcia Chapter 3
D31 Chapter 28
D4ttatraya Chapters 10, 38 and 48
Dalija Prasnikar Chapters 5 and 14
DanHabib Chapter 38
DarkDust Chapters 10, 19 and 24
David Chapter 13
Diogo Antunes Chapters 4, 7 and 11
Duncan C Chapters 2 and 8
Echelon Chapters 35 and 44
egor.zhdan Chapters 9 and 12
elprl Chapter 2
Esqarrouth Chapter 13
esthepiking Chapters 1 and 5
Fangming Ning Chapter 59