Swift Programming Language

Swift Programming Language

not Maruti Suzuki Swift... xd

ยท

12 min read

Introduction

Swift was created by Apple in 2014. It's the official language that works with the whole Apple Operating System. It is statically typed and is a modern programming language that was designed to fit in an ecosystem that was previously designed for a different programming language called Objective-C.

Most of the software running on the iPhone and Mac today is based on Objective-C code, even for official Apple apps. But Swift usage is gaining traction year after year. While Objective-C will be used for years to maintain and improve existing apps, new applications are likely going to be created with Swift.

Before Apple introduced Swift, Objective-C was heavily developed to introduce new capabilities and features. But in recent years this effort has decreased a lot in favor of Swift development. This does not mean Objective-C is dead or not worth learning: Objective-C is still an essential tool for any Apple developer.

Variables and Constants

  1. As Swift has a powerful inference system, you do not always need to specify the type of variable, the compiler automatically detects the type by seeing the value assigned, but in case some error occurs or the compiler is not able to read the code, we specify the data type.

     var x = "john"
     var y = 2
    
     When compiler is not able to read-
     var z: Int = 2  //datatype specified
    
  2. Value can be changed i.e. mutable.

     var x = 1
     x = 2
    
  3. To declare constant use let keyword. The value of constant once defined can't be changed.

     let x = 1
    
  4. Naming convention and optional variable.

    The naming convention follows the camel case convention, where the first letter of each subsequent word is capitalized.

    Optional variables can hold either a value of the specified type or nil, indicating the absence of a value.

     var numberOfStudents: Int
    
     var optionalName: String?
    

Data Types

  1. Int: Used to represent whole numbers. It can be signed (+ve, -ve, or 0) or unsigned (+ve or 0 only).

     let age: Int = 1 
    
     var count: UInt = 10
    
  2. Float: Represents single-precision floating-point numbers. They are typically used when precision up to 6 decimal places is sufficient.

     let pi: Float = 3.14159
    
  3. Double: Returns double-precision floating-point numbers. They have a higher precision than Float and are the default type for floating-point numbers in Swift.

     let pi: Double = 3.14159265359
    
  4. Bool: Returns true or false on passing a value.

     let isSunny: Bool = true
    
  5. String: Returns a sequence of characters. Strings are used to store text and are enclosed in double quotation marks.

     let greeting: String = "Hello, World!"
    
  6. Character: Returns a single character. Characters are enclosed in single quotation marks.

     let firstLetter: Character = 'A'
    
  7. Array: Returns an ordered collection of elements of the same type. Arrays can be mutable (var) or immutable (let).

     var numbers: [Int] = [1, 2, 3, 4, 5].
    
  8. Dictionary: Returns a collection of key-value pairs. Each key in the dictionary must be unique, and the values can be of any type.

     var topg: [String: Int] = ["Dhruv": 28, "Rutam": 21]
    
  9. Set: Returns an unordered collection of unique elements. Sets are useful when you want to ensure that there are no duplicate values.

     var uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5]
    
  10. Tuple: Returns a group of values combined together. Tuples can contain values of different types and are defined using parentheses.

    let number: (Int, Int) = (1, 2)
    
  11. Optional: Returns a value that may or may not exist. It is used when a variable or constant is null.

    var optionalString: String? = "Optional"
    

Loops

  1. For-In Loop: This loop is used to iterate over a sequence, such as an array, a range of numbers, or a collection of items. The loop executes a set of statements for each element in the sequence.

     for item in sequence {
         // Code to be executed for each item
     }
    
     let numbers = [1, 2, 3, 4, 5]
     for number in numbers {
         print(number)
     }
    
  2. While Loop: This loop repeats a block of code until a certain condition becomes false. The condition is evaluated before each iteration.

     while condition {
         // Code to be executed while the condition is true
     }
    
     var x = 0
     while x < 5 {
         print(x)
         x += 1
     }
    
  3. Repeat-While Loop: This loop is similar to the while loop, but the condition is evaluated after each iteration. This guarantees that the loop will execute at least once.

     repeat {
         // Code to be executed
     } while condition
    
     var counter = 0
     repeat {
         print(counter)
         counter += 1
     } while counter < 5
    

    Repeat while loop is similar to do while loop in other languages.


