Contents

Swift OOPs

Swift Structures

A structure in Swift is a general-purpose building block used to group variables of different data types into a single unit. Similar to other programming languages, Swift allows defining properties (constants or variables) and methods inside a structure. Unlike classes, structures are value types in Swift, meaning their values are copied when assigned to variables, constants, or passed to functions. Structures are useful for encapsulating data and related functionality.

Syntax

				
					struct StructureName {
    // Properties and methods
}

				
			

Example 1: Creating a Structure

				
					// Swift program to illustrate how to create a structure
import Swift

// Defining a structure
struct Employee {
    var name = "Mohit"
    var id = 1234
    var department = "HR"
    var joiningYear = 2019
}

				
			
Structure Instances

Instances of structures allow access to their properties and methods. They can be created using the initializer syntax.

				
					// Creating an instance of the structure
let employeeInstance = Employee()

				
			

Example 2: Accessing Structure Properties:

				
					// Swift program to demonstrate property access
import Swift

// Defining a structure
struct Employee {
    var name = "Mohit"
    var id = 1234
    var department = "HR"
    var joiningYear = 2019
}

// Creating an instance
let employeeInstance = Employee()

// Accessing properties
print("Employee Name:", employeeInstance.name)
print("Joining Year:", employeeInstance.joiningYear)

				
			

Output:

				
					Employee Name: Mohit  
Joining Year: 2019  

				
			
Memberwise Initializers

Structures in Swift automatically generate a memberwise initializer, which can be used to set property values when creating an instance.

				
					// Swift program demonstrating memberwise initializers
import Swift

// Defining a structure
struct Employee {
    var name = "Mohit"
    var id = 1234
    var department = "HR"
    var joiningYear = 2019
}

// Using memberwise initializer
let updatedEmployee = Employee(id: 5678)
print("Updated Employee ID:", updatedEmployee.id)

				
			

Output:

				
					Updated Employee ID: 5678
				
			

Example 3: Using Functions Inside a Structure

Structures can include functions, referred to as methods.

				
					// Swift program demonstrating a method in a structure
import Swift

// Defining a structure
struct Salary {
    var baseSalary = 230000
    
    func calculateIncrement() {
        let newSalary = 2 * baseSalary
        print("New Salary:", newSalary)
    }
}

// Creating an instance
let salaryInstance = Salary()

// Calling the method
salaryInstance.calculateIncrement()

				
			

Output:

				
					New Salary: 460000  

				
			
Using self in a Structure

The self keyword is used to reference the current instance of a structure, especially when parameter names overlap with property names.

Example:

				
					// Swift program demonstrating the use of self keyword
import Swift

// Defining a structure
struct Article {
    var count = 230
    
    func update(count: Int = 23) {
        let updatedData1 = count + 234
        print("Updated Data 1:", updatedData1)
        
        // Using self to reference the property
        let updatedData2 = self.count + 234
        print("Updated Data 2:", updatedData2)
    }
}

// Creating an instance
let articleInstance = Article()

// Calling the method
articleInstance.update()

				
			

Output:

				
					Updated Data 1: 257  
Updated Data 2: 464  

				
			

Swift Properties and its Different Types

In Swift, properties associate values with a class, structure, or enumeration. They are categorized into stored properties and computed properties:

  • Stored Properties store constant or variable values as part of an instance.
  • Computed Properties calculate a value, rather than storing it, using custom getter and setter methods.
Stored Properties

Stored properties are directly stored within an instance of a type and can either be variable (var) or constant (let).

1. Variable Stored Properties

Example:

				
					// Swift program for variable stored properties

// Creating a structure
struct Person { 
    // Stored property
    var name: String
}

// Creating a Person instance
let person = Person(name: "John") 

// Accessing the property
print("The person's name is \(person.name)")

				
			

Output:

				
					The person's name is John

				
			

2. Constant Stored Properties

Example:

				
					// Swift program for constant stored properties

