Cómo migrar al SDK de Places para Swift en iOS

La migración del SDK de Places para iOS al SDK de Places Swift para iOS debería ser sencilla y se puede realizar de forma incremental. Dado que las structs del SDK de Places para iOS en Swift no son compatibles con sus contrapartes basadas en Objective-C, recomendamos migrar fragmentos discretos de funcionalidad según los usos de las APIs en GMSPlacesClient.

Agrega el SDK de Places de Swift para iOS a tu proyecto

Se requieren los siguientes pasos para usar el SDK de Places Swift para iOS:

  1. Habilita la API de Places (nueva).
  2. Agrega el SDK de Places para Swift a tus dependencias. Puedes instalar GooglePlaces, GooglePlacesSwift o ambos.

  3. Inicializa el cliente de Places con PlacesClient.

Ejemplo de migración paso a paso

Por ejemplo, supongamos que una app que usa el SDK de Places para iOS recibe sugerencias de autocompletar basadas en una entrada de texto y, luego, recupera los detalles de la primera sugerencia de lugar. Con el SDK de Places para iOS, el código existente podría verse de la siguiente manera:

// Initialize Places Client.
GMSPlacesClient.provideAPIKey(apiKey)
let client = GMSPlacesClient.shared()

// Fetch Autocomplete Request.
let center = CLLocation(latitude: 37.3913916, longitude: -122.0879074)
let northEast = CLLocationCoordinate2DMake(37.388162, -122.088137)
let southWest = CLLocationCoordinate2DMake(37.395804, -122.077023)

let filter = GMSAutocompleteFilter()
filter.types = [kGMSPlaceTypeRestaurant]
filter.origin = center
filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest)

let request = GMSAutocompleteRequest(query: "Sicilian piz")
request.filter = filter

client.fetchAutocompleteSuggestions(from: request) { (results, error) in
  guard let results, error == nil else {
    print("Autocomplete error: \(String(describing: error))")
    return
  }

  // Fetch Place Request.
  guard let placeID = results.first?.placeSuggestion?.placeID else { return }
  let myProperties = [GMSPlaceProperty.name, GMSPlaceProperty.website].map {$0.rawValue}

  let fetchPlaceRequest = GMSFetchPlaceRequest(placeID: placeID, placeProperties: myProperties, sessionToken: nil)

  client.fetchPlace(with: fetchPlaceRequest) { (place: GMSPlace?, error: Error?) in
    guard let place, error == nil else { return }
    print("Place found: \(String(describing: place.name)); \(String(describing: place.website))")
  }
}

Actualiza el inicializador del cliente de Places

Para modernizar el código y aprovechar las capacidades del nuevo SDK, deberás reemplazar GMSPlacesClient por PlacesClient. Además, los nombres de los parámetros se cambiaron en el nuevo método, por lo que deberás actualizar el parámetro a from en lugar de with. Por último, el SDK de Places para Swift usa el AutocompleteRequest actualizado.

Código actualizado

// Initialize Places Swift Client.
let _ = PlacesClient.provideAPIKey(apiKey)
let placesSwiftClient = PlacesClient.shared

Código original

// Initialize Places Client.
GMSPlacesClient.provideAPIKey(apiKey)
let client = GMSPlacesClient.shared()

Actualiza la solicitud de autocompletado

Podrías comenzar por actualizar el flujo de solicitudes de autocompletado. El código anterior usa una devolución de llamada para solicitar sugerencias de autocompletar, mientras que el código nuevo emplea un patrón switch/await. Las devoluciones de llamada pueden agregar complejidad a la estructura del código y al control de errores. El nuevo SDK de Places para Swift admite la simultaneidad, lo que simplifica las operaciones asíncronas.

// Initialize Places Swift Client.
let _ = PlacesClient.provideAPIKey(apiKey)
let placesSwiftClient = PlacesClient.shared

// Fetch Autocomplete Request.
let center = CLLocation(latitude: 37.3913916, longitude: -122.0879074)
let northEast = CLLocationCoordinate2DMake(37.388162, -122.088137)
let southWest = CLLocationCoordinate2DMake(37.395804, -122.077023)

