Page updated Jan 16, 2024

Read application data

Query by Id

Now that you were able to make a mutation, take the Id that was printed out and use it in your query to retrieve data.

1func getTodo() async {
2 do {
3 let result = try await Amplify.API.query(
4 request: .get(Todo.self, byId: "9FCF5DD5-1D65-4A82-BE76-42CB438607A0")
5 )
6
7 switch result {
8 case .success(let todo):
9 guard let todo = todo else {
10 print("Could not find todo")
11 return
12 }
13 print("Successfully retrieved todo: \(todo)")
14 case .failure(let error):
15 print("Got failed result with \(error.errorDescription)")
16 }
17 } catch let error as APIError {
18 print("Failed to query todo: ", error)
19 } catch {
20 print("Unexpected error: \(error)")
21 }
22}
1func getTodo() -> AnyCancellable {
2 let sink = Amplify.Publisher.create {
3 try await Amplify.API.query(
4 request: .get(Todo.self, byId: "9FCF5DD5-1D65-4A82-BE76-42CB438607A0")
5 )
6 }
7 .sink {
8 if case let .failure(error) = $0 {
9 print("Got failed event with error \(error)")
10 }
11 }
12 receiveValue: { result in
13 switch result {
14 case .success(let todo):
15 guard let todo = todo else {
16 print("Could not find todo")
17 return
18 }
19 print("Successfully retrieved todo: \(todo)")
20 case .failure(let error):
21 print("Got failed result with \(error.errorDescription)")
22 }
23 }
24 return sink
25}

List Query

You can get the list of items using .list with optional parameters limit and where to specify the page size and condition. By default, the page size is 1000.

1func listTodos() async {
2 let todo = Todo.keys
3 let predicate = todo.name == "my first todo" && todo.description == "todo description"
4 let request = GraphQLRequest<Todo>.list(Todo.self, where: predicate, limit: 1000)
5 do {
6 let result = try await Amplify.API.query(request: request)
7 switch result {
8 case .success(let todos):
9 print("Successfully retrieved list of todos: \(todos)")
10 case .failure(let error):
11 print("Got failed result with \(error.errorDescription)")
12 }
13 } catch let error as APIError {
14 print("Failed to query list of todos: ", error)
15 } catch {
16 print("Unexpected error: \(error)")
17 }
18}
1func listTodos() -> AnyCancellable {
2 let todo = Todo.keys
3 let predicate = todo.name == "my first todo" && todo.description == "todo description"
4 let request = GraphQLRequest<Todo>.list(Todo.self, where: predicate, limit: 1000)
5 let sink = Amplify.Publisher.create {
6 try await Amplify.API.query(request: request)
7 }
8 .sink {
9 if case let .failure(error) = $0 {
10 print("Got failed event with error \(error)")
11 }
12 }
13 receiveValue: { result in
14 switch result {
15 case .success(let todos):
16 print("Successfully retrieved list of todos: \(todos)")
17 case .failure(let error):
18 print("Got failed result with \(error.errorDescription)")
19 }
20 }
21 return sink
22}

List subsequent pages of items

If you are using SwiftUI and have SwiftUI imported in the same code file, you will need to import the class Amplify.List to resolve name collision with SwiftUI.List:

1import SwiftUI
2import Amplify
3import class Amplify.List

For large data sets, you'll need to paginate through the results. After receiving the first page of results, you can check if there is a subsequent page and obtain the next page.

1var todos: [Todo] = []
2var currentPage: List<Todo>?
3
4func listFirstPage() async {
5 let todo = Todo.keys
6 let predicate = todo.name == "my first todo" && todo.description == "todo description"
7 let request = GraphQLRequest<Todo>.list(Todo.self, where: predicate, limit: 1000)
8 do {
9 let result = try await Amplify.API.query(request: request)
10 switch result {
11 case .success(let todos):
12 print("Successfully retrieved list of todos: \(todos)")
13 self.currentPage = todos
14 self.todos.append(contentsOf: todos)
15 case .failure(let error):
16 print("Got failed result with \(error.errorDescription)")
17 }
18 } catch let error as APIError {
19 print("Failed to query list of todos: ", error)
20 } catch {
21 print("Unexpected error: \(error)")
22 }
23}
24
25func listNextPage() async {
26 if let current = self.currentPage, current.hasNextPage() {
27 do {
28 let todos = try await current.getNextPage()
29 self.todos.append(contentsOf: todos)
30 self.currentPage = todos
31 } catch {
32 print("Failed to get next page \(error)")
33 }
34 }
35}

List all pages

If you want to get all pages, retrieve the subsequent page when you have successfully retrieved the first or next page.

  1. Update the above method listFirstPage() to listAllPages()
  2. Call listNextPageRecursively() in the success block of the query in listAllPages()
  3. Update the listNextPage() to listNextPageRecursively()
  4. Call listNextPageRecursively() in the success block of the query in listNextPageRecursively()

The completed changes should look like this:

1var todos: [Todo] = []
2var currentPage: List<Todo>?
3
4func listAllPages() async { // 1. Updated from `listFirstPage()`
5 let todo = Todo.keys
6 let predicate = todo.name == "my first todo" && todo.description == "todo description"
7 let request = GraphQLRequest<Todo>.list(Todo.self, where: predicate, limit: 1000)
8 do {
9 let result = try await Amplify.API.query(request: request)
10 switch result {
11 case .success(let todos):
12 print("Successfully retrieved list of todos: \(todos)")
13 self.currentPage = todos
14 self.todos.append(contentsOf: todos)
15 await self.listNextPageRecursively() // 2. Added
16 case .failure(let error):
17 print("Got failed result with \(error.errorDescription)")
18 }
19 } catch let error as APIError {
20 print("Failed to query list of todos: ", error)
21 } catch {
22 print("Unexpected error: \(error)")
23 }
24}
25
26func listNextPageRecursively() async { // 3. Updated from `listNextPage()`
27 if let current = currentPage, current.hasNextPage() {
28 do {
29 let todos = try await current.getNextPage()
30 self.todos.append(contentsOf: todos)
31 self.currentPage = todos
32 await self.listNextPageRecursively() // 4. Added
33 } catch {
34 print("Failed to get next page \(error)")
35 }
36 }
37}