Conditional Statements

  1. If Statement: The if statement is used to execute a block of code if a certain condition is true. It can be followed by else if and else clauses to specify additional conditions and code blocks to execute.

     if condition {
         // Code to be executed if the condition is true
     } else if anotherCondition {
         // Code to be executed if anotherCondition is true
     } else {
         // Code to be executed if none of the conditions are         true         
     }
    
     let num = 10
    
     if num > 0 {
         print("Number is positive")
     } else if num < 0 {
         print("Number is negative")
     } else {
         print("Number is zero")
     }
    
  2. Switch Statement: The switch statement is used to perform different actions based on the value of an expression. It provides an alternative to using multiple if statements. Each case in the switch statement represents a different value or condition to match against.

     switch value {
         case pattern1:
             // Code to be executed if value matches pattern1
         case pattern2:
             // Code to be executed if value matches pattern2
         default:
             // Code to be executed if none of the patterns match
     }
    
     let fruit = "apple"
    
     switch fruit {
         case "apple":
             print("It's an apple")
         case "orange":
             print("It's an orange")
         default:
             print("Unknown fruit")
     }
    
  3. Ternary Conditional Operator: Swift also provides a ternary conditional operator (? :) that allows you to write a simple conditional expression in a more concise form.

     condition ? expression1 : expression2
    
     let num = 10
     let result = num > 0 ? "Positive" : "Negative or zero"
     print(result)
    

Functions

To define a function, you specify its name, parameters (if any), return type, and the code block that contains the statements to be executed.

func functionName(parameter1: Type, parameter2: Type, ...) -> ReturnType {
    // Code to be executed
    return value
}
  • functionName is the name of the function.

  • parameter1, parameter2, etc., are the input parameters with their corresponding types.

  • ReturnType is the type of value that the function returns.

  • The code block contains the statements to be executed when the function is called.

  • return statement is used to return a value from the function (if applicable).

When do we call the function?

To execute our code we call the function, you use its name followed by parentheses. If the function has parameters, you pass the values for those parameters inside the parentheses.

functionName(argument1, argument2, ...)

An example to demonstrate the sum of 2 numbers.

func calculateSum(a: Int, b: Int) -> Int {
    let sum = a + b
    return sum
}

let result = calculateSum(a: 5, b: 3)
print(result)

In this example, the calculateSum function takes two parameters a and b of type Int and returns their sum as an Int value. The function is called with arguments 5 and 3, and the result is assigned to the result constant.


Enumerations

Enumerations are a way to group a set of different options under a common name.

enum Animal {
    case dog
    case cat
    case mouse
    case cow
}

This Animal enum is now a type whose value can only be one of the cases listed.

Assigning value to a variable:

var animal: Animal 
animal = .dog

Once you have a variable, you can get this value using its rawValue property:

enum Animal: Int {     
    case dog = 1     
    case cat = 2     
    case mouse = 3     
    case horse = 4 
}  

var animal: Animal 
animal = .dog  
animal.rawValue //1

Enumerations are a value type. This means they are copied when passed to a function, or when returned from a function. And when we assign a variable pointing to an enumeration to another variable.


Structures

Structures are everywhere in Swift. Even the built-in types are structures. They are light versions of classes.

One important thing classes allow is inheritance, so if you need that, you have classes.

A struct is defined using this syntax:

struct Dog {

}

Inside a structure you can define stored properties:

struct Dog {     
    var age = 8     
    var name = "Roger" 
}

This structure definition defines a type. To create a new instance with this type, We use this syntax:

let roger = Dog() 
roger.age
roger.name

The same dot syntax is used to update a property value:

arin.age = 9

You can also create a struct instance by passing the values of the properties:

let syd = Dog(age: 7, name: "Syd") 
syd.age 
syd.name

To do so, properties must be defined variables with var, not as constants (with let). It's also important to respect the order those properties are defined.

struct Dog {     
    var age = 8
    var name = "Roger"
    func bark() { 
        print("\(name): wof!") 
    }     
    static func hello() {   
        print("Hello I am the Dog struct")     
    } 
}

This is invoked as Dog.hello().

Structures are a value type. This means they are copied when passed to a function, or when returned from a function. And when we assign a variable pointing to a structure to another variable.

This also means that if we want to update the properties of a structure we must define it using var and not let.

All types in Swift are defined as structures: Int, Double, String, arrays and dictionaries, and more are structures.


Class

