Page updated Nov 3, 2023

Using the Combine framework with Amplify

Amplify supports iOS 13+ and macOS 10.15+, and ships with APIs that leverage Swift concurrency (async/await) to return values. For example, the following returns an array of type Geo.Place with search results for coffee shops.

1let places = try await Amplify.Geo.search(for "coffee")

Some APIs do not return a simple result, such as those that return subscriptions or provide progress updates. In cases where multiple values are expected over time, Amplify typically provides an AmplifyAsyncSequence or AmplifyAsyncThrowingSequence. These types conform to the AsyncSequence protocol and can be iterated over asynchronously. For example, the following subscribes to the creation of new Todos.

1let subscription = Amplify.API.subscribe(
2 request: .subscription(of: Todo.self, type: .onCreate)
3)

Amplify.Publisher

In order to support Combine, Amplify includes Amplify.Publisher, which can be used to get Combine Publishers for Amplify APIs, such as those listed above. Specifically, it provides static methods to create Combine Publishers from Tasks and AsyncSequences.

The following examples show how to create Combine Publishers for the above API calls.

1let sink = Amplify.Publisher.create {
2 try await Amplify.Geo.search(for "coffee")
3}
4.sink { completion in
5 // handle completion
6} receiveValue: { value in
7 // handle value
8}
1let subscription = Amplify.API.subscribe(
2 request: .subscription(of: Todo.self, type: .onCreate)
3)
4
5let sink = Amplify.Publisher.create(subscription)
6 .sink { completion in
7 // handle completion
8 } receiveValue: { value in
9 // handle value
10 }

Cancellation

When using Amplify.Publisher, cancelling a subscription to a publisher also cancels the underlying task. Note, however, that in the case of progress sequences, this would only cancel progress updates, and not the associated task such as a file upload or download. Those associated tasks would need to be cancelled separately, either by calling .cancel() on the task itself or by cancelling the parent task.

Hub.publisher(for:)

The Amplify Hub category exposes only one Combine-related API: Hub.publisher(for:), which returns a publisher for all events on a given channel. You can then apply the standard Combine filter operator to inspect only those events you care about.