// Creating a structure
struct Employee { 
    // Constant stored properties
    let age: Int
    let name: String
}

// Creating an Employee instance
let employee = Employee(age: 30, name: "Jane")

// Accessing the properties
print("The employee's name is \(employee.name)")
print("The employee's age is \(employee.age)")

				
			

Output:

				
					The employee's name is Jane
The employee's age is 30

				
			
Lazy Stored Properties

Lazy stored properties defer their initialization until they are first accessed. Use the lazy keyword to declare such properties.

Example:

				
					// Swift program for lazy stored property

// Class containing a lazy property
class Course {
    var courseName: String?
    
    // Lazy property
    lazy var description: String = {
        guard let name = self.courseName else { return "No course available" }
        return "Course: \(name)"
    }()
    
    init(courseName: String) {
        self.courseName = courseName
    }
}

// Using the class
var course = Course(courseName: "Swift")
print(course.description)

				
			

Output:

				
					Course: Swift

				
			
Computed Properties

Computed properties calculate a value using a custom getter (and optionally, a setter). They do not store values directly.

Example:

				
					// Swift program for computed properties

// Structure
struct Rectangle {
    var length: Double
    var width: Double
    
    // Computed property
    var perimeter: Double {
        get {
            return 2 * (length + width)
        }
        set(newPerimeter) {
            length = (newPerimeter - width) / 2
        }
    }
}

var rect = Rectangle(length: 10, width: 5)

// Accessing the computed property
print("Perimeter: \(rect.perimeter)")

// Modifying the property
rect.perimeter = 40

// Accessing updated property
print("Length: \(rect.length)")

				
			

Output:

				
					Perimeter: 30.0
Length: 17.5

				
			
Read-Only Computed Properties

A read-only computed property has only a getter and no setter.

Example:

				
					// Swift program for read-only computed property

// Structure to calculate the volume of a cuboid
struct Cuboid {
    var width: Double
    var height: Double
    var depth: Double
    
    // Read-only computed property
    var volume: Double {
        return width * height * depth
    }
}

// Using the structure
let cuboid = Cuboid(width: 4.0, height: 4.0, depth: 4.0)
print("The volume is \(cuboid.volume)")

				
			

Output:

				
					The volume is 64.0

				
			
Property Observers

Property observers are methods triggered automatically whenever a property’s value is about to be or has just been changed. Use willSet and didSet for observing property changes.

Example:

				
					// Swift program for property observers

// Class to track steps
class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set total steps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue {
                print("Added \(totalSteps - oldValue) new steps")
            }
        }
    }
}

// Using the class
let counter = StepCounter()

counter.totalSteps = 105
counter.totalSteps = 240
counter.totalSteps = 370

				
			

Output:

				
					About to set total steps to 105
Added 105 new steps
About to set total steps to 240
Added 135 new steps
About to set total steps to 370
Added 130 new steps

				
			

Swift Methods

Methods are functions tied to specific types like classes, structures, and enumerations. They are broadly classified into instance methods, which perform tasks specific to an instance, and type methods, which are called on the type itself. Swift distinguishes itself from Objective-C by allowing methods to be defined in structures and enumerations, not just classes.

Instance Methods

Instance methods define behavior that acts on an instance of a type, enabling access to or modification of the instance’s properties.

Syntax

				
					func methodName(parameters) -> ReturnType {
    // Code block
    return value
}

				
			

Example:

				
					class Calculator {
    let x: Int
    let y: Int
    let result: Int
    
    init(x: Int, y: Int) {
        self.x = x
        self.y = y
        self.result = x + y
    }
    
    func subtract(by value: Int) -> Int {
        return result - value
    }
    
    func displayResults() {
        print("Result after subtraction: \(subtract(by: 50))")
        print("Result after subtraction: \(subtract(by: 100))")
    }
}

let calculator = Calculator(x: 200, y: 300)
calculator.displayResults()

				
			

Output:

				
					Result after subtraction: 450
Result after subtraction: 400

				
			
Local and External Parameter Names

