Exploring Swift Concurrency with Actors and Structured Concurrency

Share this post on:

Introduction:

  • Concurrency Challenges in iOS Development:
    Briefly explain the complexities of managing concurrent tasks, such as race conditions and thread management.
  • Swift Concurrency Framework:
    Introduce Swift’s modern concurrency tools introduced in Swift 5.5, designed to make concurrent code safer, simpler, and more maintainable
  • Async/Await Overview:
    Introduce async and await for managing asynchronous tasks.

Example:

func fetchData() async -> String {

    return "Data fetched!"

}

Task {

    let data = await fetchData()

    print(data) // Output: Data fetched!

}
  • Structured Concurrency:

Explain the concept of structured concurrency, where tasks have a defined hierarchy, ensuring predictable and safe execution

  • The Problem Actors Solve:
    Discuss common problems in concurrent programming, such as race conditions, and how actors provide a thread-safe solution.
  • How Actors Work:
    Define actors as reference types that isolate their state and ensure only one task can access their mutable state at a time.
  • Actor Syntax:

Example of defining and using an actor:

actor Counter {
    private var value = 0

    func increment() {
        value += 1
    }

    func getValue() -> Int {
        return value
    }
}
let counter = Counter()
Task {
    await counter.increment()
    print(await counter.getValue())  // Output: 1
}
  • Task Groups:
    Explain TaskGroup and how it enables parallel execution of multiple tasks
    while maintaining control over their lifecycle.
func fetchMultipleData() async {
    await withTaskGroup(of: String.self) { group in
        group.addTask { "First Task" }
        group.addTask { "Second Task" }
        
        for await result in group {
            print(result)
        }
    }
}
  • Child Tasks:
    Discuss how child tasks inherit the parent task’s context and can
    be automatically canceled if the parent task fails.
  • Real-World Example:
    Demonstrate how to use actors and structured concurrency together in a practical scenario, such as fetching and aggregating data from multiple APIs.
actor DataManager {
    private var data = [String]()
 
    func addData(_ newData: String) {
        data.append(newData)
    }
 
    func getData() -> [String] {
        return data
    }
}
 
func fetchDataConcurrently() async {
    let dataManager = DataManager()
    
    await withTaskGroup(of: String.self) { group in
        for i in 1...3 {
            group.addTask {
                return "Data \(i)"
            }
        }
        
        for await result in group {
            await dataManager.addData(result)
        }
    }
 
    print(await dataManager.getData())  // Output: ["Data 1", "Data 2", "Data 3"]
}
  • Global Actors:
    Introduce global actors, such as MainActor, which enforce execution on specific threads.

Example:

  • Global Actors:
    Introduce global actors, such as MainActor, which enforce execution on specific threads.

Example:

@MainActor
class ViewModel {
    var title: String = ""
}
 
let viewModel = ViewModel()
Task {
    viewModel.title = "Updated on Main Thread"
}
  • Custom Executors:
    Briefly touch on custom executors for advanced performance tuning.
  • Best Practices:
    • Use actors for shared mutable state.
    • Avoid mixing older concurrency models (like DispatchQueue) with Swift concurrency.
    • Always handle cancellations properly.
  • Limitations:
    Discuss some challenges, such as debugging async tasks or dealing
    with non-Swift legacy codebases.

Recap the benefits of using actors and structured concurrency,
emphasizing how they make concurrent programming more approachable and safer.

Piyush Solanki

PHP Tech Lead & Backend Architect

10+ years experience
UK market specialist
Global brands & SMEs
Full-stack expertise

Core Technologies

PHP 95%
MySQL 90%
WordPress 92%
AWS 88%
  • Backend: PHP, MySQL, CodeIgniter, Laravel
  • CMS: WordPress customization & plugin development
  • APIs: RESTful design, microservices architecture
  • Frontend: React, TypeScript, modern admin panels
  • Cloud: AWS S3, Linux deployments
  • Integrations: Stripe, SMS/OTP gateways
  • Finance: Secure payment systems & compliance
  • Hospitality: Booking & reservation systems
  • Retail: E-commerce platforms & inventory
  • Consulting: Custom business solutions
  • Food Services: Delivery & ordering systems
  • Modernizing legacy systems for scalability
  • Building secure, high-performance products
  • Mobile-first API development
  • Agile collaboration with cross-functional teams
  • Focus on operational efficiency & innovation

Piyush is a seasoned PHP Tech Lead with 10+ years of experience architecting and delivering scalable web and mobile backend solutions for global brands and fast-growing SMEs.

He specializes in PHP, MySQL, CodeIgniter, WordPress, and custom API development, helping businesses modernize legacy systems and launch secure, high-performance digital products.

He collaborates closely with mobile teams building Android & iOS apps, developing RESTful APIs, cloud integrations, and secure payment systems. With extensive experience in the UK market and across multiple sectors, Piyush is passionate about helping SMEs scale technology teams and accelerate innovation through backend excellence.