DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

  1. DZone
  2. Refcards
  3. Swift Essentials
refcard cover
Refcard #235

Swift Essentials

Explore the essentials of this open source, type-safe, object-oriented programming language.

With its rapid development process, impressive safety and performance, and spirited open source community, Swift has quickly become the language of choice for iOS, macOS, and Linux applications. This Refcard will get you started with Swift, provides a quick reference guide for Swift syntax, and explores security and testing features in the world’s fastest growing programming language today.

Download Refcard
Free PDF for Easy Reference
refcard cover

Written By

author avatar James Sugrue
Chief Technology Officer, Over-C
author avatar Alex Blewitt
Author and Tech Writer, Bandlem Ltd.
Table of Contents
► Introduction ► Getting Started ► Optionality ► Classes and Structs ► Protocols and Extensions ► Functional Programming ► Security in Swift ► Testing in Swift ► Swift Quick Reference ► Other Resources
Section 1

Introduction

Swift is the fastest growing programming language today. It is built on LLVM, which is a key part of both Clang and other popular native runtimes like Rust and Julia. It's easy to learn, compiles down to native code, and interoperates with existing languages like Objective-C. Developers are increasingly using this modern, type-safe, object-oriented/functional programming language for more than client-side mobile apps. This is because this popular mobile language moved into an open source project at Swift.org under an Apache license in December of 2015, just over a year after it was introduced at Apple's WWDC 2014 developer event. Developers from around the world are working to ensure Swift is available for use in other environments and for efforts spanning Web, Mobile, Cloud and IoT. As Swift, the programming language, matures, it can increasingly be the language of choice end-to-end, bringing its modern advantages to both client-side and server-side deployments.

Section 2

Getting Started

Although Swift is a compiled language, it comes with an interpreter swift which can be used to experiment with files and functions. For example, a factorial function can be defined in the interpreter as follows:

1
$ swift
2
Welcome to Swift 
3
  func factorial(i:UInt) -> UInt {
4
    if i == 0 {
5
      return 1
6
    } else {
7
      return i * factorial(i-1)
8
    }
9
  }
10
factorial(5)
11
$R0: UInt = 120

This shows several features of Swift: the interpreter, which makes it really easy to experiment with code; the fact that the language is strongly typed (the function takes an unsigned integer argument, and returns an unsigned integer argument); and that--unlike C-derived languages--the type is on the right of the variable instead of the left (i.e. i:UInt and not UInt i).The reason for the type appearing on the right is that Swift uses type inference where possible so that the types don't need to be declared:

2
1
let fiveFactorial = factorial(5)
2
fiveFactorial: UInt = 120 

The let is a constant definition, which means it can't be changed. It has also been inferred to be a UInt, because that's what the return type of factorial was. Variables also exist, and are declared using the var keyword:

4
1
var myFactorial = factorial(6)
2
myFactorial: UInt = 720
3
myFactorial = factorial(7)
4
myFactorial: UInt = 5040

Being a typed language, it is not possible to assign a value to a variable of the wrong type (or to initialize a constant with the wrong type):

3
1
myFactorial = -1 
2
error: repl.swift:15:15: error: negative integer '-1' overflows when stored into unsigned type 'UInt' 
3
myFactorial = -1 
Section 3

Optionality

Swift has a specific way of dealing with optionality; it encodes it into the type system. Instead of having values which may be reference types having a nil value by default, variables explicitly opt-in to being an optional type or not. This also applies to value types like integers, although the overhead is far less than a primitive wrapper like Integer  in languages such as Java.

4
1
var thinkOfANumber: Int?
2
thinkOfANumber: Int? = nil
3
thinkOfANumber = 4; // chosen by random dice roll
4
thinkOfANumber: Int? = 4

Under the covers, there is a generic Optional<Int> type, but for brevity the ?   suffix can be used instead, which means the same thing.

Optional values can be unpacked using either ?? (which allows
for a default value to be substituted in case of being nil) or forcibly with !. In most cases these are unnecessary since it's possible to call a function using ?. on an optional type, which returns an optional result, or to use a map function to transform it into a different value.

​x
1
thinkOfANumber?.successor()
2
$R0: Int? = 5
3
​
4
thinkOfANumber ?? 0
5
$R1: Int? = 4
6
​
7
thinkOfANumber = nil
8
thinkOfANumber?.successor()
9
$R2: Int? = nil
10
​
11
thinkOfANumber ?? 0
12
$R3: Int = 0
Section 4

Classes and Structs

Swift has reference types and value types in the language, which are defined in classes and structs. Classes are passed into functions by reference, and structs are passed by value (copied). They can both have methods associated with them, and the syntax for calling methods is identical in both cases. The only significant difference is that structs can't inherit from other structs (although they can embed them).