Swift methods provide flexibility with parameter names by allowing both local and external parameter names. This helps improve code readability.

Example:

				
					class Divider {
    var quotient: Int = 0
    
    func divide(_ numerator: Int, by denominator: Int) {
        quotient = numerator / denominator
        print("Quotient is: \(quotient)")
    }
}

let divider = Divider()
divider.divide(120, by: 3)
divider.divide(180, by: 6)

				
			

Output:

				
					Quotient is: 40
Quotient is: 30

				
			
Self Keyword in Methods

The self keyword refers to the current instance of a class, structure, or enumeration within its methods.

Example:

				
					class Calculator {
    let x: Int
    let y: Int
    let result: Int
    
    init(x: Int, y: Int) {
        self.x = x
        self.y = y
        self.result = x + y
        print("Inside initializer: \(result)")
    }
    
    func subtract(by value: Int) -> Int {
        return result - value
    }
    
    func showResults() {
        print("Subtraction result: \(subtract(by: 20))")
        print("Subtraction result: \(subtract(by: 30))")
    }
}

let calc1 = Calculator(x: 100, y: 200)
calc1.showResults()

				
			

Output:

				
					Inside initializer: 300
Subtraction result: 280
Subtraction result: 270

				
			
Modifying Value Types with Instance Methods

Structures and enumerations, as value types, cannot modify their properties in normal instance methods. However, using the mutating keyword allows methods to modify properties.

Example

				
					struct Rectangle {
    var length = 1
    var width = 1
    
    func area() -> Int {
        return length * width
    }
    
    mutating func scale(by factor: Int) {
        length *= factor
        width *= factor
        print("Scaled dimensions: Length = \(length), Width = \(width)")
    }
}

var rectangle = Rectangle(length: 4, width: 5)
rectangle.scale(by: 2)
rectangle.scale(by: 3)

				
			

Output:

				
					Scaled dimensions: Length = 8, Width = 10
Scaled dimensions: Length = 24, Width = 30

				
			
Type Methods

Type methods operate on the type itself rather than its instances. Use the class keyword for type methods in classes and the static keyword for structures and enumerations.

Example

				
					class MathOperations {
    class func absoluteValue(of number: Int) -> Int {
        return number < 0 ? -number : number
    }
}

struct Utility {
    static func absoluteValue(of number: Int) -> Int {
        return number < 0 ? -number : number
    }
}

let absValueClass = MathOperations.absoluteValue(of: -10)
let absValueStruct = Utility.absoluteValue(of: -20)
print("Class absolute value: \(absValueClass)")
print("Struct absolute value: \(absValueStruct)")

				
			

Output:

				
					Class absolute value: 10
Struct absolute value: 20

				
			

Difference Between Function and Method

Functions vs. Methods in Swift

While some people use the terms “function” and “method” interchangeably, they have distinct meanings in Swift. Both perform specific tasks and can be reused, but methods are inherently tied to types like classes, structures, or enumerations, while functions are not.

In short, a method is a function that is associated with a type. All methods are functions, but not all functions are methods. Swift uses the func keyword to define both functions and methods.

Functions

A function is a standalone block of code that performs a specific task. Functions can be defined globally and are not associated with any type. They can accept parameters, perform actions, and return results. Functions are independent and can be used anywhere in a program.

Syntax:

				
					func functionName(parameters) -> ReturnType {
    // Body of the function
}

				
			

Example:

				
					// Swift program to illustrate a function

// Function
func greet() {
    print("Hello Swift!")
}

// Calling the function
greet()

				
			

Output:

				
					Hello Swift!

				
			

Methods

A method is a function associated with a type, such as a class, struct, or enum. Methods can be of two types:

1. Instance Methods: Called on instances of a type.
2. Type Methods: Called on the type itself and are prefixed with static or class.

Syntax:

				
					func methodName(parameters) {
    // Body of the method
}

				
			

Example:

				
					// Swift program to illustrate methods

struct Developer {
    let speed: Int

