Mobile Development 40 min read

Comprehensive Swift Language Tutorial: Basics, Syntax, and Advanced Features

This extensive Swift tutorial introduces the language’s fundamentals—including variables, constants, control flow, functions, closures, enums, and memory management—while providing detailed code examples and explanations of advanced concepts such as protocols, generics, and ARC, making it a complete guide for iOS and macOS developers.

Wukong Talks Architecture
Wukong Talks Architecture
Wukong Talks Architecture
Comprehensive Swift Language Tutorial: Basics, Syntax, and Advanced Features

Swift is a modern, safe, and fast programming language for developing iOS, macOS, watchOS, and tvOS applications, offering features like Playgrounds for instant code preview without compilation.

It enforces safety through mandatory variable initialization, array bounds checking, integer overflow detection, optionals for nil handling, and automatic memory management, while providing robust error handling mechanisms.

Fundamentals

Constants and Variables

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
// type annotation
var welcomeMessage: String

Comments

// This is a comment

/* This is a multi-line comment */
/* This is a nested comment
/* Nested */
End of first comment */

Semicolons

let cat = "🐱"; print(cat)
// prints "🐱"

Integers and Floating‑point Numbers

let minValue = UInt8.min  // 0
let maxValue = UInt8.max  // 255

Type Safety and Type Inference

let meaningOfLife = 42   // inferred as Int
let pi = 3.14159        // inferred as Double

Numeric Literals and Conversions

let decimalInteger = 17
let binaryInteger = 0b10001   // 17 in binary
let octalInteger = 0o21        // 17 in octal
let hexadecimalInteger = 0x11  // 17 in hex

Type Aliases

typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min

Booleans

let orangesAreOrange = true
let turnipsAreDelicious = false

Tuples let http404Error = (404, "Not Found") Optionals

var serverResponseCode: Int? = 404
serverResponseCode = nil

Error Handling

func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

Assertions and Preconditions

let age = -3
assert(age >= 0, "A person's age cannot be less than zero")

Basic Operators

Swift supports most standard C operators and adds range operators such as a..<b (half‑open) and a...b (closed).

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    print("第 \(i + 1) 个人叫 \(names[i])")
}

Strings and Characters

String literals, interpolation, character counting, concatenation, and comparison are demonstrated.

// Multi‑line string literal
let quotation = """
The White Rabbit put on his spectacles.  
Where shall I begin, please your Majesty?
"""
let singleLineString = "These are the same."
let multilineString = """
These are the same.
"""
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")

Collection Types

Arrays, Sets, and Dictionaries are introduced with examples of mutability and common operations.

// Array
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
var threeDoubles = Array(repeating: 0.0, count: 3)
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
var sixDoubles = threeDoubles + anotherThreeDoubles
var shoppingList: [String] = ["Eggs", "Milk"]
for (index, value) in shoppingList.enumerated() {
    print("Item \(index + 1): \(value)")
}
// Dictionary
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2

Control Flow

For‑In loops, while/repeat‑while loops, guard statements, and API availability checks are shown.

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
    print("Hello, \(name)!")
}
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}
repeat {
    // statements
} while condition

func greet(person: [String: String]) {
    guard let name = person["name"] else { return }
    print("Hello \(name)!")
    guard let location = person["location"] else {
        print("I hope the weather is nice near you.")
        return
    }
    print("I hope the weather is nice in \(location).")
}

Functions

Function definitions, parameter labels, return values, optional tuple returns, and inout parameters are covered.

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}
func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)!  Glad you could visit from \(hometown)."
}
func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.isEmpty { return nil }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin { currentMin = value }
        else if value > currentMax { currentMax = value }
    }
    return (currentMin, currentMax)
}
func greeting(for person: String) -> String { "Hello, " + person + "!" }

Closures

Closure syntax, trailing closures, value capture, escaping closures, and auto‑closures are illustrated.

let digitNames = [0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"]
let numbers = [16, 58, 510]
let strings = numbers.map { (number) -> String in
    var number = number
    var output = ""
    repeat {
        output = digitNames[number % 10]! + output
        number /= 10
    } while number > 0
    return output
}
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count) // 5
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count) // 5
print("Now serving \(customerProvider())!")
print(customersInLine.count) // 4