18
1
struct Time {
2
   var hh: UInt8
3
   var mm: UInt8
4
   var ss: UInt8
5
   var display: String {
6
     return "\(hh):\(mm):\(ss)"
7
   }
8
 }
9
class Clock {
10
   let time: Time
11
   let h24: Bool
12
   init(h24: Bool = true) {
13
     self.h24 = h24
14
     self.time = Time(hh: h24 ? 13 : 1, mm:15, ss:23) 
15
   }
16
 }
17
Clock().time.display
18
$R0: String = "13:15:23"

The example above demonstrates how a struct and a class are defined. A value type Time (storing the hours, minutes, and seconds as unsigned bytes – UInt8) allows mutable updates to the fields, and has a computed property display that returns a formatted String. Computed properties are represented with var (if they are mutable) or let (if they are immutable). A function could have been used instead, but then the invocation would have been time() in the example at line 3 in that case.

The class Clock stores a Time struct inside. Unlike languages such as Java or C#, the struct is in-lined into the class definition rather than as a separate pointer to a different area of memory. (This helps cache locality and reduces memory fragmentation.)

Constructors have the special name init, and can have named arguments. In this case, the property h24 can be configured from initialization, although default parameter values can be used to supply the values on demand. Constructors for classes and structs are both called with the class name; Clock() and Time() will create instances of both. In the case of structures, the constructor is automatically created based on the names of the fields.

Finally, properties can be defined with either let or var. In this case, the time field is declared as a constant with let, so although the Time type allows mutability of its fields in general, in this specific case the time field cannot be mutated:

2
1
Clock().time.hh = 10
2
 error: cannot assign to property: 'time' is a 'let' constant
Section 5

Protocols and Extensions

It is possible to extend an existing class or struct by adding functions to the type. The new method can be used anywhere the extension is in scope.

7
1
 extension Clock {
2
   func tick() -> String {
3
     return "tock"
4
   }
5
 }
6
Clock().tick()
7
$R1: String = "tock"

Adding extensions to types doesn't require the code for the original to be changed; so it's possible to extend the built-in types with additional functionality:

9
1
25> 1.negate()
2
 error: value of type 'Int' has no member 'negate'
3
 26> extension Int {
4
 27.   func negate() -> Int {
5
 28.     return -self
6
 29.   }
7
 30. }
8
 31> 1.negate()
9
 $R2: Int = -1

This exposes the fact that a literal 1 is actually a struct type; we can add new functions to the structure that perform different operations. Since it's an immutable struct, we can't change the value of the constant; but we can add constant properties and functions to the mix.

This hasn't added negation to all integer types though, only the Int type -- which is a typealias for the platform's default word size (64 bits on a 64-bit system, 32 bits on a 32-bit system).

2
1
Int8(1).negate()
2
error: value of type 'Int8' has no member 'negate'

This can be solved by adding an extension to a protocol instead of the actual type. A protocol is like an interface in other languages; it's an abstract type representation that has no implementation body, and types (both struct and class) can adopt protocols at definition time.

The Int type adopts several protocols; IntegerType (which is the parent of all integer types, including unsigned ones) and SignedNumberType (amongst others). We can add the extension to this protocol instead:

5
1
extension SignedNumberType {
2
   func negate() -> Self {
3
     return -self
4
   }
5
 }

Note that the return type of the negate function is now Self--this is a special type for generic values that returns the actual type of the object, rather than a generic implementation of the SignedNumberType interface. This allows an Int8 to be negated into an Int8, and an Int16 to be negated to an Int16.

4
1
Int8(1).negate()
2
 $R3: Int8 = -1
3
Int16(1).negate()
4
 $R4: Int16 = -1

Extensions can be used to retroactively adopt procotols for classes. Unlike Go, which uses structural interface adoption to automatically align interfaces, Swift uses an opt-in model where types explicitly have to say that they adopt the protocol in order to use it. Unlike Java or C#, these don't have to be done at the type definition time; they can be added retroactively through extensions.

7
1
 extension Clock: CustomStringConvertible {
2
   public var description: String {
3
     return "The time is: \(time.display)"
4
   }
5
 }
6
print(Clock())
7
The time is: 13:15:23
Section 6

Functional Programming

As well as object-oriented programming, Swift can be used for functional programming. Built-in data structures provide a way of taking existing functions and processing values:

5
1
func factorial(i:UInt) -> UInt {
2
   if i == 0 { return 1 } else { return i * factorial(i-1) }
3
}
4
[1,2,3,4,5].map(factorial)
5
$R0: [UInt] = 5 values { 1, 2, 6, 24, 120 }