    // Instance method
    func learn() {
        print("Learning at \(speed) MPH")
    }

    // Type method
    static func code() {
        print("Writing Swift code")
    }
}

// Create an instance
let dev = Developer(speed: 15)

// Call instance method
dev.learn()

// Call type method
Developer.code()

				
			

Output:

				
					Learning at 15 MPH  
Writing Swift code

				
			
Difference Between Functions and Methods
AspectFunctionMethod
ExistenceFunctions are independent and can be defined outside of a class, struct, or enum.Methods are always associated with a class, struct, or enum.
ReferenceFunctions do not have reference variables.Methods are accessed using reference variables or instances of a type.
UsageFunctions are called directly.Methods are called using an instance or the type name.
PropertyFunctions are part of structured programming languages.Methods are properties of object-oriented programming languages.
PurposeFunctions are self-contained pieces of code.Methods often manipulate instance variables of the type they belong to.
AssociationFunctions are not tied to any type.Methods are tied to a specific class, struct, or enum.
RelationshipNot every function is a method.Every method is a function.

Swift – Deinitialization and How It Works

Deinitialization in Swift is the process of releasing memory allocated to an instance when it is no longer needed. When a class instance is no longer in use, deinitialization ensures that its memory is freed up for other purposes. This process helps improve memory management by cleaning up unused objects in the system.

Deinitialization is primarily used with class types and is triggered automatically before an instance is deallocated. Swift uses the deinit keyword to define a deinitializer. A class can have only one deinitializer, and it does not accept parameters or return values. You can include custom cleanup code within the deinitializer to perform tasks like releasing resources or saving data.

Syntax:

				
					deinit {
    // Code for deinitialization actions
}

				
			

Example:

				
					// Swift program to store values in arrays

// Initializing an array of integer type
var numbers: [Int] = [1, 3, 5, 7]

// Initializing another array of character type
var characters: [Character] = ["A", "B", "C", "D"]

// Print arrays
print("Numbers Array: \(numbers)")
print("Characters Array: \(characters)")

				
			

Output:

				
					Value of x before deinit = 20  
Value of x after deinit = 0

				
			
How Deinitialization Works

Swift employs Automatic Reference Counting (ARC) to manage memory. When an instance is no longer required, Swift automatically deallocates it, freeing up memory resources. This automated process eliminates the need for manual cleanup, ensuring efficient memory management.

Deinitializers are automatically called just before an instance is deallocated. Subclasses inherit their superclass’s deinitializers, and the superclass’s deinitializer is called after the subclass’s implementation completes. Even if a subclass does not define its own deinitializer, the superclass’s deinitializer will still be invoked.

If memory is not released as expected after a deinitializer is executed, it may be due to properties still referencing the instance, preventing deallocation. In such cases, deinitializers can modify these properties to allow memory release.

Example 1: Basic Deinitialization

In the following example, a variable x is initialized to 10. During the class’s initialization, x is incremented by 10. The value of x is then printed, and the class object is set to nil. This triggers the deinitializer, which resets x to 0.

				
					// Swift program to illustrate deinitialization  

// Initialize a variable x with value 10 
var x = 10 
  
// Create a class 
class DeinitializerExample { 

    // Initialization 
    init() { 
        x += 10 
    } 
      
    // Deinitialization: Set x to 0 
    deinit { 
        x = 0 
    } 
} 
  
// Create an instance of the class  
var obj: DeinitializerExample? = DeinitializerExample() 
  
print("Value of x before deinit = \(x)") 

// Trigger deinitialization 
obj = nil 

print("Value of x after deinit = \(x)")

				
			

Output:

				
					Value of x before deinit = 20  
Value of x after deinit = 0

				
			

Typecasting in Swift

Typecasting in Swift is a way to determine and change the type of an instance of a class, structure, or enumeration. When dealing with objects of different types, typecasting enables runtime type checking and allows safe downcasting to subclass types.

Swift provides two types of typecasting:

