DEV Community

GoyesDev
GoyesDev

Posted on

[SC] Ejecutando Tasks en SwiftUI

¿Qué relación tiene el ejemplo de búsqueda con .task?

Se retoma el ejemplo de search(_ query: String) donde se filtran unas entradas pasado un rebote de 500ms. En este ejemplo, se necesita guardar una referencia de un Task para luego cancelarlo, en la clase ArticleSearcher (que es Observable). Más tarde, desde la vista se invoca el método search(_:) desde un onChange(of:).

Estado inicial de search(_ query: String)

@MainActor
@Observable
final class ArticleSearcher {

  private static let articleTitlesDatabase = [
    "Article one",
    "Article two",
    "Article three",
  ]

  var searchResults: [String] = ArticleSearcher.articleTitlesDatabase

  private var currentSearchTask: Task<Void, Never>?

  func search(_ query: String) {
    currentSearchTask?.cancel()
    currentSearchTask = Task {
      do {
        try await Task.sleep(for: .milliseconds(500))
        print("Starting to search!")
        searchResults = Self.articleTitlesDatabase.filter {
          $0.lowercased().contains(query.lowercased())
        }
      } catch {
        print("Search was cancelled!")
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

¿Cómo funciona el modificador .task?

SwiftUI permite enganchar un Task al ciclo de vida de un View por medio de .task(). La tarea se programa antes de que aparezca la vista y se cancela cuando desaparezca.
Ya no es necesario envolver la tarea a disparar con Task { }, sino que basta con hacer async la firma del método.

Estado final de search(_ query: String)

func search(_ query: String) async {
  do {
    try await Task.sleep(for: .milliseconds(500))
    print("Starting to search!")
    searchResults = Self.articleTitlesDatabase
      .filter { $0.lowercased().contains(query.lowercased()) }
  } catch {
      print("Search was cancelled!")
  }
}
Enter fullscreen mode Exit fullscreen mode

¿Para qué sirve el parámetro id: en .task?

.task() dispara una tarea antes de que aparezca una vista. Sin embargo, cuando el valor del parámetro id: cambia, se cancela la tarea anterior de forma automática y se vuelve a disparar una nueva.

¿Para que sirve el parámetro .priority en .task?

Como Swift Concurrency tiene un pool de hilos cooperativo, podemos cambiar la prioridad para obtener un comportamiento diferente con respecto a otras tareas. Sin embargo, tener en cuenta que SwiftUI usa por defecto userInitiated, así que, en principio, tiene sentido cambiar la prioridad a media (utility) o baja (background).


Bibliografía

Top comments (0)