Swift also allows anonymous functions using a { } block and an in to separate functions from the return result:

2
1
[1,2,3,4,5].map( { i in i * 2 } )
2
$R1: [Int] = 3 values { 2, 4, 6, 8, 10  }

This can be syntactically rewritten by placing the anonymous function after the map call:

4
1
[1,2,3,4,5].map() {
2
   i in i * 2
3
}
4
$R2: [Int] = 3 values { 2,4,5,8,10 }

It's also possible to iterate over loops using a for ... in with an optional where clause:

3
1
for i in [1,2,3,4,5] where i % 2 == 0 {
2
   print(i)
3
 }


Section 7

Security in Swift


When building applications in Swift, as in any other language, security needs to be properly considered. When building iOS apps , some key areas to review when it comes to securing your code include:  


  • Using SSL on all communication so that messages are not intercepted and modified  
  • Configure App Transport Security to provide secure default behavior  
  • Validate incoming and outgoing URL handler calls 
  • Do not store passwords, private keys or identities within your application. Instead use Keychain Services.  
  • Avoid SQL injection attacks by using prepared statements in cases where SQLite is being used  


Swift also has a number of libraries available to help with security related concerns such as SSL/TLS , JWT (Swift-JWT), and cryptography (BlueCryptor).  


Section 8

Testing in Swift


Testing in Swift is facilitated through XCTest, which follows the similar test paradigms that you will notice in most major languages. As well as covering the basics of unit testing, the XCTest framework includes APIs for performance testing as well as user interface testing.  

Test classes are always subclasses ofXCTestCase which each test inside that class must exist in a function prefixed with test. Any number of assertions can be added to your tests using the  XCTAssert function and its variants.  

Asynchronous operations can be tested using XCTestExpectation which allows you to specify an amount of time to wait for the completion of the operation before the test is considered to have failed.  

Section 9

Swift Quick Reference

Operators

Operator Function
+ Addition operator.
- Subtraction operator/unary minus (negative value) operator.
* Multiplication operator.
/ Division operator.
= Assignment operator.
% Remainder operator.
== Equal to.
!= Not equal to.
< Less than.
<= Less than or equal to.
> Greater than.
>= Greater than or equal to.
! NOT logical operator.
&& AND logical operator.
|| OR logical operator.
... Range operator, inclusive.
<.. Range operator, exclusive of final value (up to but not including).
// Single-line comment.
/* Begin multiline comment.
*/ End multiline comment.

Variables

Keyword Definition Example
var Defines a mutable (changeable) variable. Variable may be explicitly typed, or Swift will infer variable type.
3
1
var somevar: Int = 1
2
var somevar = 1
3
somevar = 2
let


Defines an immutable (constant) variable. Variable may be explicitly typed, or Swift will infer variable type.

4
1
let somevar: String = 
2
  "something"
3
​
4
let somevar = "different"
"\(x)"


String interpolation; the value of the escaped variable x is inserted into the String.

1
1
"text \(somevar)"

Types

Name Type
Bool


Boolean values true and false.

Int Signed integer value (whole number).
UInt Unsigned integer value (non-negative whole number).
Float 32-bit floating-point number.
Double

64-bit floating-point number

Character Unicode scalar(s) producing a human-readable character
String A series of characters.
Tuple A group of multiple values of any type.
Array

An indexed collection of data.

Set An unordered collection of data of one hashable type.
Dictionary A collection of key-value pairs.

Control Flow

Loops

Keyword Description Example
while

Execute block as long as the while condition is true.

3
1
while somevar > 1 {
2
print(somevar) 
3
}
repeat-while


Executes a block, then repeats as long

as the while condition is true.

3
1
repeat { 
2
  print(somevar)
3
} while somevar > 1
for


Executes a block for a number of times determined

by a boolean expression and iterator defined

in the for loop statement.

4
1
for var i = 0; i < 10;
2
++i {
3
print(i) 
4
}
for-in


Executes a block for each element in an array or range.

4
1
for element in
2
  someArray {
3
  print(element) 
4
}

Conditionals

Keyword Description Example
if

Evaluates a boolean expression and executes a block if the expression is true.


3
1
if somevar < 1 {
2
  print("Less than one.") 
3
}



else


Executes a block once an if statement evaluates as false