1. Upcasting: Converting a subclass instance to its superclass, which is always safe.
2. Downcasting: Converting a superclass instance to its subclass, which requires explicit syntax as it’s not always safe.

Swift provides two main operators for typecasting:

  • is operator: Checks if an instance belongs to a specific subclass type.
  • as operator: Attempts to cast an instance to a subclass type and returns an optional value.
Upcasting

Upcasting refers to converting a subclass instance to its superclass. This is always safe and does not require explicit syntax.

Example:

				
					class Animal { 
    var name: String
    init(name: String) { 
        self.name = name 
    } 
    func makeSound() { 
        print("Animal sound") 
    } 
} 
  
class Dog: Animal { 
    override func makeSound() { 
        print("Woof") 
    } 
} 
  
let dog = Dog(name: "Fido") 
let animal: Animal = dog // Upcasting 
  
print(animal.name) 
animal.makeSound() 

				
			

Output:

				
					Fido
Woof

				
			

Type Checking with is Operator

The is operator checks whether an instance is of a specific type.

Example:

				
					let myInstance: Any = 42 
if myInstance is Int { 
    print("myInstance is an Int") 
} else { 
    print("myInstance is not an Int") 
} 

				
			

Output:

				
					myInstance is an Int

				
			
Type Casting with as? and as!
  • as?: Safely attempts to cast an instance, returning an optional.
  • as!: Forcefully casts an instance, causing a runtime error if it fails.

Example:

				
					class Vehicle { 
    var name: String
    init(name: String) { 
        self.name = name 
    } 
} 
  
class Car: Vehicle { 
    var brand: String
    init(name: String, brand: String) { 
        self.brand = brand 
        super.init(name: name) 
    } 
} 
  
let myVehicle = Car(name: "My Car", brand: "Tesla") 
let myCar = myVehicle as? Car 
if let myCar = myCar { 
    print("My car's brand is \(myCar.brand)") 
} else { 
    print("myVehicle is not a Car") 
} 

				
			

Output:

				
					My car's brand is Tesla

				
			
Any and AnyObject
  • Any: Represents any type, including functions and optionals.
  • AnyObject: Represents any class type.

Example:

				
					let myInstance: Any = 42 
if let myInt = myInstance as? Int { 
    print("myInt is \(myInt)") 
} 
  
struct Car { 
    var name: String
    var brand: String
} 
  
let myObject = Car(name: "My Car", brand: "Tesla") 
print("My car's name is \(myObject.name)")

				
			

Output:

				
					myInt is 42
My car's name is My Car

				
			
Type Erasure

Type erasure hides the concrete type of an object while providing a uniform interface.

Example:

				
					protocol Printable { 
    func printMe() 
} 
  
class Car: Printable { 
    func printMe() { 
        print("I'm a Car") 
    } 
} 
  
class Dog: Printable { 
    func printMe() { 
        print("I'm a Dog") 
    } 
} 
  
struct PrintableBox<T: Printable> { 
    let value: T 
    func printValue() { 
        value.printMe() 
    } 
} 
  
let myCar = Car() 
let box = PrintableBox(value: myCar) 
box.printValue() 

				
			

Output:

				
					I'm a Car

				
			

Repeating Timers in Swift

In Swift, an array is an ordered collection that stores values of the same type. For example, an array declared to hold integers cannot store floating-point numbers. Arrays in Swift can store duplicate values.

When an array is assigned to a variable, it is mutable, meaning you can modify its contents and size. However, when an array is assigned to a constant, it becomes immutable, and you cannot modify it.

Removing Elements in Swift Arrays

You can remove the first element from a Swift array using the removeFirst() function. Additionally, you can use this function to remove multiple elements from the start of the array by specifying the number of elements to remove as an argument.

Syntax

				
					arrayName.removeFirst(x: Int)

				
			

Example 1: Removing a Single Element

				
					import Swift

// String array of authors' names
var authors = ["Alice", "Bob", "Charlie", "Diana", "Eve"]

print("Authors before removing the first element: \(authors)")

// Remove the first element
authors.removeFirst()

print("Authors after removing the first element: \(authors)")

// Integer array of article IDs
var articleIDs = [101, 202, 303, 404, 505]

print("\nArticle IDs before removing the first element: \(articleIDs)")

// Remove the first element
articleIDs.removeFirst()

print("Article IDs after removing the first element: \(articleIDs)")

				
			

Output:

				
					Authors before removing the first element: ["Alice", "Bob", "Charlie", "Diana", "Eve"]
Authors after removing the first element: ["Bob", "Charlie", "Diana", "Eve"]

Article IDs before removing the first element: [101, 202, 303, 404, 505]
Article IDs after removing the first element: [202, 303, 404, 505]

				
			

Repeating Timers in Swift

A repeating timer is a mechanism that schedules code to run at regular intervals. It continues until explicitly stopped. Repeating timers are helpful in scenarios requiring periodic execution, such as polling or periodic updates.

Creating a Repeating Timer

Steps:

1. Create a Timer Object: Use Timer.scheduledTimer to create the timer.

  • timeInterval: Time (in seconds) between repetitions.
  • target: Object that receives the method call when the timer fires.
  • selector: Method called when the timer fires.
  • userInfo: Optional data passed to the method.

2. Start the Timer: Call the fire() method on the timer.
3. Implement the Timer Method: Write the method to be executed each time the timer fires.

Example:

				
					class TimerExample { 
    var timer: Timer? 
      
    func startTimer() { 
        timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true) 
        timer?.fire() 
    } 
      
    func stopTimer() { 
        timer?.invalidate() 
        timer = nil
    } 
      
    @objc func timerFired() { 
        print("Timer fired!") 
    } 
} 
  
let example = TimerExample() 
example.startTimer() 

				
			

Output:

				
					Timer fired!
Timer fired!
Timer fired!
... (repeats every 2 seconds)

				
			
Invalidating a Timer

To stop a timer, use the invalidate() method. This prevents further firing of the timer.

Example:

				
					example.stopTimer()

				
			
				
					The timer stops firing.
				
			
Scheduling a Timer on a Background Thread

By default, timers are scheduled on the main thread. Use Timer.scheduledTimer(withTimeInterval:repeats:block:) for background execution.

Example:

				
					let queue = DispatchQueue.global(qos: .background) 
  
let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in
    print("Timer fired!")
} 
  
queue.async { 
    RunLoop.current.add(timer, forMode: .default)
    RunLoop.current.run()
}

				
			

Output:

				
					Timer fired!
Timer fired!
Timer fired!
... (on a background thread)

				
			
Rescheduling a Timer

To change a timer’s interval, invalidate the existing timer and create a new one.

Example:

				
					class ReschedulingTimerExample { 
    var timer: Timer? 
    var timeInterval: TimeInterval = 2.0 
      
    func startTimer() { 
        timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true) 
        timer?.fire()
    } 
      
    func rescheduleTimer(newInterval: TimeInterval) { 
        timer?.invalidate() 
        timeInterval = newInterval
        startTimer()
    } 
      
    @objc func timerFired() { 
        print("Timer fired!")
    } 
} 

let rescheduleExample = ReschedulingTimerExample()
rescheduleExample.startTimer()
rescheduleExample.rescheduleTimer(newInterval: 5.0)

				
			

Output:

				
					Timer fired! (every 2 seconds initially)
Timer fired! (every 5 seconds after rescheduling)

				
			
Using GCD Timers

GCD timers offer an efficient way to schedule tasks.

Example:

				
					let queue = DispatchQueue.global(qos: .background) 
  
let timer = DispatchSource.makeTimerSource(queue: queue) 
  
timer.schedule(deadline: .now(), repeating: .seconds(2)) 
  
timer.setEventHandler { 
    print("Timer fired!")
} 
  
timer.resume()

				
			

Output:

				
					Timer fired!
