Sitemap

Swift Concurrency Recipes: Known Parallel Requests

2 min readOct 24, 2026

--

Known/Fixed Count Parallel Requests

Get Mok5ha G’s stories in your inbox

Join Medium for free to get updates from this writer.

You need to launch a fixed set of independent network calls simultaneously (e.g., fetching User Profile, Cart Items, and App Config at app launch) and execute a single completion block when all of them finish.

Press enter or click to view image in full size

Approach 1: Grand Central Dispatch (DispatchGroup)

import Foundation

final class InitialDataLoaderGCD {
func loadDashboardData(completion: @escaping (Result<Void, Error>) -> Void) {
let group = DispatchGroup()

// 1. Task 1: Profile
group.enter()
fetchProfile { _ in
group.leave()
}

// 2. Task 2: Cart
group.enter()
fetchCart { _ in
group.leave()
}

// 3. Task 3: Config
group.enter()
fetchConfig { _ in
group.leave()
}

// Notify on main thread when all enter() calls have matching leave() calls
group.notify(queue: .main) {
completion(.success(()))
}
}

private func fetchProfile(completion: @escaping (Data?) -> Void) {
URLSession.shared.dataTask(with: URL(string: "https://api.example.com/profile")!) { data, _, _ in
completion(data)
}.resume()
}

private func fetchCart(completion: @escaping (Data?) -> Void) {
URLSession.shared.dataTask(with: URL(string: "https://api.example.com/cart")!) { data, _, _ in
completion(data)
}.resume()
}

private func fetchConfig(completion: @escaping (Data?) -> Void) {
URLSession.shared.dataTask(with: URL(string: "https://api.example.com/config")!) { data, _, _ in
completion(data)
}.resume()
}
}

Approach 2: Swift Concurrency (async let)

import Foundation

final class InitialDataLoaderAsync {
func loadDashboardData() async throws -> (Data, Data, Data) {
let profileURL = URL(string: "https://api.example.com/profile")!
let cartURL = URL(string: "https://api.example.com/cart")!
let configURL = URL(string: "https://api.example.com/config")!

// Spawn 3 child tasks concurrently
async let profileData = fetch(url: profileURL)
async let cartData = fetch(url: cartURL)
async let configData = fetch(url: configURL)

// Wait for all 3 to complete
return try await (profileData, cartData, configData)
}

private func fetch(url: URL) async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return data
}
}

SwiftUI Usage Example

import SwiftUI

struct DashboardView: View {
private let loader = InitialDataLoaderAsync()

var body: some View {
Text("Dashboard")
.task {
do {
let (profile, cart, config) = try await loader.loadDashboardData()
print("Loaded: \(profile.count)b profile, \(cart.count)b cart, \(config.count)b config")
} catch {
print("Failed to load dashboard: \(error)")
}
}
}
}

--

--