In Swift, classes are used to define blueprints for creating objects. They are a fundamental part of object-oriented programming and provide a way to encapsulate data and functionality together. Here's an example of how to create and use a class in Swift:

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func sayHello() {
        print("Hello, my name is \(name)!")
    }
}

// Creating an instance of the Person class
let person1 = Person(name: "John", age: 25)

// Accessing properties and calling methods
print(person1.name)   // Output: John
print(person1.age)    // Output: 25
person1.sayHello()    // Output: Hello, my name is John!

In the example above, we define a class called Person with two properties: name and age. The init method is a special initializer that is called when creating a new instance of the class. We provide values for the name and age properties when creating the instance person1.

The sayHello method is defined within the class to print a greeting message using the name property.

To create an instance of the Person class, we use the initializer Person(name: "John", age: 25) and assign it to the variable person1. We can then access the properties (name and age) and call the method (sayHello) on the instance using dot notation.

Classes can have additional methods, properties, and can also inherit from other classes using inheritance. They allow for creating more complex data structures and implementing object-oriented programming principles in Swift.


Protocols

A protocol is a way to have different objects, of different types, have a common set of functionalities.

You define a protocol like this:

protocol Mammal {

}

Structs and classes can adopt a protocol in this way:

struct Dog: Mammal {

}

class Cat: Mammal {

}

A protocol can define properties and methods, without providing values and implementations, and a struct/class must implement them:

protocol Mammal {
    var age: Int { get set }
    func walk()
}

The property can be defined as get or get set. If it's get, the property must be implemented as read-only, with a getter.

Any type that adopts the protocol must conform to the protocol by implementing those methods or providing those properties:

struct Dog: Mammal {     
    var age: Int = 0     
    func walk() {         
        print("The dog is walking")     
    } 
}  
class Cat: Mammal {  
    var age: Int = 0
    func walk() {
        print("The cat is walking") 
    } 
}

Structs and classes can adopt multiple protocols:

struct Dog: Mammal, Animal {

}

class Cat: Mammal, Animal {

}

Notice that for classes, this is the same syntax used to define a superclass. If there is a superclass, list it as the first item in the list, after the colon.


Initializers

In Swift, initializers are special methods that are used to initialize (or create) instances of a class, structure, or enumeration. They ensure that all properties have initial values and allow you to perform any additional setup that might be required before an instance is ready to use.

Here are a few important points to know about initializers in Swift:

  1. Default Initializers: If you don't provide any custom initializers, Swift automatically generates a default initializer for you. This initializer sets all properties to their default values (e.g., 0 for numbers, empty string for strings, nil for optionals, etc.). Default initializers are available for classes, structures, and enumerations.

  2. Custom Initializers: You can define your own custom initializers to set specific initial values for properties or perform additional setup. Custom initializers are defined within the class or structure, and they have the same name as the type. You can have multiple custom initializers with different parameter lists (known as overloading).

  3. Initializer Delegation: In a class, an initializer can call another initializer to perform some or all of the initialization. This process is known as initializer delegation. Initializer delegation is done using the self.init keyword, which allows you to call other initializers within the same class.

  4. Required Initializers: In some cases, you may want to enforce that all subclasses provide a certain initializer. In such cases, you can mark the initializer as required. Subclasses must implement this initializer, and it cannot be overridden.

Here's an example demonstrating the use of initializers in Swift:

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    convenience init() {
        self.init(name: "John Doe", age: 30)
    }
}

let person1 = Person(name: "Alice", age: 25)
let person2 = Person()

print(person1.name, person1.age)  // Output: Alice 25
print(person2.name, person2.age)  // Output: John Doe 30

In the example above, the Person class has a custom initializer init(name:age:) that takes name and age as parameters and assigns them to the respective properties. It also has a convenience initializer init() that sets default values for name and age and delegates to the custom initializer.

The instances person1 and person2 are created using the custom initializer and convenience initializer, respectively. The values passed to the initializer are used to initialize the properties.

Initializers are a powerful feature in Swift that allows you to set up objects with initial values and perform necessary setup tasks before using them. They provide flexibility and control over the initialization process of your types.


For getting started with iOS dev this blog contains sufficient knowledge but if you wanna explore more you can check out these links.

https://www.youtube.com/live/Ulp1Kimblg0?feature=share

https://www.freecodecamp.org/news/the-swift-handbook/

Happy learning and thanks for your time :)

ย