6
1
if somevar < 1 { 
2
  print("Less than one.")
3
} else {
4
  print("Not less than
5
     one.") 
6
}


else if


Can chain if statemetns, evaluating boolean

expression once the previous conditional evaluates as false, then executing a block if its expression is true

8
1
if somevar < 1 {
2
  print("Less than one.")
3
} else if somevar == 1 { 
4
  print("Exactly one.")
5
} else { 
6
  print("Greater than
7
    one.") 
8
}


switch


Evaluates conditions based on case and executes a block

for the first matching case; if no matching case exists,

the switch statement executes the block for the default case

9
1
switch someSwitch { 
2
  case 1:
3
    print("One") 
4
  case 2:
5
    print ("Two")
6
  default:
7
    print("Not one or 
8
       two.")
9
}


where


Evaluates additional conditionals in switch cases.

11
1
switch someSwitch {
2
  case 0:
3
    print("Zero")
4
  case 1:
5
    print ("One")
6
  case let x where
7
x.isPrime():
8
print("Prime")
9
  default:
10
print("Not prime")
11
}


guard


Evaluates a boolean expression and, if the expression

is not true, exits the code block containing the guard statement.


6
1
for element in someArray {
2
  guard let x = element
3
    where x > 0 else {
4
break 
5
  }
6
}


Control Transfer

KEYWORD DEscription EXAMPLE
fallthrough Falls into the next case in a switch statement
once a case has already matched.
13
1
switch someSwitch {
2
  case 3:
3
print(“Three.”)
4
fallthrough
5
  case 2:
6
print(“Two.”)
7
fallthrough
8
  case 1:
9
print(“One.”)
10
fallthrough
11
  default:
12
print(“Done.”)
13
}



continue


Ends the current iteration of a loop and

begins the next iteration.

8
1
for i in 1...10 {
2
  if i == 3 { 
3
    continue
4
  } else {
5
print("\(i) is not
6
three.") 
7
  }
8
}



break


Ends execution of a running loop and continues

running code immediately after the loop. Also

used to pass over unwanted cases in switch 

statements (as switch cases must be exhaustive

and must not be empty).

8
1
for i in 1...10 { 
2
  if i == 3 { 
3
    break
4
  } else {
5
print("\(i) is less
6
  than three.") 
7
  }
8
}



Section 10

Other Resources

Tools

  • AppCode: IDE for Mac OS and iOS software developed by JetBrains. jetbrains.com/objc/special/appcode/appcode.jsp
  • CodeRunner: An alternative IDE to Xcode. coderunnerapp.com
  • Xcode: Apple’s IDE for developing software for Mac OS, iOS, WatchOS and tvOS. developer.apple.com/xcode/downloads
  • RunSwift: Browser-based “code bin” which lets you test your code. runswiftlang.com

Libraries

  • Swift Toolbox swifttoolbox.io
  • CocoaPods: Dependency manager for Swift projects. cocoapods.org
  • Carthage: A simple dependency manager for Cocoa projects. github.com/Carthage/Carthage
  • Wolg/awesome-swift: A curated list of Swift frameworks, libraries and software. https://github.com/Wolg/awesome-swift

Communities

• Apple Developer Forums - Swift devforums.apple.com/community/tools/languages/swift

  • StackOver ow: Swift Questions stackoverflow.com/questions/tagged/swift
  • Google Groups: Swift groups.google.com/forum/#!forum/swift-language
  • Swift Language swiftlang.eu/community
  • Swift Meetups meetup.com/find/?keywords=Swift&radius=Infinity

Misc

  • Apple Swift Resources developer.apple.com/swift/resources 
  • Swift Package Manager swift.org/package-manager/ 
  • Github’s Trending Swift Repositories: Track trending Swift repositories to find the hottest projects. github.com/trending?l=swift&since=monthly 
  • Secure iOS Application Development github.com/felixgr/secure-ios-app-dev 
  • Ponemon Institute's Mobile and IoT Application Security Testing Study: https://securityintelligence.com/10-key-findings-from-the-ponemon-institutes-mobile-iot-application-security-testing-study/  

Like This Refcard? Read More From DZone

related article thumbnail

DZone Article

Top 6 Programming Languages for Mobile App Development
related article thumbnail

DZone Article

Object Oriented Programming in Swift
related article thumbnail

DZone Article

Mastering Advanced Traffic Management in Multi-Cloud Kubernetes: Scaling With Multiple Istio Ingress Gateways
related article thumbnail

DZone Article

The Cypress Edge: Next-Level Testing Strategies for React Developers
related refcard thumbnail

Free DZone Refcard

Swift Essentials
related refcard thumbnail

Free DZone Refcard

Mobile Web Application Testing
related refcard thumbnail

Free DZone Refcard

Getting Started With PhoneGap
related refcard thumbnail

Free DZone Refcard

HTML5 Mobile Development

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: