Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Getting Started with iOS Development for Frontend Developers: Swift Basics

Tech 1

Prerequisites

You need:

  1. A Mac computer
  2. An Apple ID, which you can register for free on Apple's official website
  3. Xcode, available for download from the Mac App Store

Prractice Environment Setup

To practice Swift syntax without creating a full iOS project, you can use Xcode's Playground:

  1. Open Xcode
  2. Go to File > New > Playground
  3. Select the Blank template
  4. Save the file to your local machine to start practicing. Playground shows you the execution result of your code in real time on the right panel.

Swift Basic Syntax

Comments

Swift uses the same comment syntax as JavaScript:

  • Single line comments start with //
  • Multi-line comments are wrapped in /* */
// This is a single line comment

/*
This is a
multi-line comment
*/

Variables

Variables are declared with the var keyword. It is best practice to explicitly declare the type of the variable, though Swift can automatically infer the type if you omit it.

To explicitly declare a type, add a colon followed by the type name after the variable name.

// Explicit type declaration
var greeting: String = "Hello World"

// Type inference by Swift
var autoGreeting = "Hi there"

Variable values can be modified after declaration, but the type of a variable cannot be changed once declared, and you cannot re-declare the same variable name in the same scope. Both of the following examples will throw a compile error:

// Error: Cannot assign an Int to a String variable
var myText: String = "test"
myText = 123

// Error: Variable already declared
var myValue: Int = 10
var myValue: Int = 20

Constants

Constants are declared with the let keyword. You can assign a value when declaring the constant, or assign it later before using it. Once assigned, the value cannot be modified.

// Assign value at declaration
let defaultSiteName: String = "My Blog"

// Declare first, assign later
let apiBaseUrl: String
apiBaseUrl = "https://api.example.com"

The following code will throw an error because you cannot modify a constant after assignment:

// Error: Cannot mutate a constant
let appName: String = "DemoApp"
appName = "NewDemoApp"

Naming Rules for Variables & Constants

  • Allowed characters: letters, numbers, underscores, even Chinese characters and emojis, though non-ASCII characters are not recommended for production code.
  • Cannot start with a number, but can start with an underscore.
  • Special characters other than underscore are not allowed.
  • You can use Swift reserved words as variable names by wrapping them in backticks, though this is not recommended.
// Using a reserved word as a variable name (not recommended in production)
var `let` = "Hello"
print(`let`)

Print Output

To output values to the console, use the print() function:

var message: String = "Hello Swift"
print(message)

Common Data Types

Integer: Int

Used to store whole numbers, declaerd with the Int type:

var userAge: Int = 28

Floating Point: Float & Double

Used to store numbers with decimal points. Double has double the precision of Float, and is the default choice for most use cases.

Like JavaScript, Swift can have precision issues with floating point arithmetic:

var pi: Double = 3.1415926

var a: Double = 0.1
var b: Double = 0.2
print(a + b) // Output: 0.30000000000000004

String: String

Strings in Swift must be wrapped in double quotes (single quotes are not allowed). Common string operations:

Check if string is empty: isEmpty

var emptyStr = ""
print(emptyStr.isEmpty) // true

Get string length: count

var helloStr = "Hello"
print(helloStr.count) // 5

Concatenate strings with +

var str1 = "Hello"
var str2 = "World"
print(str1 + " " + str2) // "Hello World"

Append to string

var msg = "Hello"
msg.append(Character("!"))
print(msg) // Hello!

// Alternative:
msg = msg + "!!"
print(msg) // Hello!!!

Boolean: Bool

Boolean type only has two possible values: true and false, used for logical judgments:

var isLoggedIn: Bool = true
var isDisabled: Bool = false

Tuples

Tuples allow you to group multiple values of different types into a single compound value. You can name each element, or access them by index.

// Define a tuple with named elements: (username, age)
var user: (name: String, age: Int) = ("Alice", 28)

// Access via dot syntax with element names
print(user.name) // Alice
print(user.age) // 28

// Access via numeric index
print(user.0) // Alice
print(user.1) // 28

// Decompose a tuple into separate variables
let (userName, userAge) = user
print(userName) // Alice
print(userAge) // 28

// Ignore unused elements with _
let (_, onlyAge) = user
print(onlyAge) // 28

Array: Array

Arrays are ordered collections of same-type values, accessed by zero-based index.

Create an Array

// Empty integer array
var emptyNums: [Int] = []

// String array with initial values (type inferred)
var fruits = ["Apple", "Banana", "Orange"]

// Explicit type declaration
var explicitFruits: [String] = ["Apple", "Banana", "Orange"]
var genericFruits: Array<String> = ["Apple", "Banana", "Orange"]

// Create array with repeated values
var fiveApples = Array(repeating: "Apple", count: 5)

Common Array Operations

  • Access and modify elements by index:
var fruits = ["Apple", "Banana", "Orange"]
print(fruits[0]) // Apple
fruits[0] = "Apricot"
print(fruits) // ["Apricot", "Banana", "Orange"]
  • Get range of elements, modify range:
var chars = ["h", "e", "l", "l", "o"]
print(chars[1...3]) // ["e", "l", "l"]

// Replace range with new values (number of elements can differ)
chars[1...3] = ["a", "a"]
print(chars) // ["h", "a", "a", "o"]

// Delete range by assigning empty array
chars[1...2] = []
print(chars) // ["h", "o"]
  • Check if array is empty, get element count:
var emptyArr: [Int] = []
var fullArr = [1, 2, 3]
print(emptyArr.isEmpty) // true
print(fullArr.count) // 3
  • Add elements:
var nums = [1, 2, 3]
nums.append(4) // Add single element
nums.append(contentsOf: [5, 6, 7]) // Add multiple elements
print(nums) // [1, 2, 3, 4, 5, 6, 7]
  • Remove elements:
var nums = [1, 2, 3, 4, 5]
nums.removeFirst() // Remove first element → [2, 3, 4, 5]
nums.removeFirst(2) // Remove first 2 elements → [4, 5]
nums.removeLast() // Remove last element → [4]
nums.removeLast(1) // Remove last 1 element → []

// Always check if array is not empty before removing elements, or you will get a crash!
  • Check if array contains a value:
var fruits = ["Apple", "Banana", "Orange"]
print(fruits.contains("Apple")) // true
print(fruits.contains("Grape")) // false

Important Note: You can read elemants from arrays declared with let, but you cannot modify, add, or remove elements from a let array. Any mutation operation on a let array will throw a compile error.

Set: Set

Sets are unordered collections of unique values, ideal for checking membership quickly.

// Create a set of integers
var uniqueNums: Set<Int> = [1, 2, 3, 2, 1]
print(uniqueNums.count) // 3 (duplicates are automatically removed)

// Common operations
print(uniqueNums.contains(2)) // true
uniqueNums.insert(4)
uniqueNums.remove(2)
uniqueNums.removeAll()
print(uniqueNums.isEmpty) // true

Dictionary: Dictionary

Dictionaries store key-value pairs, where keys are unique and used to look up corresponding values.

// Create a dictionary with string keys and string values
var userProfile: [String: String] = ["username": "alice123", "email": "alice@example.com"]

// Common operations
print(userProfile["username"]) // "alice123"
userProfile["username"] = "alice_dev" // Update existing value
userProfile["bio"] = "iOS developer" // Add new key-value pair
print(userProfile.count) // 3
print(userProfile.isEmpty) // false
userProfile.removeValue(forKey: "bio") // Remove entry
userProfile.removeAll() // Clear entire dictionary

Check Variable Type

To check the type of a value at runtime, use type(of:):

var username = "alice"
var tags = ["Swift", "iOS"]
print(type(of: username)) // String
print(type(of: tags)) // Array<String>

Operators

Swift supports most common operators found in other C-like languages:

Assignment Operator

= to assign a value to a variable/constant.

Arithmetic Operators

Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Remainder (only works for integers)
+=, -=, *=, /=, %= Compound assignment

Note: Swift removed the ++ and -- increment/decrement operators starting from Swift 2.2.

Logical Operators

&& (AND), || (OR), ! (NOT). Unlike JavaScript, Swift logical operators only work with Boolean values.

Comparison Operators

==, !=, >, >=, <, <=, work the same as most other languages.

Ternary Conditional Operator

condition ? valueIfTrue : valueIfFalse

let isPassed = score >= 60 ? "Pass" : "Fail"

Range Operators

Swift has two special range operators:

  • a...b: Closed range, includes all values from a to b (inclusive of both)
  • a..<b: Half-open range, includes all values from a up to but not including b

You can check if a value is inside a range with the ~= operator:

let validRange = 0..<10
print(validRange ~= 5) // true
print(validRange ~= 10) // false

Control Flow

If-Else

If statements in Swift do not require parentheses around the condition, but require curly braces for the body:

let score = 85
if score >= 90 {
    print("Grade A")
} else if score >= 60 {
    print("Pass")
} else {
    print("Fail")
}