let bias = RectangularCoordinateRegion(northEast: northEast, southWest: southWest)
let filter = AutocompleteFilter(types: [ .restaurant ], origin: center, coordinateRegionBias: bias)

let autocompleteRequest = AutocompleteRequest(query: "Sicilian piz", filter: filter)
let placeID: String
switch await placesSwiftClient.fetchAutocompleteSuggestions(with: autocompleteRequest) {
case .success(let results):
  switch results.first {
  case .place(let placeSuggestion):
    placeID = placeSuggestion.placeID
  case .none:
    fallthrough
  @unknown default:
    return
  }
case .failure(let placesError):
  print("Autocomplete error: \(placesError)")
  return
}

// Initialize Places Client.
GMSPlacesClient.provideAPIKey(apiKey)
let placesClient = GMSPlacesClient.shared()

// Fetch Place Request.
let myProperties = [GMSPlaceProperty.name, GMSPlaceProperty.website].map {$0.rawValue}

let fetchPlaceRequest = GMSFetchPlaceRequest(placeID: placeID, placeProperties: myProperties, sessionToken: nil)

placesClient.fetchPlace(with: fetchPlaceRequest) { (place: GMSPlace?, error: Error?) in
  guard let place, error == nil else { return }
  print("Place found: \(String(describing: place.name)); \(String(describing: place.website))")
}

Actualiza los nombres de métodos y clases

Por último, completa la migración refactorizando el código de fetchPlace y quitando tanto la inicialización de GMSPlacesClient como la declaración de GMSPlaceProperty. En el SDK de Places para Swift, se actualizaron los nombres de métodos y clases para quitar el prefijo "GMS", y deben actualizarse según corresponda; p.ej., GMSFetchPlaceRequest se convierte en FetchPlaceRequest.

Manejo de tipos

El nuevo método fetchPlace usa un control de tipos mejorado. Si bien el código anterior requería pasar los valores sin procesar de la propiedad, el código nuevo no requiere que los desarrolladores recuperen explícitamente los valores sin procesar aquí, lo que mejora la concisión y la legibilidad.

Simultaneidad

Además, el nuevo método admite la simultaneidad, lo que permite reemplazar la devolución de llamada en placesClient.fetchPlace con un patrón switch/await en placesSwiftClient.fetchPlace.

// Initialize Places Swift Client.
let _ = PlacesClient.provideAPIKey(apiKey)
let placesSwiftClient = PlacesClient.shared

// Fetch Autocomplete Request.
let center = CLLocation(latitude: 37.3913916, longitude: -122.0879074)
let northEast = CLLocationCoordinate2DMake(37.388162, -122.088137)
let southWest = CLLocationCoordinate2DMake(37.395804, -122.077023)

let bias = RectangularCoordinateRegion(northEast: northEast, southWest: southWest)
let filter = AutocompleteFilter(types: [ .restaurant ], origin: center, coordinateRegionBias: bias)

let autocompleteRequest = AutocompleteRequest(query: "Sicilian piz", filter: filter)
let placeID: String
switch await placesSwiftClient.fetchAutocompleteSuggestions(with: autocompleteRequest) {
case .success(let results):
  switch results.first {
  case .place(let placeSuggestion):
    placeID = placeSuggestion.placeID
  case .none:
    fallthrough
  @unknown default:
    return
  }
case .failure(let placesError):
  print("Autocomplete error: \(placesError)")
  return
}

// Fetch Place Request.
let fetchPlaceRequest = FetchPlaceRequest(placeID: placeID, placeProperties: [.displayName, .websiteURL])
switch await placesSwiftClient.fetchPlace(with: fetchPlaceRequest) {
case .success(let place):
  print("Place found: \(place.displayName): \(String(describing: place.description))")

case .failure(let placesError):
  print("Place not found: \(placeID); \(placesError)")
}

Mantenerte al tanto

Visita la página de notas de la versión del SDK de Places Swift para iOS para obtener información sobre las nuevas funciones y los cambios.