Enumerations

Enum syntax, associated values, raw values, and recursive enums are demonstrated.

enum CompassPoint { case north, south, east, west }
enum Planet { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune }
let somePlanet = Planet.earth
switch somePlanet {
case .earth: print("Mostly harmless")
default: print("Not a safe place for humans")
}
enum Barcode { case upc(Int, Int, Int, Int); case qrCode(String) }
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
indirect enum ArithmeticExpression { case number(Int); case addition(ArithmeticExpression, ArithmeticExpression); case multiplication(ArithmeticExpression, ArithmeticExpression) }
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, .number(2))
func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value): return value
    case let .addition(left, right): return evaluate(left) + evaluate(right)
    case let .multiplication(left, right): return evaluate(left) * evaluate(right)
    }
}
print(evaluate(product)) // 18

Structures and Classes

Definition, properties, methods, and differences between value and reference types are shown.

struct SomeStructure { }
class SomeClass { }
struct Resolution { var width = 0; var height = 0 }
class VideoMode { var resolution = Resolution(); var interlaced = false; var frameRate = 0.0; var name: String? }

Properties

Stored, computed, property observers, property wrappers, and type properties are explained.

struct Point { var x = 0.0, y = 0.0 }
struct Size { var width = 0.0, height = 0.0 }
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}
@propertyWrapper
struct TwelveOrLess {
    private var number = 0
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}

Methods

Instance and type (static) methods are illustrated.

class Counter {
    var count = 0
    func increment() { count += 1 }
    func increment(by amount: Int) { count += amount }
    func reset() { count = 0 }
}

Subscripts

Subscript syntax for arrays, dictionaries, and static subscripts on enums is shown.

struct TimesTable { let multiplier: Int; subscript(index: Int) -> Int { return multiplier * index } }
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])") // 18
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
enum Planet: Int { case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
    static subscript(n: Int) -> Planet { return Planet(rawValue: n)! }
}
let mars = Planet[4]
print(mars)

Inheritance

Base class, subclassing, overriding, and final are demonstrated.

class Vehicle {
    var currentSpeed = 0.0
    var description: String { return "traveling at \(currentSpeed) miles per hour" }
    func makeNoise() {}
}
class Car: Vehicle {
    var gear = 1
    override var description: String { return super.description + " in gear \(gear)" }
}
class AutomaticCar: Car {
    override var currentSpeed: Double {
        didSet { gear = Int(currentSpeed / 10.0) + 1 }
    }
}

Initialization and Deinitialization

Designated and convenience initializers, failable initializers, required initializers, and deinit examples are provided.

struct Fahrenheit { var temperature: Double = 32.0 }
struct Color { let red, green, blue: Double; init(red: Double, green: Double, blue: Double) { self.red = red; self.green = green; self.blue = blue }
    init(white: Double) { self.red = white; self.green = white; self.blue = white } }
class Bank { static var coinsInBank = 10_000; static func distribute(coins numberOfCoinsRequested: Int) -> Int { let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank); coinsInBank -= numberOfCoinsToVend; return numberOfCoinsToVend }
    static func receive(coins: Int) { coinsInBank += coins } }
class Player { var coinsInPurse: Int; init(coins: Int) { coinsInPurse = Bank.distribute(coins: coins) }
    func win(coins: Int) { coinsInPurse += Bank.distribute(coins: coins) }
    deinit { Bank.receive(coins: coinsInPurse) } }

Optional Chaining

class Person { var residence: Residence? }
class Residence { var numberOfRooms = 1 }
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).")
} else {
    print("Unable to retrieve the number of rooms.")
}
john.residence = Residence()
if let roomCount = john.residence?.numberOfRooms {
    print("John's residence has \(roomCount) room(s).")
}

Type Casting