Switch

Switch statements in Swift do not require a break after each case (it is implicit), and a default case is required to handle all unmatched values. A single case can match multiple values:

let grade = "B"
switch grade {
case "A", "B", "C":
    print("Pass")
case "D", "F":
    print("Fail")
default:
    print("Invalid grade")
}

Loops

For-In Loop

Use for-in to iterate over ranges, arrays, dictionaries, and other collections:

// Iterate over a closed range
for i in 1...5 {
    print(i) // Output 1, 2, 3, 4, 5
}

// Iterate over an array
let fruits = ["Apple", "Banana", "Orange"]
for fruit in fruits {
    print(fruit) // Output each fruit name
}

// Iterate over dictionary key-value pairs
let profile = ["username": "alice", "age": "28"]
for (key, value) in profile {
    print("\(key): \(value)")
}

While Loop

While loops run as long as the condition is true:

var count = 0
let maxCount = 5
while count < maxCount {
    print(count)
    count += 1
}

Repeat-While

Repeat-While is equivalent to do-while in other languages: it runs the loop body at least once, then checks the condition:

var count = 0
repeat {
    print(count)
    count += 1
} while count < 5

Functions

Functions are reusable blocks of code that perform a specific task. Functions are declared with the func keyword.

Basic Function Definition

func checkPassed(score: Int) -> Bool {
    return score >= 60
}

// Call the function
print(checkPassed(score: 85)) // true

You can omit parameters or the return value:

// No parameters, has return value
func getAppName() -> String {
    return "Demo App"
}

// Has parameters, no return value
func printMessage(message: String) {
    print(message)
}

Special Function Parameter Features

  • Omit external parameter name: Use _ before the parameter name to omit the external name when calling:
func add(_ a: Int, _ b: Int) -> Int {
    return a + b
}
// Call without parameter names
add(2, 3)
  • Default parameter values: You can set a default value for parameters:
func greet(name: String, greeting: String = "Hello") {
    print("\(greeting) \(name)")
}
greet(name: "Alice") // Uses default greeting: Hello Alice
greet(name: "Alice", greeting: "Hi") // Hi Alice
  • Variadic parameters: Add ... after the type to accept any number of arguments of that type:
func sum(_ numbers: Int...) -> Int {
    return numbers.reduce(0, +)
}
sum(1, 2, 3, 4) // Returns 10
  • Inout parameters: By default, function parameters cannot be modified inside the function. Use inout to allow modifying the original external variable:
func increment(_ num: inout Int) {
    num += 1
}
var value = 5
increment(&value)
print(value) // 6

Closures

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures can capture and store references to any constants and variables from the context in which they are defined.

// Counter example that demonstrates value capture
func makeCounter() -> () -> Int {
    var count = 0
    let increment = {
        count += 1
        return count
    }
    return increment
}

let counter = makeCounter()
print(counter()) // 1
print(counter()) // 2
print(counter()) // 3

Inline closure syntax:

let add: (Int, Int) -> Int = { a, b in
    return a + b
}
add(2, 3) // 5

Custom Types

Enums

Enums define a group of related values with a common type:

enum AppTheme: String {
    case light = "Light Mode"
    case dark = "Dark Mode"
}
var currentTheme = AppTheme.dark
print(currentTheme.rawValue) // Dark Mode

Structs vs Classes

Swift has two main types for defining custom data structures: structs and classes. The key difference is that structs are value types and classes are reference types.

Struct Definition

struct User {
    var name: String
    var age: Int
    mutating func increaseAge() {
        age += 1
    }
}

Class Definition

class User {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func increaseAge() {
        age += 1
    }
}

Value vs Reference Type

When you assign a value type (struct) to a new variable, it creates a full copy of the original value, so modifying the copy does not affect the original:

struct UserStruct {
    var name: String
}
var user1 = UserStruct(name: "Alice")
var user2 = user1
user2.name = "Bob"
print(user1.name) // Alice (original unchanged)
print(user2.name) // Bob

When you assign a reference type (class) to a new variable, it copies a reference to the same underlying instance, so modifying the copy modifies the original:

class UserClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}
var userA = UserClass(name: "Alice")
var userB = userA
userB.name = "Bob"
print(userA.name) // Bob (original modified)
print(userB.name) // Bob

iOS Project Setup

Create a New Project

  1. Open Xcode, select Create a new Xcode project
  2. Select App as the project template, click Next
  3. Fill in your project details, select Storyboard as the Interface option, click Next
  4. Select a location to save your project and create it.

