Il servizio di completamento automatico in Places SDK per iOS restituisce le predizioni relative ai luoghi in risposta alle query di ricerca degli utenti. Man mano che l'utente digita, il servizio di completamento automatico restituisce suggerimenti per luoghi come attività, indirizzi, plus code e punti d'interesse.
Puoi aggiungere il completamento automatico alla tua app nei seguenti modi:
- Aggiungi un controllo UI di completamento automatico per risparmiare tempo di sviluppo e garantire un'esperienza utente coerente.
- Ricevi le previsioni dei luoghi in modo programmatico per creare un'esperienza utente personalizzata.
Aggiunta di un controllo UI di completamento automatico
Il controllo UI di completamento automatico è una finestra di dialogo di ricerca con funzionalità di completamento automatico integrata. Quando un utente inserisce i termini di ricerca, il controllo presenta un elenco di luoghi previsti tra cui scegliere. Quando l'utente effettua una selezione, viene restituita un'istanza di GMSPlace
che la tua app può utilizzare per ottenere i dettagli del luogo selezionato.
Puoi aggiungere il controllo UI di completamento automatico all'app nei seguenti modi:
- Aggiungere un controllo a schermo intero
- Aggiungere un controllo risultati
- Utilizzare un'origine dati tabella
Aggiungere un controllo a schermo intero
Utilizza il controllo a schermo intero quando vuoi un contesto modale, in cui l'UI di completamento automatico sostituisce temporaneamente l'UI della tua app finché l'utente non ha effettuato la selezione. Questa funzionalità è fornita dalla classe
GMSAutocompleteViewController
. Quando l'utente seleziona un luogo, la tua app riceve un callback.
Per aggiungere un controllo a schermo intero alla tua app:
- Crea un elemento UI nell'app principale per avviare il controllo UI di completamento automatico, ad esempio un gestore tocco su un
UIButton
. - Implementa il protocollo
GMSAutocompleteViewControllerDelegate
nel controller di visualizzazione principale. - Crea un'istanza di
GMSAutocompleteViewController
e assegna il controller della vista principale come proprietà del delegato. - Crea un
GMSPlaceField
per definire i tipi di dati dei luoghi da restituire. - Aggiungi un
GMSAutocompleteFilter
per limitare la query a un determinato tipo di luogo. - Presenta
GMSAutocompleteViewController
utilizzando[self presentViewController...]
. - Gestisci la selezione dell'utente nel metodo
didAutocompleteWithPlace
delegate. - Rimuovi il controller nei metodi delegati
didAutocompleteWithPlace
,didFailAutocompleteWithError
ewasCancelled
.
L'esempio seguente mostra un possibile modo per avviare
GMSAutocompleteViewController
in risposta al tocco di un pulsante da parte dell'utente.
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
Aggiunta di un controllore dei risultati
Utilizza un controller dei risultati se vuoi un maggiore controllo sull'interfaccia utente di inserimento di testo. Il controller dei risultati attiva e disattiva dinamicamente la visibilità dell'elenco dei risultati in base all'input dell'UI.
Per aggiungere un controller dei risultati all'app:
- Crea un
GMSAutocompleteResultsViewController
.- Implementa il protocollo
GMSAutocompleteResultsViewControllerDelegate
nel view controller principale e assegnalo come proprietà del delegato.
- Implementa il protocollo
- Crea un oggetto
UISearchController
, passando il valoreGMSAutocompleteResultsViewController
come argomento del controller dei risultati. - Imposta
GMSAutocompleteResultsViewController
come proprietàsearchResultsUpdater
diUISearchController
. - Aggiungi il
searchBar
per ilUISearchController
all'interfaccia utente della tua app. - Gestisci la selezione dell'utente nel metodo
didAutocompleteWithPlace
delegate.
Esistono diversi modi per inserire la barra di ricerca di un UISearchController
nell'interfaccia utente della tua app:
- Aggiungere una barra di ricerca alla barra di navigazione
- Aggiungere una barra di ricerca nella parte superiore di una visualizzazione
- Aggiungere una barra di ricerca utilizzando i risultati popup
Aggiunta di una barra di ricerca alla barra di navigazione
L'esempio di codice seguente mostra l'aggiunta di un controller dei risultati, l'aggiunta di searchBar
alla barra di navigazione e la gestione della selezione dell'utente:
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; }
Aggiunta di una barra di ricerca nella parte superiore di una visualizzazione
Il seguente esempio di codice mostra l'aggiunta di searchBar
nella parte superiore di una visualizzazione.
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; }
Per impostazione predefinita,
UISearchController
nasconde la barra di navigazione durante la presentazione (questa opzione può essere disattivata). Nei casi in cui la barra di navigazione sia visibile e opaca, UISearchController
non imposta correttamente il posizionamento.
Utilizza il seguente codice come soluzione alternativa:
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;
Aggiunta di una barra di ricerca utilizzando i risultati popup
L'esempio di codice seguente mostra il posizionamento di una barra di ricerca sul lato destro della barra di navigazione e la visualizzazione dei risultati in un popup.
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; }
Utilizzare un'origine dati della tabella
Se la tua app ha un'interfaccia utente di testo di ricerca personalizzata, puoi utilizzare la classe
GMSAutocompleteTableDataSource
per gestire la visualizzazione tabella che mostra i risultati nel controller della visualizzazione.
Per utilizzare
GMSAutocompleteTableDataSource
come origine dati e delegato di
UITableView
in un controller della vista:
- Implementa i protocolli
GMSAutocompleteTableDataSourceDelegate
eUISearchBarDelegate
nel controller della visualizzazione. - Crea un'istanza di
GMSAutocompleteTableDataSource
e assegna il controller della vista come proprietà del delegato. - Imposta
GMSAutocompleteTableDataSource
come origine dati e delega le proprietà dell'istanzaUITableView
sul controller della vista. - Nell'handler per l'input del testo di ricerca, chiama
sourceTextHasChanged
suGMSAutocompleteTableDataSource
.- Gestisci la selezione dell'utente nel metodo
didAutocompleteWithPlace
delegate.
- Gestisci la selezione dell'utente nel metodo
- Rilascia il controllore nei metodi del delegato
didAutocompleteWithPlace
,didFailAutocompleteWithError
,wasCancelled
.
Il seguente esempio di codice mostra come utilizzare la classe
GMSAutocompleteTableDataSource
per gestire la visualizzazione tabella di un UIViewController
quando il UISearchBar
viene
aggiunto separatamente.
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
Personalizzare i colori del testo e dello sfondo
Puoi impostare i colori di testo e sfondo nel controllo UI per il completamento automatico, in modo da abbinare il widget all'aspetto visivo della tua app. Esistono due modi per impostare i colori dei controlli dell'interfaccia utente:
- Utilizzando il protocollo UIAppearance di iOS integrato per applicare lo stile ai controlli dell'interfaccia utente a livello globale, ove possibile. Queste impostazioni si applicano a molti, ma non a tutti, gli elementi di controllo dell'interfaccia utente.
- Utilizzando i metodi SDK sulle classi di widget per impostare proprietà che non sono supportate dal protocollo UIAppearance.
In genere, l'app utilizza una combinazione del protocollo UIAppearance e dei metodi SDK. Il seguente diagramma mostra quali elementi possono essere personalizzati:
La tabella seguente elenca tutti gli elementi dell'interfaccia utente e indica lo stile di ciascuno (protocollo UIAppearance o metodo SDK).
Elemento UI | Metodo | Guida allo stile |
---|---|---|
Tinta barra di navigazione (sfondo) | Protocollo UIAppearance | Chiama setBarTintColor sul proxy UINavigationBar . |
Colore tonalità barra di navigazione (cursore del testo della barra di ricerca e pulsante Annulla) | Protocollo UIAppearance | Chiama setTintColor sul proxy UINavigationBar . |
Colore del testo della barra di ricerca | Protocollo UIAppearance | Imposta NSForegroundColorAttributeName in searchBarTextAttributes . |
Colore tinta della barra di ricerca | N/D | La barra di ricerca è traslucida e viene visualizzata come una versione ombreggiata della barra di navigazione. |
Colore del testo segnaposto della barra di ricerca (testo di ricerca predefinito) | Protocollo UIAppearance | Imposta NSForegroundColorAttributeName in placeholderAttributes . |
Testo principale (applicato anche al testo di errori e messaggi) | Metodo SDK | Chiama il numero primaryTextColor . |
Evidenziazione del testo principale | Metodo SDK | Chiama il numero primaryTextHighlightColor . |
Testo secondario | Metodo SDK | Chiama il numero secondaryTextColor . |
Testo di errore e messaggio | Metodo SDK | Chiama il numero primaryTextColor . |
Sfondo delle celle della tabella | Metodo SDK | Chiama il numero tableCellBackgroundColor . |
Colore del separatore delle celle della tabella | Metodo SDK | Chiama il numero tableCellSeparatorColor . |
Pulsante "Riprova" | Metodo SDK | Chiama il numero tintColor . |
Indicatore di attività (indicatore di avanzamento) | Protocollo UIAppearance | Chiama setColor sul proxy UIActivityIndicatorView . |
Logo "Powered by Google", immagine di una nuvola triste | N/D | La versione bianca o grigia viene selezionata automaticamente in base al contrasto dello sfondo. |
Icone a forma di lente d'ingrandimento e testo chiaro nel campo di testo della barra di ricerca | N/D | Per applicare uno stile, sostituisci le immagini predefinite con immagini del colore desiderato. |
Utilizzo del protocollo UIAppearance
Puoi utilizzare il protocollo UIAppearance per ottenere il proxy dell'aspetto di un determinato elemento dell'interfaccia utente, che puoi poi utilizzare per impostare il colore dell'elemento. Quando viene apportata una modifica, tutte le istanze di un determinato elemento dell'interfaccia utente sono interessate. Ad esempio, l'esempio seguente cambia in modo globale il colore del testo delle classi UITextField
in verde quando sono contenute in un UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
Per ulteriori informazioni sulla definizione dei valori di colore, consulta la sezione Riferimento alla classe UIColor.
I seguenti snippet di codice mostrano tutti i comandi proxy che devi utilizzare per impostare lo stile di tutti gli elementi del controllo UI di completamento automatico a schermo intero. Aggiungi questo codice al metodo didFinishLaunchingWithOptions
in 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;
Impostazione delle proprietà dello stile di controllo dell'interfaccia utente
Un sottoinsieme di elementi di controllo dell'interfaccia utente ha proprietà che non sono interessate dal protocollo UIAppearance e devono quindi essere impostate direttamente. Il seguente esempio di codice
mostra la definizione dei colori di primo piano e di sfondo e la loro applicazione a un'istanza di controllo UI acController
. Aggiungi questo codice al metodo onLaunchClicked
in 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;
Ottenere le previsioni dei luoghi in modo programmatico
Puoi creare un'interfaccia utente di ricerca personalizzata come alternativa a quella fornita dal widget di completamento automatico. Per farlo, l'app deve ricevere le previsioni dei luoghi programmaticamente. La tua app può ottenere un elenco di nomi di luoghi e/o indirizzi previsti in uno dei seguenti modi:
Chiamata a GMSPlacesClient findAutocompletePredictionsFromQuery:
Per ottenere un elenco di nomi di luoghi e/o indirizzi previsti, inizializza
GMSPlacesClient,
poi chiama il metodo GMSPlacesClient
findAutocompletePredictionsFromQuery:
con i seguenti parametri:
- Una stringa
autocompleteQuery
contenente il testo digitato dall'utente. - Un
GMSAutocompleteSessionToken
, che viene utilizzato per identificare ogni singola sessione. L'app deve passare lo stesso token per ogni chiamata alla richiesta di completamento automatico, quindi passare quel token, insieme a un ID luogo, nella chiamata successiva afetchPlacefromPlaceID:
per recuperare i dettagli del luogo selezionato dall'utente. - A
GMSAutocompleteFilter
a:- Spostare l'attenzione o limitare i risultati a una regione specifica.
- Limita i risultati a un tipo di luogo specifico.
- Un oggetto
GMSPlaceLocationBias
/Restriction che orienta i risultati verso un'area specifica specificata da limiti di latitudine e longitudine.
- Un metodo di callback per gestire le previsioni restituite.
Gli esempi di codice riportati di seguito mostrano una chiamata 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); } } }];
L'API invoca il metodo di callback specificato, passando un array di oggetti
GMSAutocompletePrediction
.
Ogni
oggetto
GMSAutocompletePrediction
contiene le seguenti informazioni:
attributedFullText
: il testo completo della previsione, sotto forma diNSAttributedString
. Ad esempio, "Sydney Opera House, Sydney, Nuovo Galles del Sud, Australia". Ogni intervallo di testo che corrisponde all'input dell'utente ha un attributo,kGMSAutocompleteMatchAttribute
. Puoi utilizzare questo attributo per evidenziare il testo corrispondente nella query dell'utente, ad esempio come mostrato di seguito.placeID
: l'ID luogo del luogo previsto. Un ID luogo è un identificatore di testo che identifica in modo univoco un luogo. Per ulteriori informazioni sugli ID luogo, consulta la panoramica degli ID luogo.distanceMeters
: la distanza in linea retta dalorigin
specificato alla destinazione. Se la proprietàorigin
non è impostata, non verrà restituito alcun valore di distanza.
Il seguente esempio di codice illustra come evidenziare in grassetto le parti del risultato che corrispondono al testo nella query dell'utente utilizzando 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;
Utilizzo del locatore
Se vuoi creare da zero il tuo controllo di completamento automatico, puoi utilizzare
GMSAutocompleteFetcher
, che
incapsula il metodo autocompleteQuery
su
GMSPlacesClient
. Il recuperatore limita le richieste, restituendo solo i risultati relativi al testo di ricerca inserito più di recente. Non fornisce elementi dell'interfaccia utente.
Per implementare
GMSAutocompleteFetcher
,
segui questi passaggi:
- Implementa il protocollo
GMSAutocompleteFetcherDelegate
. - Crea un oggetto
GMSAutocompleteFetcher
. - Chiama
sourceTextHasChanged
sul recuperatore mentre l'utente digita. - Gestisci le previsioni e gli errori utilizzando i metodi di protocollo
didAutcompleteWithPredictions
edidFailAutocompleteWithError
.
Il seguente esempio di codice mostra come utilizzare il recupero per acquisire l'input dell'utente e visualizzare le corrispondenze dei luoghi in una visualizzazione di testo. La funzionalità per la selezione di un luogo è stata omessa. FetcherSampleViewController
deriva da UIViewController
in
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
Token di sessione
I token di sessione raggruppano le fasi di query e selezione di una ricerca di completamento automatico dell'utente in una sessione distinta a fini di fatturazione. La sessione inizia quando l'utente inizia a digitare una query e termina quando seleziona un luogo. Ogni sessione può avere più query, seguite dalla selezione di un luogo. Al termine di una sessione, il token non è più valido; l'app deve generare un nuovo token per ogni sessione. Ti consigliamo di utilizzare i token di sessione per tutte le sessioni di completamento automatico programmatico (quando utilizzi il controllo a schermo intero o il controllo dei risultati, l'API si occupa di tutto automaticamente).
L'SDK Places per iOS utilizza un
GMSAutocompleteSessionToken
per identificare ogni sessione. L'app deve passare un nuovo token di sessione all'inizio di ogni nuova sessione, quindi passare lo stesso token, insieme a un ID luogo, nella chiamata successiva a fetchPlacefromPlaceID:
per recuperare i dettagli del luogo selezionato dall'utente.
Scopri di più sui token sessione.
Utilizza il seguente codice per generare un nuovo token di sessione:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
Limiti di utilizzo
- L'utilizzo del metodo
GMSPlacesClient findAutocompletePredictionsFromQuery
è soggetto a limiti di query a più livelli. Consulta la documentazione relativa ai limiti di utilizzo.
Visualizzazione delle attribuzioni nell'app
- Se la tua app utilizza il servizio di completamento automatico in modo programmatico, l'interfaccia utente deve mostrare un'attribuzione "Fornito da Google" o apparire all'interno di una mappa con il brand Google.
- Se la tua app utilizza il controllo UI di completamento automatico, non è necessaria alcuna azione aggiuntiva (l'attribuzione richiesta viene visualizzata per impostazione predefinita).
- Se recuperi e mostri ulteriori informazioni sui luoghi dopo aver recuperato un luogo tramite ID, devi mostrare anche gli attributi di terze parti.
Per ulteriori dettagli, consulta la documentazione sulle attribuzioni.
Controllo dell'indicatore di attività di rete
Per controllare l'indicatore dell'attività di rete nella barra di stato delle applicazioni, devi implementare i metodi facoltativi del delegato appropriati per la classe di completamento automatico che stai utilizzando e attivare e disattivare manualmente l'indicatore di rete.
- Per
GMSAutocompleteViewController
devi implementare i metodi delegatididRequestAutocompletePredictions:
edidUpdateAutocompletePredictions:
. - Per
GMSAutocompleteResultsViewController
devi implementare i metodi del delegatodidRequestAutocompletePredictionsForResultsController:
edidUpdateAutocompletePredictionsForResultsController:
. - Per
GMSAutocompleteTableDataSource
devi implementare i metodi del delegatodidRequestAutocompletePredictionsForTableDataSource:
edidUpdateAutocompletePredictionsForTableDataSource:
.
Se implementi questi metodi e imposti [UIApplication
sharedApplication].networkActivityIndicatorVisible
su YES
e NO
, la barra di stato corrisponderà correttamente all'interfaccia utente di completamento automatico.
Limitare i risultati del completamento automatico
Puoi impostare il controllo UI di completamento automatico in modo da limitare i risultati a una specifica regione geografica e/o filtrare i risultati in base a uno o più tipi di località o a un paese o a paesi specifici. Per limitare i risultati, puoi:
- Per preferire (predisponibilità) i risultati all'interno della regione definita, imposta
locationBias
suGMSAutocompleteFilter
(alcuni risultati al di fuori della regione definita potrebbero essere ancora restituiti). Se è impostato anchelocationRestriction
,locationBias
viene ignorato. Per mostrare solo (limitare) i risultati all'interno della regione definita, imposta
locationRestriction
suGMSAutocompleteFilter
(verranno restituiti solo i risultati all'interno della regione definita).- Nota: questa limitazione si applica solo a interi percorsi. I risultati sintetici situati al di fuori dei limiti rettangolari possono essere restituiti in base a un percorso che si sovrappone alla limitazione della località.
Per restituire solo i risultati conformi a un determinato tipo di luogo, imposta
types
suGMSAutocompleteFilter
. Ad esempio, se specifichi TypeFilter.ADDRESS, il widget restituirà solo i risultati con un indirizzo preciso.Per restituire solo i risultati relativi a un massimo di cinque paesi specificati, imposta
countries
suGMSAutocompleteFilter
.
Spostare in modo ingiusto i risultati verso una regione specifica
Per preferire (predisponibilità) i risultati all'interno della regione definita, imposta locationBias
su
GMSAutocompleteFilter
, come mostrato di seguito:
northEast = CLLocationCoordinate2DMake(39.0, -95.0); southWest =
CLLocationCoordinate2DMake(37.5, -100.0); GMSAutocompleteFilter *filter =
[[GMSAutocompleteFilter alloc] init]; filter.locationBias =
GMSPlaceRectangularLocationOption(northEast, southWest);
Limitare i risultati a una regione specifica
Per mostrare solo (limitare) i risultati all'interno della regione definita, imposta locationRestriction
su GMSAutocompleteFilter
, come mostrato di seguito:
northEast = CLLocationCoordinate2DMake(39.0, -95.0); southWest =
CLLocationCoordinate2DMake(37.5, -100.0); GMSAutocompleteFilter *filter =
[[GMSAutocompleteFilter alloc] init]; filter.locationRestriction =
GMSPlaceRectangularLocationOption(northEast, southWest);
Filtra i risultati per paese
Per filtrare i risultati in un massimo di cinque paesi specificati, imposta countries
su
GMSAutocompleteFilter
, come mostrato di seguito:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
Filtra i risultati per tipo di luogo o raccolta di tipi
Limita i risultati a un determinato tipo o a una raccolta di tipi impostando la proprietà types
di GMSAutoCompleteFilter
.
Utilizza questa proprietà per specificare i filtri elencati nelle tabelle 1, 2 e 3 in Place
Types. Se non viene specificato nulla, vengono restituiti tutti i tipi.
Per specificare un filtro di tipo o di raccolta di tipi:
Utilizza la proprietà
types
per specificare fino a cinque valori type della Tabella 1 e della Tabella 2 mostrati in Tipi di luoghi. I valori di tipo sono definiti dalle costanti inGMSPlaceType
.Utilizza la proprietà
types
per specificare una raccolta di tipi dalla Tabella 3 riportata in Tipi di luoghi. I valori della raccolta di tipi sono definiti dalle costanti inGMSPlaceType
.Nella richiesta è consentito un solo tipo della Tabella 3. Se specifichi un valore della Tabella 3, non puoi specificare un valore della Tabella 1 o della Tabella 2. Se lo fai, si verifica un errore.
Ad esempio, per restituire solo i risultati conformi a un determinato tipo di luogo, imposta
types
su GMSAutocompleteFilter
. L'esempio seguente mostra l'impostazione del
filtro in modo da restituire solo i risultati con un indirizzo preciso:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
Ottimizzazione del completamento automatico dei luoghi
Questa sezione descrive le best practice per aiutarti a sfruttare al meglio il servizio di completamento automatico dei luoghi.
Ecco alcune linee guida generali:
- Il modo più rapido per sviluppare un'interfaccia utente funzionante è utilizzare il widget di completamento automatico dell'API Maps JavaScript, il widget di completamento automatico di Places SDK per Android o il controllo UI di completamento automatico di Places SDK per iOS.
- Acquisisci fin dall'inizio una conoscenza dei campi di dati essenziali di Completamento automatico dei luoghi.
- I campi di bias di località e limitazione della località sono facoltativi, ma possono avere un impatto significativo sul rendimento del completamento automatico.
- Utilizza la gestione degli errori per assicurarti che l'app degradi in modo corretto se l'API restituisce un errore.
- Assicurati che la tua app gestisca la situazione in cui non viene effettuata alcuna selezione e offra agli utenti un modo per continuare.
Best practice per l'ottimizzazione dei costi
Ottimizzazione dei costi di base
Per ottimizzare il costo dell'utilizzo del servizio Place Autocomplete, utilizza le maschere dei campi nei widget Dettagli dei luoghi e Place Autocomplete per restituire solo i campi dati dei luoghi di cui hai bisogno.
Ottimizzazione avanzata dei costi
Valuta la possibilità di implementare in modo programmatico Place Autocomplete per accedere ai prezzi per richiesta e richiedere i risultati dell'API Geocoding relativi al luogo selezionato anziché a Place Details. I prezzi per richiesta abbinati all'API Geocoding sono più convenienti rispetto ai prezzi per sessione (in base alla sessione) se sono soddisfatte entrambe le seguenti condizioni:
- Se ti serve solo la latitudine/longitudine o l'indirizzo del luogo selezionato dall'utente, l'API Geocoding fornisce queste informazioni a un costo inferiore a una chiamata a Dettagli luogo.
- Se gli utenti selezionano una previsione di completamento automatico entro una media di quattro richieste di previsione di completamento automatico o meno, i prezzi per richiesta potrebbero essere più convenienti rispetto a quelli per sessione.
La tua applicazione richiede altre informazioni oltre all'indirizzo e alla latitudine/longitudine della previsione selezionata?
Sì, sono necessari ulteriori dettagli
Utilizza la funzionalità di completamento automatico dei luoghi basata sulla sessione con i dettagli dei luoghi.
Poiché la tua applicazione richiede dettagli sui luoghi, come il nome del luogo, lo stato dell'attività o l'orario di apertura, l'implementazione di Place Autocomplete deve utilizzare un token di sessione (programmaticamente o integrato nei widget JavaScript, Android o iOS) a un costo totale di 0,017 $per sessione più gli SKU dei dati di Places applicabili, a seconda dei campi di dati dei luoghi che richiedi.1
Implementazione dei widget
La gestione delle sessioni è integrata automaticamente nei widget JavaScript, Android o iOS. Sono incluse sia le richieste di completamento automatico dei luoghi sia la richiesta di dettagli dei luoghi per la previsione selezionata. Assicurati di specificare il parametro fields
per assicurarti di richiedere solo i
campi dati dei luoghi di cui hai bisogno.
Implementazione programmatica
Utilizza un token di sessione con le richieste Place Autocomplete. Quando richiedi i dettagli dei luoghi relativi alla previsione selezionata, includi i seguenti parametri:
- L'ID luogo della risposta di Place Autocomplete
- Il token di sessione utilizzato nella richiesta Place Autocomplete
- Il parametro
fields
che specifica i campi di dati dei luoghi di cui hai bisogno
No, sono necessari solo indirizzo e posizione
L'API Geocoding potrebbe essere un'opzione più conveniente di Dettagli dei luoghi per la tua applicazione, a seconda del rendimento dell'utilizzo di Completamento automatico dei luoghi. L'efficienza del completamento automatico di ogni applicazione varia a seconda di ciò che gli utenti inseriscono, di dove viene utilizzata l'applicazione e se sono state implementate le best practice per l'ottimizzazione delle prestazioni.
Per rispondere alla seguente domanda, analizza il numero di caratteri digitati in media da un utente prima di selezionare una previsione di Place Autocomplete nella tua applicazione.
In media, i tuoi utenti selezionano una previsione del completamento automatico dei luoghi in quattro o meno richieste?
Sì
Implementa la funzionalità di completamento automatico dei luoghi in modo programmatico senza token di sessione e chiama l'API Geocoding sulla previsione del luogo selezionato.
L'API Geocoding fornisce indirizzi e coordinate di latitudine/longitudine a 0,005 $per richiesta. L'invio di quattro richieste Place Autocomplete - Per richiesta costa 0,01132 $, pertanto il costo totale di quattro richieste più una chiamata all'API Geocoding relativa alla previsione del luogo selezionato è pari a 0,01632 $, inferiore al prezzo di 0,017 $per sessione di Autocomplete per sessione.1
Valuta la possibilità di utilizzare le best practice per il rendimento per aiutare gli utenti a ottenere la previsione che cercano con un numero ancora inferiore di caratteri.
No
Utilizza la funzionalità di completamento automatico dei luoghi basata sulla sessione con i dettagli dei luoghi.
Poiché il numero medio di richieste che prevedi di effettuare prima che un utente selezioni una previsione di Place Autocomplete supera il costo del prezzo per sessione, l'implementazione di Place Autocomplete deve utilizzare un token di sessione sia per le richieste di Place Autocomplete sia per la richiesta di dettagli dei luoghi associata a un costo totale di 0,017 $per sessione.1
Implementazione dei widget
La gestione delle sessioni è integrata automaticamente nei widget JavaScript, Android o iOS. Sono incluse sia le richieste di completamento automatico dei luoghi sia la richiesta di dettagli dei luoghi per la previsione selezionata. Assicurati di specificare il parametro fields
per assicurarti di richiedere solo i campi Dati di base.
Implementazione programmatica
Utilizza un token di sessione con le richieste Place Autocomplete. Quando richiedi i dettagli dei luoghi relativi alla previsione selezionata, includi i seguenti parametri:
- L'ID luogo della risposta di Place Autocomplete
- Il token di sessione utilizzato nella richiesta Place Autocomplete
- Il parametro
fields
che specifica i campi Dati di base come indirizzo e geometria
Valuta la possibilità di ritardare le richieste di completamento automatico dei luoghi
Puoi utilizzare strategie come il ritardo di una richiesta di completamento automatico dei luoghi fino a quando l'utente non ha digitato i primi tre o quattro caratteri, in modo che la tua applicazione effettui meno richieste. Ad esempio, se effettui richieste di completamento automatico dei luoghi per ogni carattere dopo che l'utente ha digitato il terzo carattere, significa che se l'utente digita sette caratteri e seleziona una previsione per la quale effettui una richiesta all'API Geocoding, il costo totale sarà di 0,01632 $ (4 * 0,00283 $ per completamento automatico per richiesta + 0,005 $per geocodifica).1
Se il ritardo delle richieste può ridurre la richiesta programmatica media a meno di quattro, puoi seguire le indicazioni per l'implementazione di Autocompletamento dei luoghi efficiente con l'API Geocoding. Tieni presente che le richieste in ritardo possono essere percepite come latenza dall'utente che potrebbe aspettarsi di vedere le previsioni con ogni nuova battuta.
Valuta la possibilità di utilizzare le best practice per il rendimento per aiutare gli utenti a ottenere la previsione che cercano con meno caratteri.
-
I costi indicati qui sono in dollari statunitensi. Per informazioni complete sui prezzi, consulta la pagina Fatturazione di Google Maps Platform.
Best practice per le prestazioni
Le seguenti linee guida descrivono i modi per ottimizzare il rendimento di Ricerca automatica dei luoghi:
- Aggiungi limitazioni per i paesi, bias di località e (per le implementazioni programmatiche) preferenze di lingua all'implementazione della funzionalità di completamento automatico dei luoghi. Con i widget non è necessaria la preferenza di lingua, poiché le preferenze di lingua vengono scelte dal browser o dal dispositivo mobile dell'utente.
- Se la funzionalità di completamento automatico dei luoghi è accompagnata da una mappa, puoi modificare la posizione in base all'area visibile della mappa.
- Quando un utente non sceglie una delle previsioni del completamento automatico, in genere perché nessuna di queste corrisponde all'indirizzo del risultato desiderato, puoi riutilizzare l'input utente originale per tentare di ottenere risultati più pertinenti:
- Se prevedi che l'utente inserisca solo i dati dell'indirizzo, riutilizza i dati inseriti dall'utente in una chiamata all'API Geocoding.
- Se prevedi che l'utente inserisca query per un luogo specifico per nome o indirizzo, utilizza una richiesta di ricerca di luoghi. Se i risultati sono previsti solo in una regione specifica, utilizza la sbiasatura della località.
- Utenti che inseriscono indirizzi di proprietà secondarie in paesi in cui il supporto del completamento automatico dei luoghi per gli indirizzi di proprietà secondarie è incompleto, ad esempio Cechia, Estonia e Lituania. Ad esempio, l'indirizzo ceco "Stroupežnického 3191/17, Praha" genera una previsione parziale in Posizione completamento automatico.
- Utenti che inseriscono indirizzi con prefissi di tratti stradali come "23-30 29th St, Queens" a New York o "47-380 Kamehameha Hwy, Kaneohe" sull'isola di Kauai nelle Hawaii.
Risoluzione dei problemi
Sebbene possano verificarsi una vasta gamma di errori, la maggior parte di quelli che possono verificarsi nella tua app è in genere causata da errori di configurazione (ad esempio, è stata utilizzata la chiave API errata o la chiave API è stata configurata in modo errato) o da errori di quota (la tua app ha superato la quota). Per ulteriori informazioni sulle quote, consulta Limiti di utilizzo.
Gli errori che si verificano durante l'utilizzo dei controlli di completamento automatico vengono restituiti nel metodo didFailAutocompleteWithError()
dei vari protocolli del delegato. La proprietà code
dell'oggetto NSError
fornito è impostata su uno dei valori dell'enumerazione GMSPlacesErrorCode
.