class MediaItem { var name: String; init(name: String) { self.name = name } }
class Movie: MediaItem { var director: String; init(name: String, director: String) { self.director = director; super.init(name: name) } }
class Song: MediaItem { var artist: String; init(name: String, artist: String) { self.artist = artist; super.init(name: name) } }
let library: [MediaItem] = [Movie(name: "Casablanca", director: "Michael Curtiz"), Song(name: "Blue Suede Shoes", artist: "Elvis Presley"), Movie(name: "Citizen Kane", director: "Orson Welles"), Song(name: "The One And Only", artist: "Chesney Hawkes"), Song(name: "Never Gonna Give You Up", artist: "Rick Astley")]
for item in library {
    if let movie = item as? Movie {
        print("Movie: \(movie.name), dir. \(movie.director)")
    } else if let song = item as? Song {
        print("Song: \(song.name), by \(song.artist)")
    }
}

Nested Types

struct BlackjackCard {
    enum Suit: Character { case spades = "1", hearts = "2", diamonds = "3", clubs = "4" }
    enum Rank: Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
        struct Values { let first: Int; let second: Int? }
        var values: Values {
            switch self {
            case .ace: return Values(first: 1, second: 11)
            case .jack, .queen, .king: return Values(first: 10, second: nil)
            default: return Values(first: self.rawValue, second: nil)
            }
        }
    }
    let rank: Rank, suit: Suit
    var description: String {
        var output = "suit is \(suit.rawValue), value is \(rank.values.first)"
        if let second = rank.values.second { output += " or \(second)" }
        return output
    }
}
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue

Extensions

Adding computed properties, initializers, methods, subscripts, and protocol conformance.

extension Rect {
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 3)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}
3.repetitions { print("Hello!") }
extension Int { mutating func square() { self = self * self } }
var someInt = 3
someInt.square() // now 9

Protocols

protocol FullyNamed { var fullName: String { get } }
struct Person: FullyNamed { var fullName: String }
class Starship: FullyNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) { self.name = name; self.prefix = prefix }
    var fullName: String { return (prefix != nil ? prefix! + " " : "") + name }
}
let ncc1701 = Starship(name: "Enterprise", prefix: "USS")
print(ncc1701.fullName) // USS Enterprise

Generics

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3, anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
var someString = "hello", anotherString = "world"
swapTwoValues(&someString, &anotherString)

Opaque Types

protocol Shape { func draw() -> String }
struct Triangle: Shape { var size: Int; func draw() -> String { var result = [String](); for length in 1...size { result.append(String(repeating: "*", count: length)) } return result.joined(separator: "
") } }
struct FlippedShape<T: Shape>: Shape { var shape: T; func draw() -> String { let lines = shape.draw().split(separator: "
"); return lines.reversed().joined(separator: "
") } }
let smallTriangle = Triangle(size: 3)
print(smallTriangle.draw())
let flippedTriangle = FlippedShape(shape: smallTriangle)
print(flippedTriangle.draw())

Automatic Reference Counting (ARC)

class Person { let name: String; init(name: String) { self.name = name; print("\(name) is being initialized") } deinit { print("\(name) is being deinitialized") } var apartment: Apartment? }
class Apartment { let unit: String; init(unit: String) { self.unit = unit } weak var tenant: Person? deinit { print("Apartment \(unit) is being deinitialized") } }
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // Person deinitialized, apartment remains because of weak reference

Memory Safety

func balance(_ x: inout Int, _ y: inout Int) {
    let sum = x + y
    x = sum / 2
    y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // ok
// balance(&playerOneScore, &playerOneScore) // error: conflict

Access Control

Explanation of open, public, internal, fileprivate, and private levels with examples.

public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
public class SomePublicClass {
    public var somePublicProperty = 0
    var someInternalProperty = 0
    fileprivate func someFilePrivateMethod() {}
    private func somePrivateMethod() {}
}

Advanced Operators

let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits // 0b11110000
var potentialOverflow = Int16.max
// potentialOverflow += 1 // overflow error
struct Vector2D { var x = 0.0, y = 0.0 }
extension Vector2D { static func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } }
let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector // (5.0, 5.0)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Mobile DevelopmentiOSprogrammingSwiftCode ExamplesTutorial
Wukong Talks Architecture
Written by

Wukong Talks Architecture

Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.