El servicio de autocompletado del SDK de Places para iOS devuelve los predicciones en respuesta a las consultas de búsqueda de los usuarios. A medida que el usuario escribe, el servicio de autocompletado muestra sugerencias de lugares como negocios, direcciones, los Plus Codes y lugares de interés.
Puedes agregar el autocompletado a tu aplicación de las siguientes formas:
- Agrega un control de IU con la función de autocompletar para guardar. durante el desarrollo del producto, y garantizar una experiencia del usuario coherente.
- Obtén predicciones de lugares de manera programática para crear un usuario personalizado. una experiencia fluida a los desarrolladores.
Agrega un control de IU de autocompletado
El control de IU de autocompletado es un diálogo de búsqueda con autocompletado integrado
funcionalidad. A medida que un usuario ingresa términos de búsqueda, el control presenta un
una lista de predicciones de lugares entre los que puedes elegir. Cuando el usuario hace una selección,
un GMSPlace
una instancia de VM, que la app puede usar para obtener detalles sobre la
el lugar seleccionado.
Puedes agregar el control de IU de autocompletado a tu aplicación de las siguientes maneras:
- Agrega un control de pantalla completa
- Cómo agregar un controlador de resultados
- Cómo usar una fuente de datos de tabla
Cómo agregar un control de pantalla completa
Usa el control de pantalla completa cuando quieras un contexto modal, en el que
IU de Autocomplete reemplaza temporalmente la IU de tu app hasta que
usuario haya hecho su selección. Esta funcionalidad es proporcionada por el
GMSAutocompleteViewController
clase. Cuando el usuario selecciona un sitio, tu aplicación recibe un callback.
Para agregar el control de pantalla completa a tu aplicación:
- Crea un elemento de la IU en tu app principal para iniciar el control de la IU con la función de autocompletar.
(por ejemplo, un controlador táctil en un
UIButton
) - Implementa
GMSAutocompleteViewControllerDelegate
. en el controlador de vista superior. - Crea una instancia de
GMSAutocompleteViewController
y asigna el controlador de vista superior como propiedad delegada. - Crea un
GMSPlaceField
. para definir los tipos de datos de lugar que se devolverán. - Agrega un elemento
GMSAutocompleteFilter
. para limitar la consulta a un tipo de lugar en particular. - Presenta
GMSAutocompleteViewController
con[self presentViewController...]
. - Controla la selección del usuario en
didAutocompleteWithPlace
. delegado. - Descarta el controlador en
didAutocompleteWithPlace
. Métodos delegadosdidFailAutocompleteWithError
ywasCancelled
.
En el siguiente ejemplo, se muestra una posible forma de iniciar
GMSAutocompleteViewController
en respuesta al usuario
que presiona un botón.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { override func viewDidLoad() { makeButton() } // Present the Autocomplete view controller when the button is pressed. @objc func autocompleteClicked(_ sender: UIButton) { let autocompleteController = GMSAutocompleteViewController() autocompleteController.delegate = self // Specify the place data types to return. let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) | UInt(GMSPlaceField.placeID.rawValue))! autocompleteController.placeFields = fields // Specify a filter. let filter = GMSAutocompleteFilter() filter.types = [.address] autocompleteController.autocompleteFilter = filter // Display the autocomplete view controller. present(autocompleteController, animated: true, completion: nil) } // Add a button to the view. func makeButton() { let btnLaunchAc = UIButton(frame: CGRect(x: 5, y: 150, width: 300, height: 35)) btnLaunchAc.backgroundColor = .blue btnLaunchAc.setTitle("Launch autocomplete", for: .normal) btnLaunchAc.addTarget(self, action: #selector(autocompleteClicked), for: .touchUpInside) self.view.addSubview(btnLaunchAc) } } extension ViewController: GMSAutocompleteViewControllerDelegate { // Handle the user's selection. func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) { print("Place name: \(place.name)") print("Place ID: \(place.placeID)") print("Place attributions: \(place.attributions)") dismiss(animated: true, completion: nil) } func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) { // TODO: handle the error. print("Error: ", error.localizedDescription) } // User canceled the operation. func wasCancelled(_ viewController: GMSAutocompleteViewController) { dismiss(animated: true, completion: nil) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
#import "ViewController.h" @import GooglePlaces; @interface ViewController () <GMSAutocompleteViewControllerDelegate> @end @implementation ViewController { GMSAutocompleteFilter *_filter; } - (void)viewDidLoad { [super viewDidLoad]; [self makeButton]; } // Present the autocomplete view controller when the button is pressed. - (void)autocompleteClicked { GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init]; acController.delegate = self; // Specify the place data types to return. GMSPlaceField fields = (GMSPlaceFieldName | GMSPlaceFieldPlaceID); acController.placeFields = fields; // Specify a filter. _filter = [[GMSAutocompleteFilter alloc] init]; _filter.types = @[ kGMSPlaceTypeBank ]; acController.autocompleteFilter = _filter; // Display the autocomplete view controller. [self presentViewController:acController animated:YES completion:nil]; } // Add a button to the view. - (void)makeButton{ UIButton *btnLaunchAc = [UIButton buttonWithType:UIButtonTypeCustom]; [btnLaunchAc addTarget:self action:@selector(autocompleteClicked) forControlEvents:UIControlEventTouchUpInside]; [btnLaunchAc setTitle:@"Launch autocomplete" forState:UIControlStateNormal]; btnLaunchAc.frame = CGRectMake(5.0, 150.0, 300.0, 35.0); btnLaunchAc.backgroundColor = [UIColor blueColor]; [self.view addSubview:btnLaunchAc]; } // Handle the user's selection. - (void)viewController:(GMSAutocompleteViewController *)viewController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place ID %@", place.placeID); NSLog(@"Place attributions %@", place.attributions.string); } - (void)viewController:(GMSAutocompleteViewController *)viewController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // User canceled the operation. - (void)wasCancelled:(GMSAutocompleteViewController *)viewController { [self dismissViewControllerAnimated:YES completion:nil]; } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; } @end
Cómo agregar un controlador de resultados
Usa un controlador de resultados cuando desees un mayor control sobre la IU de entrada de texto. El controlador de resultados activa o desactiva de forma dinámica la visibilidad de la lista de resultados según el enfoque de la IU de entrada.
Para agregar un controlador de resultados a tu aplicación:
- Crea una
GMSAutocompleteResultsViewController
. - Implementa
GMSAutocompleteResultsViewControllerDelegate
. en el controlador de vista superior y asignarlo como la propiedad de delegado. - Crea un objeto
UISearchController
y pasa elGMSAutocompleteResultsViewController
como argumento del controlador de resultados. - Establece el elemento
GMSAutocompleteResultsViewController
. como la propiedadsearchResultsUpdater
deUISearchController
. - Agrega el
searchBar
para elUISearchController
a la IU de tu app. - Controla la selección del usuario en
didAutocompleteWithPlace
. delegado.
Existen varias formas de colocar la barra de búsqueda de un objeto UISearchController
en
la IU de tu app:
- Cómo agregar una barra de búsqueda a la barra de navegación
- Cómo agregar una barra de búsqueda en la parte superior de una vista
- Cómo agregar una barra de búsqueda con resultados emergentes
Agregar una barra de búsqueda a la barra de navegación
El siguiente ejemplo de código demuestra cómo agregar un controlador de resultados, agregar el
searchBar
a la barra de navegación y cómo controlar la selección del usuario:
Swift
class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Put the search bar in the navigation bar. searchController?.searchBar.sizeToFit() navigationItem.titleView = searchController?.searchBar // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Prevent the navigation bar from being hidden when searching. searchController?.hidesNavigationBarDuringPresentation = false } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Put the search bar in the navigation bar. [_searchController.searchBar sizeToFit]; self.navigationItem.titleView = _searchController.searchBar; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Prevent the navigation bar from being hidden when searching. _searchController.hidesNavigationBarDuringPresentation = NO; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { _searchController.active = NO; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
Cómo agregar una barra de búsqueda en la parte superior de una vista
En el siguiente ejemplo de código, se muestra cómo agregar searchBar
a la parte superior de una vista.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController let subView = UIView(frame: CGRect(x: 0, y: 65.0, width: 350.0, height: 45.0)) subView.addSubview((searchController?.searchBar)!) view.addSubview(subView) searchController?.searchBar.sizeToFit() searchController?.hidesNavigationBarDuringPresentation = false // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 65.0, 250, 50)]; [subView addSubview:_searchController.searchBar]; [_searchController.searchBar sizeToFit]; [self.view addSubview:subView]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
De forma predeterminada, UISearchController
oculta la barra de navegación durante la presentación (esta opción se puede inhabilitar). En los casos en que
la barra de navegación está visible y es opaca, UISearchController
no se establece
ubicarlas de forma correcta.
Usa el siguiente código como solución:
Swift
navigationController?.navigationBar.translucent = false searchController?.hidesNavigationBarDuringPresentation = false // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = true self.edgesForExtendedLayout = .top
Objective-C
self.navigationController.navigationBar.translucent = NO; _searchController.hidesNavigationBarDuringPresentation = NO; // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = YES; self.edgesForExtendedLayout = UIRectEdgeTop;
Cómo agregar una barra de búsqueda con resultados emergentes
El siguiente ejemplo de código muestra cómo colocar una barra de búsqueda en el lado derecho de la barra de navegación y cómo mostrar los resultados en una ventana emergente.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. searchController?.searchBar.frame = (CGRect(x: 0, y: 0, width: 250.0, height: 44.0)) navigationItem.rightBarButtonItem = UIBarButtonItem(customView: (searchController?.searchBar)!) // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Keep the navigation bar visible. searchController?.hidesNavigationBarDuringPresentation = false searchController?.modalPresentationStyle = .popover } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. _searchController.searchBar.frame = CGRectMake(0, 0, 250.0f, 44.0f); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_searchController.searchBar]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Keep the navigation bar visible. _searchController.hidesNavigationBarDuringPresentation = NO; _searchController.modalPresentationStyle = UIModalPresentationPopover; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
Usa una fuente de datos de tabla
Si tu app tiene una IU de texto de búsqueda personalizada, puedes usar la
GMSAutocompleteTableDataSource
para controlar la vista de tabla que muestra los resultados en el controlador de vista.
Para usar GMSAutocompleteTableDataSource
como fuente de datos y delegado de UITableView
en un controlador de vista:
- Implementa
GMSAutocompleteTableDataSourceDelegate
. yUISearchBarDelegate
protocolos en el controlador de vista. - Crea un
GMSAutocompleteTableDataSource
. y asigna el controlador de vista como propiedad delegada. - Establece el elemento
GMSAutocompleteTableDataSource
. como la fuente de datos y las propiedades delegadas deUITableView
en el controlador de vista. - En el controlador de la entrada de texto de búsqueda, llama a
sourceTextHasChanged
en laGMSAutocompleteTableDataSource
- Controla la selección del usuario en el método de delegado
didAutocompleteWithPlace
. - Descarta el controlador en
didAutocompleteWithPlace
,didFailAutocompleteWithError
,wasCancelled
métodos delegados.
El siguiente ejemplo de código demuestra el uso de
GMSAutocompleteTableDataSource
para controlar la vista de tabla de un UIViewController
cuando el UISearchBar
se agrega por separado.
Swift
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import GooglePlaces import UIKit class PlaceAutocompleteViewController: UIViewController { private var tableView: UITableView! private var tableDataSource: GMSAutocompleteTableDataSource! override func viewDidLoad() { super.viewDidLoad() let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: self.view.frame.size.width, height: 44.0)) searchBar.delegate = self view.addSubview(searchBar) tableDataSource = GMSAutocompleteTableDataSource() tableDataSource.delegate = self tableView = UITableView(frame: CGRect(x: 0, y: 64, width: self.view.frame.size.width, height: self.view.frame.size.height - 44)) tableView.delegate = tableDataSource tableView.dataSource = tableDataSource view.addSubview(tableView) } } extension PlaceAutocompleteViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // Update the GMSAutocompleteTableDataSource with the search text. tableDataSource.sourceTextHasChanged(searchText) } } extension PlaceAutocompleteViewController: GMSAutocompleteTableDataSourceDelegate { func didUpdateAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator off. UIApplication.shared.isNetworkActivityIndicatorVisible = false // Reload table data. tableView.reloadData() } func didRequestAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator on. UIApplication.shared.isNetworkActivityIndicatorVisible = true // Reload table data. tableView.reloadData() } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didAutocompleteWith place: GMSPlace) { // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didFailAutocompleteWithError error: Error) { // Handle the error. print("Error: \(error.localizedDescription)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didSelect prediction: GMSAutocompletePrediction) -> Bool { return true } }
Objective-C
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #import "PlaceAutocompleteViewController.h" @import GooglePlaces; @import UIKit; @interface PlaceAutocompleteViewController () <GMSAutocompleteTableDataSourceDelegate, UISearchBarDelegate> @end @implementation PlaceAutocompleteViewController { UITableView *tableView; GMSAutocompleteTableDataSource *tableDataSource; } - (void)viewDidLoad { [super viewDidLoad]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)]; searchBar.delegate = self; [self.view addSubview:searchBar]; tableDataSource = [[GMSAutocompleteTableDataSource alloc] init]; tableDataSource.delegate = self; tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 44)]; tableView.delegate = tableDataSource; tableView.dataSource = tableDataSource; [self.view addSubview:tableView]; } #pragma mark - GMSAutocompleteTableDataSourceDelegate - (void)didUpdateAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator off. UIApplication.sharedApplication.networkActivityIndicatorVisible = NO; // Reload table data. [tableView reloadData]; } - (void)didRequestAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator on. UIApplication.sharedApplication.networkActivityIndicatorVisible = YES; // Reload table data. [tableView reloadData]; } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didAutocompleteWithPlace:(GMSPlace *)place { // Do something with the selected place. NSLog(@"Place name: %@", place.name); NSLog(@"Place address: %@", place.formattedAddress); NSLog(@"Place attributions: %@", place.attributions); } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didFailAutocompleteWithError:(NSError *)error { // Handle the error NSLog(@"Error %@", error.description); } - (BOOL)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didSelectPrediction:(GMSAutocompletePrediction *)prediction { return YES; } #pragma mark - UISearchBarDelegate - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { // Update the GMSAutocompleteTableDataSource with the search text. [tableDataSource sourceTextHasChanged:searchText]; } @end
Cómo personalizar el texto y los colores de fondo
Puedes establecer los colores de todo el texto y los fondos en la IU de Autocomplete para que el widget coincida más con la apariencia visual de tu app de cerca. Existen dos formas de configurar los colores del control de IU:
- Usando el protocolo UIAppearance de iOS nativo para definir el estilo global de los controles de la IU siempre que sea posible Esta configuración se aplica a muchos de los controles de la IU, pero no a todos. o de terceros.
- Usando los métodos del SDK en las clases de widgets para establecer propiedades que no son compatibles con el protocolo UIAppearance.
Por lo general, tu app usará alguna combinación del protocolo UIAppearance y los métodos del SDK. En el siguiente diagrama, se muestran los elementos cuyo estilo se puede personalizar:
En la siguiente tabla, se enumeran todos los elementos de la IU y se indica cómo cada uno debe tener estilo (protocolo UIAppearance o método SDK).
Elemento de la IU | Método | Consejos sobre estilo |
---|---|---|
Tono de la barra de navegación (fondo) | Protocolo UIAppearance | Llama a setBarTintColor en el proxy UINavigationBar . |
Color del tono de la barra de navegación (signo de intercalación de texto de la barra de búsqueda y botón Cancelar) | Protocolo UIAppearance | Llama a setTintColor en el proxy UINavigationBar . |
Color del texto de la barra de búsqueda | Protocolo UIAppearance | Establece NSForegroundColorAttributeName en searchBarTextAttributes . |
Color del tono de la barra de búsqueda | N/A | La barra de búsqueda es traslúcida y se mostrará como una versión sombreada. de la barra de navegación. |
Color del texto del marcador de posición de la barra de búsqueda (texto de búsqueda predeterminado) | Protocolo UIAppearance | Establece NSForegroundColorAttributeName en placeholderAttributes . |
Texto principal (también se aplica al texto de errores y mensajes) | Método del SDK | Llamar a primaryTextColor |
Destacado del texto principal | Método del SDK | Llamar a primaryTextHighlightColor |
Texto secundario | Método del SDK | Llamar a secondaryTextColor |
Error y texto del mensaje | Método del SDK | Llamar a primaryTextColor |
Fondo de celda de tabla | Método del SDK | Llamar a tableCellBackgroundColor |
Color del separador de celda de la tabla | Método del SDK | Llamar a tableCellSeparatorColor |
"Vuelve a intentarlo" botón | Método del SDK | Llamar a tintColor |
Indicador de actividad (ícono giratorio de progreso) | Protocolo UIAppearance | Llama a setColor en el proxy UIActivityIndicatorView . |
"Con la tecnología de Google" Logotipo de una nube triste | N/A | La versión blanca o gris se selecciona automáticamente según el contraste del fondo. |
Íconos de lupa y texto claro en el campo de texto de la barra de búsqueda | N/A | Para aplicar un estilo, reemplaza las imágenes predeterminadas por imágenes del color deseado. |
Cómo usar el protocolo UIAppearance
Puedes usar el protocolo UIAppearance
para obtener el proxy de apariencia para un elemento determinado de la IU, que luego puedes usar para
establecer el color para el elemento de la IU. Cuando se realiza una modificación, todas las instancias de
un elemento determinado de la IU se ven afectados. A continuación, se muestra un ejemplo
cambia el color del texto de las clases UITextField
a verde cuando están
Se incluye en un UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
Para obtener más información sobre la definición de valores de color, consulta el Referencia de la clase UIColor.
Los siguientes fragmentos de código muestran todos los comandos de proxy que debes usar para
diseñar todo en el control de la IU con la función de autocompletar en pantalla completa. Agregar este código
al método didFinishLaunchingWithOptions
en Appdelegate.m:
// Define some colors. UIColor *darkGray = [UIColor darkGrayColor]; UIColor *lightGray = [UIColor lightGrayColor]; // Navigation bar background. [[UINavigationBar appearance] setBarTintColor:darkGray]; [[UINavigationBar appearance] setTintColor:lightGray]; // Color of typed text in the search bar. NSDictionary *searchBarTextAttributes = @{ NSForegroundColorAttributeName: lightGray, NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]] }; [UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] .defaultTextAttributes = searchBarTextAttributes; // Color of the placeholder text in the search bar prior to text entry. NSDictionary *placeholderAttributes = @{ NSForegroundColorAttributeName: lightGray, NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]] }; // Color of the default search text. // NOTE: In a production scenario, "Search" would be a localized string. NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Search" attributes:placeholderAttributes]; [UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] .attributedPlaceholder = attributedPlaceholder; // Color of the in-progress spinner. [[UIActivityIndicatorView appearance] setColor:lightGray]; // To style the two image icons in the search bar (the magnifying glass // icon and the 'clear text' icon), replace them with different images. [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x_high"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateHighlighted]; [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal]; [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_search"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; // Color of selected table cells. UIView *selectedBackgroundView = [[UIView alloc] init]; selectedBackgroundView.backgroundColor = [UIColor lightGrayColor]; [UITableViewCell appearanceWhenContainedIn:[GMSAutocompleteViewController class], nil] .selectedBackgroundView = selectedBackgroundView;
Cómo configurar las propiedades de estilo del control de IU
Un subconjunto de elementos de control de la IU tiene propiedades que no se ven afectadas por el
UIAppearance, por lo que se debe configurar directamente. El siguiente ejemplo de código
Muestra cómo definir colores en primer y segundo plano y cómo aplicarlos a una IU
instancia de control llamada acController
. Agrega este código a onLaunchClicked
en ViewController.m:
UIColor *darkGray = [UIColor darkGrayColor]; UIColor *lightGray = [UIColor lightGrayColor]; acController.secondaryTextColor = [UIColor colorWithWhite:1.0f alpha:0.5f]; acController.primaryTextColor = lightGray; acController.primaryTextHighlightColor = [UIColor grayColor]; acController.tableCellBackgroundColor = darkGray; acController.tableCellSeparatorColor = lightGray; acController.tintColor = lightGray;
Obtén predicciones de lugares de manera programática
Puedes crear una IU de búsqueda personalizada como alternativa a la IU que proporciona la Autocomplete. Para ello, tu app debe obtener predicciones del lugar programáticamente. Tu app puede obtener una lista de nombres de lugares previstos. direcciones de correo electrónico de una de las siguientes maneras:
Llamando a GMSPlacesClient findAutocompletePredictionsFromQuery:
Para obtener una lista de lugares o direcciones previstos, primero
crear una instancia de GMSPlacesClient
y, luego, llama al
GMSPlacesClient findAutocompletePredictionsFromQuery:
con los siguientes parámetros:
- Una cadena
autocompleteQuery
que contiene el texto que escribió el usuario - Un objeto
GMSAutocompleteSessionToken
que se usa para identificar cada sesión individual. Tu app debe pasar el mismo token para cada llamada de solicitud a Autocomplete y luego pasar ese token junto con un ID de lugar, en la llamada posterior afetchPlacefromPlaceID:
para recuperar los detalles de Place del lugar que seleccionó el usuario. - Un
GMSAutocompleteFilter
para hacer lo siguiente:- Personalizar o restringir los resultados para una región específica
- Restringe los resultados a un tipo de lugar específico.
- Un objeto
GMSPlaceLocationBias
/Restriction que personaliza los resultados para un área específica especificada por los límites de latitud y longitud.
- Un método de devolución de llamada para manejar las predicciones devueltas.
En los siguientes ejemplos de código, se muestra una llamada a findAutocompletePredictionsFromQuery:
.
Swift
/** * Create a new session token. Be sure to use the same token for calling * findAutocompletePredictions, as well as the subsequent place details request. * This ensures that the user's query and selection are billed as a single session. */ let token = GMSAutocompleteSessionToken.init() // Create a type filter. let filter = GMSAutocompleteFilter() filter.types = [.bank] filter.locationBias = GMSPlaceRectangularLocationOption( northEastBounds, southWestBounds); placesClient?.findAutocompletePredictions(fromQuery: "cheesebu", filter: filter, sessionToken: token, callback: { (results, error) in if let error = error { print("Autocomplete error: \(error)") return } if let results = results { for result in results { print("Result \(result.attributedFullText) with placeID \(result.placeID)") } } })
Objective-C
/** * Create a new session token. Be sure to use the same token for calling * findAutocompletePredictionsFromQuery:, as well as the subsequent place details request. * This ensures that the user's query and selection are billed as a single session. */ GMSAutocompleteSessionToken *token = [[GMSAutocompleteSessionToken alloc] init]; // Create a type filter. GMSAutocompleteFilter *_filter = [[GMSAutocompleteFilter alloc] init]; _filter.types = @[ kGMSPlaceTypeBank ]; [_placesClient findAutocompletePredictionsFromQuery:@"cheesebu" filter:_filter sessionToken:token callback:^(NSArray<GMSAutocompletePrediction *> * _Nullable results, NSError * _Nullable error) { if (error != nil) { NSLog(@"An error occurred %@", [error localizedDescription]); return; } if (results != nil) { for (GMSAutocompletePrediction *result in results) { NSLog(@"Result %@ with PlaceID %@", result.attributedFullText, result.placeID); } } }];
La API invoca el método de devolución de llamada especificado, pasando un array de
GMSAutocompletePrediction
objetos.
Cada GMSAutocompletePrediction
contiene la siguiente información:
attributedFullText
: es el texto completo de la predicción, en forma de un elementoNSAttributedString
. Por ejemplo, “Ópera de Sídney, Sídney, Nuevo Sur Gales, Australia". Cada rango de texto que coincide con la entrada del usuario tiene un ,kGMSAutocompleteMatchAttribute
. Puedes usar este atributo para lo siguiente: destacar el texto coincidente en la consulta del usuario, por ejemplo, como se muestra a continuaciónplaceID
: el ID de lugar del sitio de predicción. Un ID de lugar es un identificador textual que identifica un lugar de forma exclusiva. Para obtener más información los IDs de lugar, consulta la descripción general de los IDs de lugar.distanceMeters
: la distancia en línea recta a partir del valor especificadoorigin
hasta el destino. Si no se establece la propiedadorigin
, no hay distancia “value”.
En el siguiente ejemplo de código, se muestra cómo resaltar en negrita las partes
del resultado que coincide con el texto en la consulta del usuario, mediante enumerateAttribute
:
Swift
let regularFont = UIFont.systemFont(ofSize: UIFont.labelFontSize) let boldFont = UIFont.boldSystemFont(ofSize: UIFont.labelFontSize) let bolded = prediction.attributedFullText.mutableCopy() as! NSMutableAttributedString bolded.enumerateAttribute(kGMSAutocompleteMatchAttribute, in: NSMakeRange(0, bolded.length), options: []) { (value, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in let font = (value == nil) ? regularFont : boldFont bolded.addAttribute(NSFontAttributeName, value: font, range: range) } label.attributedText = bolded
Objective-C
UIFont *regularFont = [UIFont systemFontOfSize:[UIFont labelFontSize]]; UIFont *boldFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; NSMutableAttributedString *bolded = [prediction.attributedFullText mutableCopy]; [bolded enumerateAttribute:kGMSAutocompleteMatchAttribute inRange:NSMakeRange(0, bolded.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { UIFont *font = (value == nil) ? regularFont : boldFont; [bolded addAttribute:NSFontAttributeName value:font range:range]; }]; label.attributedText = bolded;
Usa el recuperador
Si quieres crear tu propio control de autocompletar desde cero, puedes usar
GMSAutocompleteFetcher
:
que une el método autocompleteQuery
en GMSPlacesClient
.
La herramienta de buscador limita las solicitudes y solo muestra resultados de los datos más recientes
texto de búsqueda ingresado. No ofrece elementos de IU.
Para implementar GMSAutocompleteFetcher
, haz lo siguiente:
sigue estos pasos:
- Implementa
GMSAutocompleteFetcherDelegate
. protocolo. - Crea un objeto
GMSAutocompleteFetcher
. - Llama a
sourceTextHasChanged
en el recuperador a medida que el usuario escribe. - Controla las predicciones y los errores con
didAutcompleteWithPredictions
. ydidFailAutocompleteWithError
métodos de protocolo.
En el siguiente ejemplo de código, se demuestra cómo usar la herramienta de buscador para tomar entradas del usuario
y mostrar las coincidencias de lugares en una vista de texto. Funcionalidad para seleccionar un lugar
se omitió. FetcherSampleViewController
deriva de UIViewController
.
en FetcherSampleViewController.h.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var textField: UITextField? var resultText: UITextView? var fetcher: GMSAutocompleteFetcher? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white edgesForExtendedLayout = [] // Set bounds to inner-west Sydney Australia. let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366, longitude: 151.134002) let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725, longitude: 151.200349) // Set up the autocomplete filter. let filter = GMSAutocompleteFilter() filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner) // Create a new session token. let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init() // Create the fetcher. fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter) fetcher?.delegate = self fetcher?.provide(token) textField = UITextField(frame: CGRect(x: 5.0, y: 10.0, width: view.bounds.size.width - 5.0, height: 64.0)) textField?.autoresizingMask = .flexibleWidth textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) let placeholder = NSAttributedString(string: "Type a query...") textField?.attributedPlaceholder = placeholder resultText = UITextView(frame: CGRect(x: 0, y: 65.0, width: view.bounds.size.width, height: view.bounds.size.height - 65.0)) resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0) resultText?.text = "No Results" resultText?.isEditable = false self.view.addSubview(textField!) self.view.addSubview(resultText!) } @objc func textFieldDidChange(textField: UITextField) { fetcher?.sourceTextHasChanged(textField.text!) } } extension ViewController: GMSAutocompleteFetcherDelegate { func didAutocomplete(with predictions: [GMSAutocompletePrediction]) { let resultsStr = NSMutableString() for prediction in predictions { resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText) resultsStr.appendFormat("Place ID: %@\n", prediction.placeID) } resultText?.text = resultsStr as String } func didFailAutocompleteWithError(_ error: Error) { resultText?.text = error.localizedDescription } }
Objective-C
#import "FetcherSampleViewController.h" #import <GooglePlaces/GooglePlaces.h> @interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate> @end @implementation FetcherSampleViewController { UITextField *_textField; UITextView *_resultText; GMSAutocompleteFetcher* _fetcher; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.edgesForExtendedLayout = UIRectEdgeNone; // Set bounds to inner-west Sydney Australia. CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(-33.843366, 151.134002); CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(-33.875725, 151.200349); GMSAutocompleteFilter *autocompleteFilter = [[GMSAutocompleteFilter alloc] init]; autocompleteFilter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner); // Create the fetcher. _fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:nil filter:filter]; _fetcher.delegate = self; // Set up the UITextField and UITextView. _textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 0, self.view.bounds.size.width - 5.0f, 44.0f)]; _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; _resultText =[[UITextView alloc] initWithFrame:CGRectMake(0, 45.0f, self.view.bounds.size.width, self.view.bounds.size.height - 45.0f)]; _resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f]; _resultText.text = @"No Results"; _resultText.editable = NO; [self.view addSubview:_textField]; [self.view addSubview:_resultText]; } - (void)textFieldDidChange:(UITextField *)textField { NSLog(@"%@", textField.text); [_fetcher sourceTextHasChanged:textField.text]; } #pragma mark - GMSAutocompleteFetcherDelegate - (void)didAutocompleteWithPredictions:(NSArray *)predictions { NSMutableString *resultsStr = [NSMutableString string]; for (GMSAutocompletePrediction *prediction in predictions) { [resultsStr appendFormat:@"%@\n", [prediction.attributedPrimaryText string]]; } _resultText.text = resultsStr; } - (void)didFailAutocompleteWithError:(NSError *)error { _resultText.text = [NSString stringWithFormat:@"%@", error.localizedDescription]; } @end
Tokens de sesión
Los tokens de sesión agrupan las fases de búsqueda y selección del autocompletado de un usuario busca en una sesión discreta para facturar. La sesión comienza cuando el usuario comienza a escribir una consulta y termina cuando selecciona un lugar. Cada puede tener varias búsquedas, seguidas de una selección de lugar. Una vez por sesión concluyó, el token ya no es válido; tu app debe generar un un token nuevo para cada sesión. Recomendamos usar tokens de sesión sesiones programáticas de autocompletado (cuando usas el controlador de pantalla completa, o el controlador de resultados, la API se encarga de esto automáticamente).
El SDK de Places para iOS usa un GMSAutocompleteSessionToken
para identificar cada sesión. La aplicación deberá pasar un nuevo token de sesión al
cada nueva sesión, pasa ese mismo token, junto con un ID de lugar,
en la llamada posterior a fetchPlacefromPlaceID:
para recuperar los detalles de Place del lugar que seleccionó el usuario.
Obtén más información sobre los tokens de sesión.
Usa el siguiente código para generar un nuevo token de sesión:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
Límites de uso
- Uso de
GMSPlacesClient findAutocompletePredictionsFromQuery
está sujeto a los límites de consulta por niveles. Consulta la documentación sobre límites de uso.
Cómo mostrar atribuciones en tu aplicación
- Si tu app usa el servicio de autocompletado de manera programática, tu IU debe mostrar un mensaje “Powered by Google” atribución, o aparecer dentro de una Mapa con la marca de Google.
- Si tu app usa el control de IU de autocompletado, no se requiere ninguna acción adicional (la atribución requerida se muestra de forma predeterminada).
- Si recuperas y muestras información adicional del lugar después de obtener un lugar por ID. también debes mostrar atribuciones de terceros.
Para obtener más detalles, consulta la documentación sobre atribuciones.
Cómo controlar el indicador de actividad de red
Para controlar el indicador de actividad de red en la barra de estado de las aplicaciones, se deben implementar los métodos delegados opcionales adecuados para el autocompletado de red que estés usando y activa y desactiva el indicador de red por tu cuenta.
- Para
GMSAutocompleteViewController
, debes implementar los métodos delegadosdidRequestAutocompletePredictions:
ydidUpdateAutocompletePredictions:
. - Para
GMSAutocompleteResultsViewController
, debes implementar los métodos delegadosdidRequestAutocompletePredictionsForResultsController:
ydidUpdateAutocompletePredictionsForResultsController:
. - Para
GMSAutocompleteTableDataSource
, debes implementar los métodos delegadosdidRequestAutocompletePredictionsForTableDataSource:
ydidUpdateAutocompletePredictionsForTableDataSource:
.
Si implementas estos métodos y configuras [UIApplication sharedApplication].networkActivityIndicatorVisible
en YES
y NO
respectivamente, la barra de estado coincidirá correctamente con el
Autocomplete.
Limita los resultados de autocompletar
Puedes configurar el control de IU de autocompletado para restringir los resultados a un determinado región geográfica y filtrar los resultados por uno o más tipos de lugares, o para en un país o países específicos. Para restringir los resultados, puedes hacer lo siguiente:
- Para preferir (sesgo) los resultados dentro de la región definida, configura
locationBias
en elGMSAutocompleteFilter
(algunos resultados que no pertenecen a la región definida pueden aún se devolverán). Si también estableceslocationRestriction
, se ignorarálocationBias
. Para mostrar solo (restringir) los resultados dentro de la región definida, establece
locationRestriction
enGMSAutocompleteFilter
(solo resultados de una región definida).- Nota: Esta restricción solo se aplica a rutas completas, sintéticas los resultados ubicados fuera de los límites rectangulares se pueden devolver en función de una ruta que se superpone con la restricción de ubicación.
Para que se muestren solo resultados que coincidan con un tipo de lugar específico, configura
types
enGMSAutocompleteFilter
(por ejemplo, especificar TypeFilter.ADDRESS) hará que el widget devuelva solo resultados con una dirección exacta).Para que se muestren solo resultados de hasta cinco países especificados, configura
countries
delGMSAutocompleteFilter
Personalización de resultados según una región específica
Para preferir (sesgo) los resultados dentro de la región definida, configura locationBias
en
GMSAutocompleteFilter
, como se muestra a continuación:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);
Restringe los resultados a una región específica
Para mostrar solo (restringir) los resultados dentro de la región definida, establece
locationRestriction
en GMSAutocompleteFilter
, como se muestra a continuación:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationRestriction = GMSPlaceRectangularLocationOption(northEast, southWest);
Filtrar los resultados por país
Para filtrar los resultados en un máximo de cinco países especificados, activa countries
GMSAutocompleteFilter
, como se muestra a continuación:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
Filtrar los resultados por tipo de lugar o colección de tipos
Restringe los resultados para que sean de cierto tipo o colección de tipos estableciendo
Propiedad types
de
GMSAutoCompleteFilter
Use esta propiedad para especificar los filtros que se enumeran en las tablas 1, 2 y 3 de la
Tipos de lugar. Si no se especifica nada, se devolverán todos los tipos.
Para especificar un tipo o filtro de colección de tipos, haz lo siguiente:
Usa la propiedad
types
para especificar hasta cinco valores de type de la Tabla 1. y la Tabla 2, que se muestra en Tipos de lugar. Los valores de tipo son definidas por las constantes enGMSPlaceType
.Usa la propiedad
types
para especificar un tipo de colección de la Tabla 3. en Tipos de lugar. Los tipos de valores de la colección se definen según las constantes enGMSPlaceType
.Solo se permite un tipo de la Tabla 3 en la solicitud. Si especificas un de la Tabla 3, no puedes especificar un valor de la Tabla 1 ni de la Tabla 2. Si si lo haces, se produce un error.
Por ejemplo, para obtener resultados que coincidan con un tipo de lugar determinado, establece
types
del GMSAutocompleteFilter
En el siguiente ejemplo, se muestra cómo configurar
filtra para devolver solo los resultados con una dirección precisa:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
Optimización de Place Autocomplete
En esta sección, se describen algunas prácticas recomendadas que te ayudarán a aprovechar al máximo el servicio Place Autocomplete.
A continuación, se indican algunos lineamientos generales:
- La forma más rápida de desarrollar una interfaz de usuario funcional es usar el widget de Autocomplete de la API de Maps JavaScript, el widget de Autocomplete del SDK de Places para Android o el control de la IU de Autocomplete del SDK de Places para iOS.
- Comprende los campos de datos esenciales de Place Autocomplete desde el principio.
- Los campos de restricción y personalización de la ubicación son opcionales, pero pueden afectar significativamente el rendimiento del autocompletado.
- Usa el procedimiento de manejo de errores para asegurarte de que tu app administre el problema de forma adecuada si la API muestra un error.
- Asegúrate de que tu app gestione correctamente los problemas cuando no haya selección y ofrezca a los usuarios una manera de continuar.
Prácticas recomendadas para la optimización de los costos
Optimización básica de los costos
Para optimizar el costo de usar el servicio Place Autocomplete, usa máscaras de campo en los widgets de Place Details y Place Autocomplete, que te permiten mostrar solo los campos de datos de lugar que necesitas.
Optimización avanzada de los costos
Considera utilizar la implementación programática de Place Autocomplete para acceder a los precios por pedido y solicitar resultados de la API de Geocoding sobre el lugar seleccionado en lugar de utilizar Place Details. Los precios por pedido asociados con la API de Geocoding son más rentables que los precios por sesión (basados en sesión) si se cumplen las siguientes condiciones:
- Si solo necesitas las coordenadas de latitud y longitud, o la dirección del lugar seleccionado por el usuario, la API de Geocoding proporciona esta información de manera más fácil que una llamada a Place Details.
- Si los usuarios seleccionan una predicción de autocompletar con un promedio de cuatro solicitudes o menos, el precio por solicitud puede ser más rentable que el precio por sesión.
¿Tu aplicación requiere algún dato diferente de la dirección y las coordenadas de latitud o longitud de la predicción seleccionada?
Sí, necesita más detalles.
Usa el servicio Place Autocomplete basado en sesiones con Place Details.
Dado que tu aplicación requiere datos de Place Details, como el nombre del lugar, el estado de la empresa o el horario de atención, tu implementación de Place Autocomplete debe usar un token de sesión (programático o integrado en los widgets de JavaScript, Android o iOS) por un costo total de USD 0.017 por sesión más los SKUs de datos de Places aplicables según los campos de datos de lugar que solicites.1
Implementación de widgets
La administración de sesiones está integrada automáticamente en los widgets de JavaScript, Android o iOS. Esto incluye las solicitudes de Place Autocomplete y Place Details en la predicción seleccionada. Asegúrate de especificar el parámetro fields
para asegurarte de solicitar únicamente los campos de datos de lugar que necesitas.
Implementación programática
Usa un token de sesión con tus solicitudes de Place Autocomplete. Cuando solicites la predicción seleccionada a Place Details, incluye los siguientes parámetros:
- El ID de lugar de la respuesta de Place Autocomplete
- El token de sesión que se utilizó en la solicitud de Place Autocomplete
- El parámetro
fields
que especifica los campos de datos de lugar que necesitas
No, solo requiere la dirección y la ubicación.
La API de Geocoding podría ser una opción más rentable que Place Details para tu aplicación, según el rendimiento de su uso de Place Autocomplete. La eficiencia de Autocomplete de cada aplicación varía según las búsquedas que ingresan los usuarios, dónde se usa la aplicación y si se siguen las prácticas recomendadas de optimización del rendimiento.
Para responder la siguiente pregunta, analiza cuántos caracteres escribe un usuario en promedio antes de seleccionar una predicción de Place Autocomplete en tu aplicación.
¿Tus usuarios seleccionan, en promedio, una predicción de Place Autocomplete cada cuatro solicitudes o menos?
Sí
Implementa Place Autocomplete de manera programática sin tokens de sesión y llama a la API de Geocoding en la predicción de lugar seleccionada.
La API de Geocoding proporciona direcciones y coordenadas de latitud y longitud por USD 0.005 por solicitud. Realizar cuatro solicitudes de Place Autocomplete por solicitud cuesta USD 0.01132, por lo que el costo total de cuatro solicitudes más una llamada a la API de Geocoding sobre la predicción de lugar seleccionada sería de USD 0.01632, lo cual es inferior al precio del autocompletado por sesión, que es de USD 0.017.1
Considera aplicar las prácticas recomendadas de rendimiento para ayudar a los usuarios a obtener la predicción que buscan con menos caracteres.
No
Usa el servicio Place Autocomplete basado en sesiones con Place Details.
Dado que la cantidad promedio de solicitudes que esperas hacer antes de que un usuario seleccione una predicción de Place Autocomplete supera el costo del precio por sesión, la implementación de Place Autocomplete debe usar un token de sesión para las solicitudes de Place Autocomplete y la solicitud de Place Details asociada por un costo total de USD 0.017 por sesión.1
Implementación de widgets
La administración de sesiones está integrada automáticamente en los widgets de JavaScript, Android o iOS. Esto incluye las solicitudes de Place Autocomplete y Place Details en la predicción seleccionada. Asegúrate de especificar el parámetro fields
para asegurarte de solicitar únicamente campos de datos básicos.
Implementación programática
Usa un token de sesión con tus solicitudes de Place Autocomplete. Cuando solicites la predicción seleccionada a Place Details, incluye los siguientes parámetros:
- El ID de lugar de la respuesta de Place Autocomplete
- El token de sesión que se utilizó en la solicitud de Place Autocomplete
- El parámetro
fields
que especifica campos de datos básicos, como la dirección y la geometría
Considera retrasar las solicitudes de Place Autocomplete
Puedes emplear estrategias como demorar una solicitud de Place Autocomplete hasta que el usuario escriba los primeros tres o cuatro caracteres para que tu aplicación realice menos solicitudes. Por ejemplo, cuando se realizan solicitudes de Place Autocomplete para cada carácter después de que el usuario escribe el tercer carácter, si el usuario escribe siete caracteres y luego selecciona una predicción para la cual haces una solicitud a la API de Geocoding, el costo total será de USD 0.01632 (4 * USD 0.00283 (autocompletado por solicitud) + USD 0.005 (Geocoding)).1
Si retrasar las solicitudes puede hacer que tu solicitud programática promedio sea inferior a cuatro, puedes seguir las instrucciones para implementar Place Autocomplete con la API de Geocoding y obtener un rendimiento optimizado. Ten en cuenta que demorar las solicitudes puede percibirse como latencia por parte del usuario, que tal vez espere ver predicciones con cada letra que ingresa.
Considera seguir las prácticas recomendadas de rendimiento para ayudar a los usuarios a obtener la predicción que buscan con menos caracteres.
-
Los costos se indican en USD. Consulta la página Facturación de Google Maps Platform para obtener información completa sobre los precios.
Prácticas recomendadas para mejorar el rendimiento
Los siguientes lineamientos describen maneras de optimizar el rendimiento de Place Autocomplete:
- Agrega restricciones por país, personalización de la ubicación y, en el caso de las implementaciones programáticas, la preferencia de idioma a la implementación de Place Autocomplete. La preferencia de idioma no es necesaria para los widgets, dado que toman esta información del navegador o el dispositivo móvil del usuario.
- Si Place Autocomplete cuenta con un mapa, puedes personalizar la ubicación según su viewport.
- En las situaciones en que un usuario no elige una de las predicciones de Autocomplete, generalmente, porque ninguna de ellas indica el resultado deseado, puedes reutilizar la entrada original del usuario para tratar de obtener resultados más relevantes:
- Si esperas que el usuario ingrese únicamente información sobre la dirección, vuelve a usar su entrada original en una llamada a la API de Geocoding.
- Si esperas que el usuario ingrese búsquedas para un lugar específico por nombre o dirección, usa una solicitud de Find Place. Si se espera que los resultados pertenezcan únicamente a una región específica, usa la restricción de ubicación.
- Usuarios que ingresan direcciones con números de departamento en países donde la compatibilidad de Place Autocomplete no es completa (p. ej., República Checa, Estonia y Lituania; así, la dirección checa "Stroupežnického 3191/17, Praha" genera una predicción parcial en Place Autocomplete)
- Usuarios que ingresan direcciones con prefijos de tramo de ruta, como "23-30 29th St, Queens" en la ciudad de Nueva York o "47-380 Kamehameha Hwy, Kaneohe" en la isla de Kauai en Hawái
Soluciona problemas
Aunque pueden producirse muchos errores, la mayoría de los errores que se que la app experimenta, en general, son causados por errores de configuración (para Por ejemplo, se usó una clave de API incorrecta o se configuró la clave de API incorrectamente) o errores de cuota (tu app excedió su cuota). Consulta Límites de uso para obtener más información sobre las cuotas.
Los errores que ocurren al usar los controles de autocompletar se devuelven en el
Método didFailAutocompleteWithError()
de los diferentes protocolos delegados El
La propiedad code
del objeto NSError
proporcionado se establece en uno de los valores de
la enumeración GMSPlacesErrorCode
.