Run the Project

The default project structure for a new iOS project:

  • AppDelegate: Handles application lifecycle events
  • SceneDelegate: Manages multiple app windows/scenes
  • ViewController: The default root view controller for your app
  • Main.storyboard: The visual interface file
  • Assets.xcassets: Stores image and other static assets
  • LaunchScreen.storyboard: The launch screen shown when the app starts
  • Info.plist: Project configuration settings

To run the project: select an iOS simulator from the dropdown in the top-left corner, then click the play button. The simulator will launch and run your app.

Basic iOS UI Components

UILabel (Text Label)

UILabel is used to display static text on the screen. Add the following code to your ViewController.swift's viewDidLoad method to create a label:

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        // Create a label with position and size
        let titleLabel = UILabel(frame: CGRect(x: 20, y: 100, width: 200, height: 60))
        titleLabel.text = "Hello iOS"
        titleLabel.font = .systemFont(ofSize: 30)
        titleLabel.textColor = .systemBlue
        titleLabel.shadowColor = .systemGreen
        titleLabel.shadowOffset = CGSize(width: 2, height: 2)
        
        view.addSubview(titleLabel)
    }
}

To enable multi-line text, set the numberOfLines property: set it to 0 for unlimited lines (requires enough height to fit all text):

let longTextLabel = UILabel(frame: CGRect(x: 20, y: 200, width: 300, height: 200))
longTextLabel.text = "This is a long piece of text that will wrap across multiple lines when it reaches the edge of the label"
longTextLabel.numberOfLines = 0

To apply custom styling to parts of the text, use NSMutableAttributedString:

let attributedLabel = UILabel(frame: CGRect(x: 20, y: 400, width: 300, height: 100))
let text = "Hello, this is colored text"
let attributedText = NSMutableAttributedString(string: text)
attributedText.addAttributes([
    NSAttributedString.Key.foregroundColor: UIColor.red,
    NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 24)
], range: NSRange(location: 12, length: 12))
attributedLabel.attributedText = attributedText
attributedLabel.numberOfLines = 0
view.addSubview(attributedLabel)

UIButton (Button)

UIButton is the standard interactive control for handling taps.

// Create a system-style button
let actionButton = UIButton(type: .system)
actionButton.frame = CGRect(x: 20, y: 550, width: 100, height: 40)
actionButton.setTitle("Tap Me", for: .normal)
// Add tap event handler
actionButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
view.addSubview(actionButton)

Event handler method:

@objc func buttonTapped() {
    print("Button was tapped")
}

For custom-styled buttons, use the custom type, which allows you to set custom background colors, highlight states, and images:

let customButton = UIButton(type: .custom)
customButton.frame = CGRect(x: 140, y: 550, width: 150, height: 40)
customButton.backgroundColor = .systemBlue
customButton.setTitle("Custom Button", for: .normal)
customButton.setTitleColor(.white, for: .normal)
customButton.setTitleColor(.lightGray, for: .highlighted)
customButton.layer.cornerRadius = 8
view.addSubview(customButton)

To create an image button, first add your image file to Assets.xcassets, then set it on the button:

let imageButton = UIButton(type: .custom)
imageButton.frame = CGRect(x: 20, y: 620, width: 100, height: 100)
imageButton.setImage(UIImage(named: "your-image-name"), for: .normal)
view.addSubview(imageButton)

UIImageView (Image View)

UIImageView is used to display static images on screen:

// Add your image to Assets.xcassets first
let productImage = UIImage(named: "product")
let imageView = UIImageView(image: productImage)
imageView.frame = CGRect(x: 20, y: 100, width: 200, height: 150)
// Get original image size if needed:
if let size = productImage?.size {
    print("Original image size: \(size)")
}
view.addSubview(imageView)

UITextField (Text Input Field)

UITextField is used for single-line text input from the user.

let emailField = UITextField(frame: CGRect(x: 20, y: 750, width: 280, height: 40))
emailField.placeholder = "Enter your email"
emailField.borderStyle = .roundedRect
view.addSubview(emailField)

To get the input text when a button is tapped:

@objc func handleSubmit() {
    guard let text = emailField.text else { return }
    print("User input: \(text)")
}

You can use the delegate pattern to listen for editing events:

// Make ViewController conform to UITextFieldDelegate
class ViewController: UIViewController, UITextFieldDelegate {
    // ... in viewDidLoad:
    emailField.delegate = self
    
    // Delegate methods:
    func textFieldDidBeginEditing(_ textField: UITextField) {
        print("User started editing")
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.