Timer fired!
Timer fired!
... (repeats every 2 seconds)

				
			

Non Repeating Timers in Swift

Developers can create effective and efficient applications using Swift, a versatile and powerful programming language. Among its many tools, the Timer class is particularly useful for defining timed events that run at specified intervals. This post will discuss how to create and manage non-repeating timers using Swift’s Timer class.

Swift timers are commonly used for scheduling tasks with a delay or for creating repeating jobs. The Timer class, previously known as NSTimer, provides a flexible mechanism for scheduling tasks either once or periodically.

Importing Foundation

Since the Timer class is part of the Foundation framework, you need to import it to use timers in your application:

				
					import Foundation
				
			
Why Use Timers?

Timers are useful in scenarios where you need to execute specific actions after a set period or repeatedly within a specified time frame. Some common use cases include:

  • Automatically calling a method every 5 seconds.

  • Sending a local notification on app termination.

  • Syncing cart details with a backend server after a specified interval.

The Basics: scheduledTimer

The scheduledTimer method is used to create a timer. It requires you to specify parameters such as timeInterval, selector, and repeats.

  • timeInterval: Specifies the number of seconds before the timer fires.

  • selector: The function to be invoked when the timer fires.

  • repeats: A boolean that determines whether the timer fires repeatedly.

Example:

				
					/// Create an empty timer variable
var timer = Timer()

// In a function or viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)

// Define the action for the timer
@objc func timerAction() {
    print("Timer fired!")
}
				
			

Output:

				
					Timer fired!
Timer fired!
Timer fired!
... (repeats every 1 second)
				
			
Parameters Explanation

When creating a timer, five key parameters are required:

  • timeInterval: The time in seconds between timer firings.
  • target: The object on which the selector method is called.
  • selector: The method to execute when the timer fires.
  • userInfo: Optional data passed to the selector.
  • repeats: Specifies whether the timer should fire repeatedly.
				
					timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
				
			

You can stop a repeating timer manually by calling .invalidate():

Example:

				
					@objc func timerAction() {
    print("Timer fired once!")
    timer.invalidate()
}
				
			

Output:

				
					Timer fired once!
				
			
Repeating vs. Non-Repeating Timers
  • Non-Repeating Timer: Fires once and invalidates itself automatically.

  • Repeating Timer: Fires repeatedly at the specified interval and continues until manually invalidated.

Creating a Non-Repeating Timer

Example:

				
					let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireOnce), userInfo: nil, repeats: false)

@objc func fireOnce() {
    print("Firing the function after a specific interval")
}
				
			

Output:

				
					Timer fired once!
				
			
Parameters Explanation

When creating a timer, five key parameters are required:

  • timeInterval: The time in seconds between timer firings.
  • target: The object on which the selector method is called.
  • selector: The method to execute when the timer fires.
  • userInfo: Optional data passed to the selector.
  • repeats: Specifies whether the timer should fire repeatedly.

Example:

				
					timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
				
			
				
					@objc func timerAction() {
    print("Timer fired once!")
    timer.invalidate()
}
				
			

Output:

				
					Timer fired once!
				
			
Repeating vs. Non-Repeating Timers
  • Non-Repeating Timer: Fires once and invalidates itself automatically.
  • Repeating Timer: Fires repeatedly at the specified interval and continues until manually invalidated.

Creating a Non-Repeating Timer

Example:

				
					let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireOnce), userInfo: nil, repeats: false)

@objc func fireOnce() {
    print("Firing the function after a specific interval")
}
				
			

Output:

				
					Firing the function after a specific interval
				
			

Example Scenarios

Example 1: Display a Message After a Delay

				
					let timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { _ in
    print("Time's up!")
}
				
			

Output:

				
					Time's up!
				
			
Timer Tolerance

Adding a tolerance can improve power efficiency. Tolerance specifies how much later the timer can fire, which helps conserve resources, especially in background operations.

Example:

				
					timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
timer.tolerance = 0.3