Il servizio di completamento automatico dell'SDK Places per iOS restituisce previsioni dei luoghi in risposta alle query di ricerca degli utenti. Man mano che l'utente digita, il servizio di completamento automatico restituisce suggerimenti per luoghi quali 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 GMSPlace
, che può essere utilizzata dall'app per ottenere dettagli sul luogo selezionato.
Puoi aggiungere il controllo UI di completamento automatico alla tua app nei seguenti modi:
- Aggiungere un controllo a schermo intero
- Aggiungere un controller dei risultati
- Utilizzare un'origine dati tabella
Aggiunta di 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 effettua la selezione. Questa funzionalità è fornita dalla classe GMSAutocompleteViewController
. Quando l'utente seleziona un luogo, la tua app riceve una chiamata.
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 del tocco su
UIButton
. - Implementa il protocollo
GMSAutocompleteViewControllerDelegate
nel controller di visualizzazione padre. - Crea un'istanza di
GMSAutocompleteViewController
e assegna il controller di visualizzazione principale come proprietà delegata. - Crea un
GMSPlaceField
per definire i tipi di dati del luogo da restituire. - Aggiungi un elemento
GMSAutocompleteFilter
per vincolare la query a un tipo di luogo particolare. - Presenta la
GMSAutocompleteViewController
utilizzando[self presentViewController...]
. - Gestisci la selezione dell'utente nel metodo di delega
didAutocompleteWithPlace
. - Ignora il controller nei metodi di delega
didAutocompleteWithPlace
,didFailAutocompleteWithError
ewasCancelled
.
L'esempio seguente mostra un possibile modo per avviare GMSAutocompleteViewController
in risposta a un utente che tocca un pulsante.
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:NSSelectorFromString(@"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 controller dei risultati
Utilizza un controller dei risultati per avere un maggiore controllo sull'interfaccia utente di input di testo. Il controller dei risultati attiva/disattiva in modo dinamico la visibilità dell'elenco dei risultati in base all'elemento attivo dell'interfaccia utente di input.
Per aggiungere un controller dei risultati alla tua app:
- Crea una
GMSAutocompleteResultsViewController
. - Implementa il protocollo
GMSAutocompleteResultsViewControllerDelegate
nel controller della vista principale e assegna quest'ultimo come proprietà delegata. - Crea un oggetto
UISearchController
, passando l'GMSAutocompleteResultsViewController
come argomento del controller dei risultati. - Imposta
GMSAutocompleteResultsViewController
come proprietàsearchResultsUpdater
diUISearchController
. - Aggiungi il
searchBar
perUISearchController
alla UI della tua app. - Gestisci la selezione dell'utente nel metodo di delega
didAutocompleteWithPlace
.
Esistono diversi modi per posizionare la barra di ricerca di UISearchController
nell'interfaccia utente dell'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 dei popover
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 da parte 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 vista
L'esempio di codice seguente mostra l'aggiunta di searchBar
nella parte superiore di 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; }
Per impostazione predefinita, UISearchController
nasconde la barra di navigazione durante la presentazione (può essere disattivata). Nei casi in cui la barra di navigazione è visibile e opaca, UISearchController
non imposta correttamente il posizionamento.
Per risolvere il problema, utilizza il seguente codice:
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 dei popover
Il seguente esempio di codice mostra il posizionamento di una barra di ricerca a destra della barra di navigazione e la visualizzazione dei risultati in un popover.
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 tabella
Se la tua app ha un'UI di testo della ricerca personalizzata, puoi utilizzare la classe GMSAutocompleteTableDataSource
per migliorare la visualizzazione tabella che mostra i risultati sul controller di visualizzazione.
Per utilizzare GMSAutocompleteTableDataSource
come origine dati e delegato dell'elemento UITableView
in una visualizzazione controller:
- Implementa i protocolli
GMSAutocompleteTableDataSourceDelegate
eUISearchBarDelegate
nel controller di visualizzazione. - Crea un'istanza
GMSAutocompleteTableDataSource
e assegna il controller di visualizzazione come proprietà delegata. - Imposta
GMSAutocompleteTableDataSource
come origine dati e delega le proprietà dell'istanzaUITableView
sul controller di visualizzazione. - Nel gestore dell'input di testo della ricerca, chiama
sourceTextHasChanged
suGMSAutocompleteTableDataSource
. - Gestisci la selezione dell'utente nel metodo delegato
didAutocompleteWithPlace
. - Ignora il controller nei metodi delegati
didAutocompleteWithPlace
,didFailAutocompleteWithError
,wasCancelled
.
L'esempio di codice seguente mostra l'utilizzo della classe GMSAutocompleteTableDataSource
per generare la visualizzazione tabella di un UIViewController
quando 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
Personalizzazione dei colori del testo e dello sfondo
Puoi impostare i colori di tutto il testo e gli sfondi nel controllo dell'interfaccia utente di completamento automatico per adattare meglio il widget all'aspetto visivo della tua app. Esistono due modi per impostare i colori dei controlli dell'interfaccia utente:
- Utilizzando il protocollo UIAspetto nativo di iOS per applicare uno stile globale ai controlli dell'interfaccia utente, ove possibile. Queste impostazioni si applicano a molti elementi dei controlli UI, ma non a tutti.
- Utilizzando i metodi SDK nelle classi dei widget per impostare le proprietà non supportate dal protocollo UIAspetto.
In genere, l'app utilizza una combinazione del protocollo UIAspetto e dei metodi dell'SDK. Il seguente diagramma mostra a quali elementi è possibile applicare uno stile:
La seguente tabella elenca tutti gli elementi dell'interfaccia utente e indica come ciascuno deve definire uno stile (protocollo UIAspetto o metodo SDK).
Elemento UI | Metodo | Guida allo stile |
---|---|---|
Tinta della barra di navigazione (sfondo) | Protocollo UIAspetto | Chiama setBarTintColor sul proxy UINavigationBar . |
Colore della tonalità della barra di navigazione (carattere di testo nella barra di ricerca e pulsante Annulla) | Protocollo UIAspetto | Chiama setTintColor sul proxy UINavigationBar . |
Colore testo barra di ricerca | Protocollo UIAspetto | Imposta NSForegroundColorAttributeName in searchBarTextAttributes . |
Colore tonalità barra di ricerca | N/D | La barra di ricerca è trasparente e viene visualizzata come una versione ombreggiata della barra di navigazione. |
Colore testo segnaposto della barra di ricerca (testo predefinito della ricerca) | Protocollo UIAspetto | Imposta NSForegroundColorAttributeName in placeholderAttributes . |
Testo principale (applicato anche al testo dell'errore e del messaggio) | Metodo SDK | Chiama primaryTextColor . |
Evidenziazione del testo principale | Metodo SDK | Chiama primaryTextHighlightColor . |
Testo secondario | Metodo SDK | Chiama secondaryTextColor . |
Testo dell'errore e del messaggio | Metodo SDK | Chiama primaryTextColor . |
Sfondo della cella della tabella | Metodo SDK | Chiama tableCellBackgroundColor . |
Colore separatore cella tabella | Metodo SDK | Chiama tableCellSeparatorColor . |
Pulsante "Riprova" | Metodo SDK | Chiama tintColor . |
Indicatore di attività (rotellina di avanzamento) | Protocollo UIAspetto | Chiama setColor sul proxy UIActivityIndicatorView . |
Logo "Powered by Google", immagine cloud triste | N/D | La versione bianca o grigia viene selezionata automaticamente in base al contrasto dello sfondo. |
Lente d'ingrandimento e icone di testo in chiaro nel campo di testo della barra di ricerca | N/D | Per applicare uno stile, sostituisci le immagini predefinite con immagini del colore che preferisci. |
Utilizzo del protocollo UIAspetto
Puoi utilizzare il protocollo UIAspetto per ottenere il proxy dell'aspetto per un determinato elemento dell'interfaccia utente, che puoi utilizzare per impostare il colore dell'elemento dell'interfaccia utente. Quando viene apportata una modifica, l'operazione influisce su tutte le istanze di un determinato elemento dell'interfaccia utente. Ad esempio, il seguente esempio modifica globalmente il colore del testo delle classi UITextField
in verde quando sono contenute in una classe UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
Per ulteriori informazioni sulla definizione dei valori dei colori, consulta la pagina UIColor Class Reference.
I seguenti snippet di codice mostrano tutti i comandi proxy che devi utilizzare per applicare lo stile a tutti gli elementi nel controllo dell'interfaccia utente 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;
Impostare le proprietà degli stili dei controlli UI
Un sottoinsieme di elementi di controllo dell'interfaccia utente ha proprietà che non sono interessate dal protocollo UIAspetto, quindi deve essere impostato direttamente. L'esempio di codice riportato di seguito mostra la definizione dei colori in primo piano e di sfondo e la loro applicazione a un'istanza di controllo dell'interfaccia utente denominata 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 in modo programmatico
Puoi creare un'interfaccia utente di ricerca personalizzata in alternativa a quella fornita dal widget di completamento automatico. A questo scopo, l'app deve ricevere le previsioni delle posizioni in modo programmatico. La tua app può recuperare un elenco di nomi e/o indirizzi previsti dei luoghi in uno dei seguenti modi:
Chiamo GMSPlacesClient findAutocompletePredictionsFromQuery:
Per ottenere un elenco di nomi di luoghi e/o indirizzi previsti, per prima cosa instaura 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 di richiesta di completamento automatico, quindi questo token, insieme a un ID luogo, nella successiva chiamata afetchPlacefromPlaceID:
per recuperare i Dettagli luogo relativi al luogo selezionato dall'utente. - Un
GMSAutocompleteFilter
per:- Limita i risultati a una regione specifica.
- Limita i risultati a un tipo di luogo specifico.
- Un oggetto
GMSPlaceLocationBias
/Restriction che polarizza i risultati in un'area specifica specificata dai 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 richiama 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, "Teatro dell'opera di Sydney, Sydney, Nuovo Galles del Sud, Australia". Ogni intervallo di testo che corrisponde all'input utente ha un attributokGMSAutocompleteMatchAttribute
. Puoi utilizzare questo attributo per evidenziare il testo corrispondente nella query dell'utente, ad esempio, come mostrato di seguito.placeID
: l'ID del luogo previsto. Un ID luogo è un identificatore testuale che identifica in modo univoco un luogo. Per ulteriori informazioni sugli ID luogo, consulta la panoramica ID luogo.distanceMeters
– La distanza in linea retta tra il valoreorigin
specificato e la destinazione. Se la proprietàorigin
non è impostata, non verrà restituito alcun valore di distanza.
Il seguente esempio di codice illustra come evidenziare in testo 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;
Utilizzare il fetcher
Se vuoi creare un controllo di completamento automatico da zero, puoi utilizzare GMSAutocompleteFetcher
, che aggrega il metodo autocompleteQuery
in GMSPlacesClient
.
Il fetcher limita le richieste, restituendo solo i risultati per il testo di ricerca inserito più di recente. Non fornisce elementi UI.
Per implementare GMSAutocompleteFetcher
, segui questi passaggi:
- Implementa il protocollo
GMSAutocompleteFetcherDelegate
. - Crea un oggetto
GMSAutocompleteFetcher
. - Chiama
sourceTextHasChanged
sul fetcher mentre l'utente digita. - Gestire previsioni ed errori utilizzando i metodi dei protocolli
didAutcompleteWithPredictions
edidFailAutocompleteWithError
.
Il seguente esempio di codice mostra l'utilizzo del fetcher per acquisire l'input utente e visualizzare le corrispondenze delle posizioni in una visualizzazione di testo. La funzionalità per selezionare un luogo
è stata omessa. FetcherSampleViewController
deriva da UIViewController
in fetchSampleViewController.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> #import <GoogleMapsBase/GoogleMapsBase.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 della ricerca con completamento automatico di un utente in una sessione discreta ai fini della 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 da una selezione di luoghi. Al termine di una sessione, il token non è più valido. L'app deve generare un nuovo token per ogni sessione. Consigliamo di utilizzare i token di sessione per tutte le sessioni di completamento automatico di pubblicità programmatica (quando utilizzi il controller a schermo intero o il controller dei risultati, l'API se ne occuperà automaticamente).
L'SDK Places per iOS utilizza un elemento GMSAutocompleteSessionToken
per identificare ogni sessione. L'app deve passare un nuovo token di sessione all'inizio di ogni nuova sessione, quindi trasmettere lo stesso token, insieme a un ID luogo, nella successiva chiamata a fetchPlacefromPlaceID:
per recuperare i Dettagli luogo relativi al luogo selezionato dall'utente.
Scopri di più sui token di sessione.
Utilizza il codice seguente 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 sui 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 l'attribuzione "Powered by Google" o comparire all'interno di una mappa con brand Google.
- Se la tua app utilizza il controllo UI di completamento automatico, non sono necessarie ulteriori azioni (l'attribuzione richiesta viene visualizzata per impostazione predefinita).
- Se recuperi e visualizzi informazioni aggiuntive sul luogo dopo aver ottenuto un luogo in base all'ID, devi mostrare anche le attribuzioni di terze parti.
Per ulteriori dettagli, consulta la documentazione sulle attribuzioni.
Controllo dell'indicatore dell'attività di rete
Per controllare l'indicatore dell'attività di rete nella barra di stato delle applicazioni, devi implementare i metodi di delega facoltativi 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 di delegadidRequestAutocompletePredictions:
edidUpdateAutocompletePredictions:
. - Per
GMSAutocompleteResultsViewController
devi implementare i metodi di delegadidRequestAutocompletePredictionsForResultsController:
edidUpdateAutocompletePredictionsForResultsController:
. - Per
GMSAutocompleteTableDataSource
devi implementare i metodi di delegadidRequestAutocompletePredictionsForTableDataSource:
edidUpdateAutocompletePredictionsForTableDataSource:
.
Se implementi questi metodi e se imposti [UIApplication sharedApplication].networkActivityIndicatorVisible
rispettivamente su YES
e NO
, la barra di stato corrisponderà correttamente all'UI di completamento automatico.
Limita risultati di completamento automatico
Puoi impostare il controllo UI di completamento automatico in modo da limitare i risultati a una regione geografica specifica e/o filtrare i risultati in base a uno o più tipi di luogo oppure a uno o più paesi specifici. Per limitare i risultati:
- Per preferire i risultati (bias) nella regione definita, imposta
locationBias
suGMSAutocompleteFilter
(alcuni risultati al di fuori della regione definita potrebbero comunque essere restituiti). Se è impostato anchelocationRestriction
,locationBias
verrà ignorato. Per mostrare (limitare) i risultati solo all'interno della regione definita, imposta
locationRestriction
suGMSAutocompleteFilter
(verranno restituiti solo i risultati all'interno della regione definita).- Nota: questa limitazione viene applicata solo a intere route; i risultati sintetici che si trovano al di fuori dei confini rettangolari possono essere restituiti in base a una route che si sovrappone alla limitazione di località.
Per restituire solo risultati conformi a un determinato tipo di luogo, imposta
types
suGMSAutocompleteFilter
(ad esempio, se specifichi TypeFilter.ADDRESS il widget restituirà solo risultati con un indirizzo preciso).Per restituire solo i risultati in un massimo di cinque paesi specificati, imposta
countries
suGMSAutocompleteFilter
.
Risultati della pregiudizio per una regione specifica
Per preferisci risultati (bias) nella regione definita, imposta locationBias
su GMSAutocompleteFilter
, come mostrato qui:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);
Limita i risultati a una regione specifica
Per mostrare (limitare) i risultati solo nella regione definita, imposta locationRestriction
su GMSAutocompleteFilter
, come mostrato qui:
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 qui:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
Filtra i risultati per tipo di luogo o raccolta del tipo
Limita i risultati in modo che siano di un certo tipo o una raccolta di tipi specifici impostando la proprietà types
di GMSAutoCompleteFilter
.
Utilizza questa proprietà per specificare i filtri elencati nelle tabelle 1, 2 e 3 per i tipi di luogo. Se non viene specificato nulla, vengono restituiti tutti i tipi.
Per specificare un tipo o un filtro per la raccolta del tipo:
Utilizza la proprietà
types
per specificare fino a cinque valori type della Tabella 1 e della Tabella 2 mostrati in Tipi di luogo. I valori del tipo sono definiti dalle costanti inGMSPlaceType
.Utilizza la proprietà
types
per specificare una raccolta di tipi dalla Tabella 3 mostrata in Tipi di luogo. I valori della raccolta di tipi sono definiti dalle costanti inGMSPlaceType
.Nella richiesta è consentito un solo tipo dalla tabella 3. Se specifichi un valore dalla tabella 3, non puoi specificarne uno dalla tabella 1 o dalla tabella 2. In questo caso, si verifica un errore.
Ad esempio, per restituire solo risultati conformi a un determinato tipo di luogo, imposta types
su GMSAutocompleteFilter
. L'esempio seguente mostra l'impostazione del filtro in modo che restituisca solo 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 utilizzare al meglio il servizio Place Autocomplete.
Di seguito sono riportate 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 dell'SDK Places per Android o il controllo dell'interfaccia utente di completamento automatico dell'SDK Places per iOS.
- Sviluppa una comprensione dei campi di dati essenziali di Place Autocomplete sin dall'inizio.
- I campi relativi alla differenziazione per località e alla limitazione della località sono facoltativi, ma possono avere un impatto significativo sulle prestazioni del completamento automatico.
- Utilizza la gestione degli errori per assicurarti che la tua app venga ridotta correttamente se l'API restituisce un errore.
- Assicurati che la tua app gestisca quando non c'è 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 di campo nei widget Place Details e Place Autocomplete per restituire solo i campi dei dati dei luoghi necessari.
Ottimizzazione dei costi avanzata
Prendi in considerazione l'implementazione programmatica di 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 (basati su sessione) se vengono soddisfatte entrambe le seguenti condizioni:
- Se hai bisogno solo della latitudine/longitudine o dell'indirizzo del luogo selezionato dall'utente, l'API Geocoding fornisce queste informazioni per meno di una chiamata Place Details.
- Se gli utenti selezionano una previsione di completamento automatico in una media di quattro richieste di previsioni di completamento automatico o meno, i prezzi per richiesta potrebbero essere più convenienti rispetto a quelli per sessione.
La tua applicazione richiede informazioni diverse dall'indirizzo e dalla latitudine/longitudine della previsione selezionata?
Sì, sono necessari ulteriori dettagli
Utilizza Place Autocomplete basato sulla sessione con Place Details.
Poiché la tua applicazione richiede Place Details, 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 (in modo programmatico o integrato nei widget JavaScript, Android o iOS) per un costo totale di $0, 017 per sessione oltre agli SKU di dati di Places applicabili in base ai campi di dati dei luoghi richiesti{/14.
Implementazione dei widget
La gestione delle sessioni è integrata automaticamente nei widget JavaScript, Android o iOS. Sono incluse sia le richieste Place Autocomplete sia la richiesta Place Details sulla previsione selezionata. Assicurati di specificare il parametro fields
per assicurarti di richiedere solo i campi dei dati del luogo necessari.
Implementazione programmatica
Utilizza un token sessione con le richieste di Place Autocomplete. Quando richiedi Place Details per la previsione selezionata, includi i seguenti parametri:
- L'ID luogo dalla risposta Place Autocomplete
- Il token di sessione utilizzato nella richiesta Place Autocomplete
- Il parametro
fields
che specifica i campi dati dei luoghi necessari
No, richiede solo indirizzo e posizione
L'API Geocoding potrebbe essere un'opzione più economica rispetto a Place Details per la tua applicazione, a seconda delle prestazioni dell'utilizzo di Place Autocomplete. L'efficienza di completamento automatico di ogni applicazione varia a seconda di ciò che gli utenti stanno inserendo, dove l'applicazione è in uso e se sono state implementate best practice per l'ottimizzazione delle prestazioni.
Per rispondere alla seguente domanda, analizza il numero di caratteri che un utente digita in media prima di selezionare una previsione di Place Autocomplete nella tua applicazione.
I tuoi utenti selezionano una previsione di Place Autocomplete in una media di quattro o meno richieste?
Sì
Implementa Place Autocomplete in modo programmatico senza token di sessione e chiama l'API Geocoding nella previsione della posizione selezionata.
L'API Geocoding fornisce indirizzi e coordinate di latitudine/longitudine al costo di 0,005 $per richiesta. Effettuare quattro richieste Place Autocomplete - Per Request costa $0,01132, quindi il costo totale di quattro richieste più una chiamata API Geocoding per la previsione del luogo selezionata sarebbe di $0,01632, che è inferiore al prezzo del completamento automatico per sessione di $0,017 per sessione.1
Valuta la possibilità di adottare best practice per il rendimento per aiutare gli utenti a ottenere le previsioni che cercano con ancora meno caratteri.
No
Utilizza Place Autocomplete basato sulla sessione con Place Details.
Poiché il numero medio di richieste che prevedi di effettuare prima che un utente selezioni una previsione di Place Autocomplete supera il costo dei prezzi per sessione, la tua implementazione di Place Autocomplete deve utilizzare un token di sessione sia per le richieste Place Autocomplete sia per la richiesta Place Details associata per 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 Place Autocomplete sia la richiesta Place Details sulla previsione selezionata. Assicurati di specificare il parametro fields
per avere la certezza di richiedere solo i campi Dati di base.
Implementazione programmatica
Utilizza un token sessione con le richieste di Place Autocomplete. Quando richiedi Place Details per la previsione selezionata, includi i seguenti parametri:
- L'ID luogo dalla risposta Place Autocomplete
- Il token di sessione utilizzato nella richiesta Place Autocomplete
- Il parametro
fields
che specifica i campi Dati di base, come l'indirizzo e la geometria
Valuta la possibilità di ritardare le richieste di Place Autocomplete
Puoi utilizzare strategie come il ritardo di una richiesta Place Autocomplete finché l'utente non ha digitato i primi tre o quattro caratteri, in modo che l'applicazione effettui meno richieste. Ad esempio, se l'utente effettua una richiesta di Place Autocomplete per ogni carattere dopo che l'utente ha digitato il terzo carattere, significa che se l'utente digita sette caratteri seleziona una previsione per la quale effettui una richiesta all'API Geocoding, il costo totale sarà di $0,01632 (4 * $0,00283 Autocomplete per richiesta + $0,005 Geocoding).1
Se con un ritardo le richieste la tua richiesta di pubblicità programmatica media risulta inferiore a quattro, puoi seguire le indicazioni per l'implementazione di Place Autocomplete con l'API Geocoding. Tieni presente che il ritardo delle richieste può essere percepito come latenza da parte dell'utente, il quale potrebbe aspettarsi di vedere le previsioni a ogni nuova sequenza di tasti.
Valuta la possibilità di adottare le best practice per il rendimento per aiutare gli utenti a ottenere le previsioni che cercano con meno caratteri.
-
I costi elencati qui sono espressi in dollari statunitensi. Per informazioni complete sui prezzi, consulta la pagina Fatturazione di Google Maps Platform.
Best practice per il rendimento
Le seguenti linee guida descrivono i modi per ottimizzare le prestazioni del completamento automatico di Place:
- Aggiungi restrizioni in base al paese, differenziazione per località e (per le implementazioni programmatiche) preferenze linguistiche all'implementazione di Place Autocomplete. La preferenza della lingua non è necessaria per i widget, perché questi ultimi scelgono la lingua dal browser o dal dispositivo mobile dell'utente.
- Se Place Autocomplete è accompagnato da una mappa, puoi differenziare la posizione in base alla visualizzazione della mappa.
- Nelle situazioni in cui un utente non sceglie una delle previsioni di completamento automatico, in genere perché nessuna di queste previsioni rappresenta l'indirizzo del risultato desiderato, puoi riutilizzare l'input utente originale per cercare di ottenere risultati più pertinenti:
- Se prevedi che l'utente inserisca solo informazioni sull'indirizzo, riutilizza l'input utente originale in una chiamata all'API Geocoding.
- Se prevedi che l'utente inserisca query per un luogo specifico per nome o indirizzo, utilizza una richiesta Trova luogo. Se i risultati sono previsti solo in una regione specifica, utilizza la differenziazione per località.
- Utenti che inseriscono indirizzi secondari in paesi in cui il supporto di Place Autocomplete per gli indirizzi secondari è incompleto, ad esempio Cechia, Estonia e Lituania. Ad esempio, l'indirizzo ceco "Stroupežnického 3191/17, Praha" fornisce una previsione parziale in Place Autocomplete.
- Gli utenti inseriscono gli indirizzi con prefissi del tratto di strada, ad esempio "23-30 29th St, Queens" a New York City o "47-380 Kamehameha Hwy, Kaneohe" sull'isola di Kauai alle Hawaii.
Risoluzione dei problemi
Sebbene possa verificarsi un'ampia gamma di errori, la maggior parte degli errori che è probabile che si verifichino nell'app sono di solito causati da errori di configurazione (ad esempio, è stata utilizzata una chiave API errata o la chiave API è stata configurata in modo errato) o da errori di quota (l'app ha superato la quota). Consulta Limiti di utilizzo per ulteriori informazioni sulle quote.
Gli errori che si verificano durante l'utilizzo dei controlli di completamento automatico vengono restituiti nel metodo didFailAutocompleteWithError()
dei vari protocolli delegati. La proprietà code
dell'oggetto NSError
fornito è impostata su uno dei valori dell'enumerazione GMSPlacesErrorCode
.