Swift
async
void function
returning data
programming教程

How to returning data from a void async call in Swift function

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

You cannot synchronously return data from a function whose result is produced later by asynchronous work. In Swift, the correct answer is to change the API shape: either use a completion handler that receives the value later, or use async and return the value from an async function.

Why a Void Async Callback Cannot Return Immediately

Suppose you start a network request inside a function and try to return the result directly. That fails because the function ends before the asynchronous operation completes.

This is the wrong mental model:

swift
1func loadName() -> String {
2    var result = ""
3
4    fetchNameFromServer { value in
5        result = value
6    }
7
8    return result
9}

The callback runs later, so result is returned too early.

Use a Completion Handler in Older or Callback-Based Code

A completion handler is the classic Swift pattern:

swift
1func loadName(completion: @escaping (String) -> Void) {
2    fetchNameFromServer { value in
3        completion(value)
4    }
5}
6
7loadName { name in
8    print(name)
9}

Now the caller receives the data at the correct time instead of pretending it was available immediately.

Use async and await in Modern Swift

In modern Swift, the cleaner version is to make the function itself async and give it a real return type:

swift
1func loadName() async throws -> String {
2    let url = URL(string: "https://example.com/name")!
3    let (data, _) = try await URLSession.shared.data(from: url)
4    return String(decoding: data, as: UTF8.self)
5}

The caller then uses:

swift
1Task {
2    do {
3        let name = try await loadName()
4        print(name)
5    } catch {
6        print(error)
7    }
8}

This is still asynchronous, but the code reads more like a direct return value flow.

Choose the API Shape That Matches the Codebase

A practical rule is:

  • use completion handlers when integrating with older callback-based APIs
  • use async and await for modern Swift code where you control the function signature

The key design point is that asynchronous data must be delivered asynchronously. There is no safe trick that turns it back into a true immediate return value.

Avoid Shared Mutable State as a Workaround

Developers sometimes try to store the result in a property and read it later. That may be valid in some architectures, but it is not a replacement for a proper async API contract. Shared mutable state usually hides timing issues rather than solving them.

Bridge Old and New Styles Carefully

If you are migrating from completion handlers to async and await, keep the boundary explicit. One function can wrap the older callback-based API, but the caller should still see a clear asynchronous return path.

The Caller Must Participate

Returning data from async work is not only an implementation detail inside the function. The caller must also adopt an asynchronous pattern, whether that means using a callback, await, or task coordination.

Common Pitfalls

  • Trying to return a value before the asynchronous callback has executed.
  • Filling a local variable inside a callback and expecting the outer function to wait automatically.
  • Keeping a Void function signature when the real API should communicate a result asynchronously.
  • Mixing completion handlers and async code without a clear boundary.
  • Using shared state as a substitute for a proper asynchronous return path.

Summary

  • You cannot synchronously return data from asynchronous work that finishes later.
  • Use a completion handler in callback-based Swift code.
  • Use async and await when you can define an async function that returns the value.
  • Change the function contract instead of fighting the timing model.
  • Treat asynchronous results as asynchronous all the way to the caller.

Course illustration
Course illustration

All Rights Reserved.