Place Autocomplete

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.
Seleziona piattaforma: Android iOS JavaScript Servizio web

Il servizio di completamento automatico nell'SDK Places per iOS restituisce le previsioni dei luoghi in risposta alle query di ricerca degli utenti. Durante la digitazione, il servizio di completamento automatico restituisce suggerimenti relativi a luoghi quali attività commerciali, indirizzi, plus code e punti di interesse.

Puoi aggiungere il completamento automatico alla tua app nei seguenti modi:

Aggiunta di un controllo di completamento automatico dell'interfaccia utente

Il controllo di completamento automatico dell'interfaccia utente è una finestra di dialogo di ricerca con funzionalità di completamento automatico integrate. Quando un utente inserisce 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 la tua app può utilizzare per ottenere i dettagli del luogo selezionato.

Puoi aggiungere il controllo di completamento automatico dell'interfaccia utente alla tua app nei modi indicati di seguito.

Aggiungere un controllo a schermo intero

Utilizza il controllo a schermo intero quando vuoi un contesto modale, in cui l'UI con 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:

  1. Crea un elemento UI nella tua app principale per avviare il controllo di completamento automatico dell'interfaccia utente, ad esempio un gestore touch su UIButton.
  2. Implementa il protocollo GMSAutocompleteViewControllerDelegate nel controller di vista principale.
  3. Crea un'istanza di GMSAutocompleteViewController e assegna il controller vista principale come proprietà delegata.
  4. Crea un GMSPlaceField per definire i tipi di dati del luogo da restituire.
  5. Aggiungere una GMSAutocompleteFilter per vincolare la query a un determinato tipo di luogo.
  6. Presenta la GMSAutocompleteViewController utilizzando [self presentViewController...].
  7. Gestisci la selezione dell'utente nel metodo delega didAutocompleteWithPlace.
  8. Ignora il controller nei metodi delegati didAutocompleteWithPlace, didFailAutocompleteWithError e wasCancelled.

L'esempio seguente mostra un possibile modo per avviare GMSAutocompleteViewController in risposta all'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

Aggiungere un controller dei risultati

Utilizza un controller dei risultati quando desideri un maggiore controllo sull'interfaccia utente di inserimento del testo. Il controller dei risultati attiva/disattiva dinamicamente la visibilità dell'elenco dei risultati in base all'elemento attivo dell'interfaccia utente.

Per aggiungere un controller dei risultati alla tua app:

  1. Crea una GMSAutocompleteResultsViewController.
  2. Implementa il protocollo GMSAutocompleteResultsViewControllerDelegate nel controller vista principale e assegna quest'ultimo come proprietà delegata.
  3. Crea un oggetto UISearchController, trasmettendo GMSAutocompleteResultsViewController come argomento del controller dei risultati.
  4. Imposta GMSAutocompleteResultsViewController come proprietà searchResultsUpdater di UISearchController.
  5. Aggiungi searchBar per UISearchController all'interfaccia utente della tua app.
  6. Gestisci la selezione dell'utente nel metodo delega didAutocompleteWithPlace.

Esistono diversi modi per inserire la barra di ricerca di UISearchController nell'interfaccia utente dell'app:

Aggiungere 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;
}

Aggiungere una barra di ricerca nella parte superiore di una vista

Il seguente esempio di codice 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 (questa opzione può essere disattivata). Nei casi in cui la barra di navigazione è 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;

Aggiungere una barra di ricerca utilizzando i risultati del popover

L'esempio di codice riportato di seguito mostra una barra di ricerca sul lato destro della barra di navigazione e mostra i 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'interfaccia utente di testo personalizzata, puoi utilizzare la classe GMSAutocompleteTableDataSource per aumentare la visualizzazione della tabella visualizzando i risultati sul controller di visualizzazione.

Per utilizzare GMSAutocompleteTableDataSource come origine dati e delegare della UITableView in un controller di visualizzazione:

  1. Implementa i protocolli GMSAutocompleteTableDataSourceDelegate e UISearchBarDelegate nel controller di visualizzazione.
  2. Crea un'istanza GMSAutocompleteTableDataSource e assegna il controller vista come proprietà delegata.
  3. Imposta GMSAutocompleteTableDataSource come proprietà dati e delega l'istanza UITableView sul controller di visualizzazione.
  4. Nel gestore per l'input di testo della ricerca, chiama sourceTextHasChanged sul GMSAutocompleteTableDataSource.
  5. Gestisci la selezione dell'utente nel metodo del delegato didAutocompleteWithPlace.
  6. Ignora il controller nei metodi delegati didAutocompleteWithPlace, didFailAutocompleteWithError e wasCancelled.

Il seguente esempio di codice mostra l'utilizzo della classe GMSAutocompleteTableDataSource per guidare 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

      

Personalizzare i colori del testo e dello sfondo

Puoi impostare i colori di tutto il testo e degli sfondi nel controllo di completamento automatico della UI, per fare in modo che il widget corrisponda in modo più preciso all'aspetto visivo della tua app. Esistono due modi per impostare i colori di controllo dell'interfaccia utente:

  • Se possibile, utilizza il protocollo UIUI nativo per iOS per definire in modo globale i controlli dell'interfaccia utente. Queste impostazioni si applicano a molti elementi di controllo UI, ma non a tutti.
  • Tramite i metodi SDK nelle classi dei widget per impostare le proprietà che non sono supportate dal protocollo UIUI.

In genere, la tua app utilizza una combinazione del protocollo UIUI e dei metodi dell'SDK. Il seguente diagramma mostra quali elementi possono avere uno stile:

Colori di controllo UI completamento automatico

Nella tabella che segue vengono elencati tutti gli elementi dell'interfaccia utente e viene indicato lo stile di ciascuno (protocollo UILook o metodo SDK).

Elemento UI Metodo Guida allo stile
Tinta della barra di navigazione (in background) Protocollo UIUI Chiama setBarTintColor sul proxy UINavigationBar.
Colore della barra di navigazione (accento del testo della barra di ricerca e pulsante Annulla) Protocollo UIUI Chiama setTintColor sul proxy UINavigationBar.
Colore testo barra di ricerca Protocollo UIUI Imposta NSForegroundColorAttributeName in searchBarTextAttributes.
Colore della barra di ricerca N/A La barra di ricerca è traslucida e viene visualizzata come versione ombreggiata della barra di navigazione.
Colore testo segnaposto barra della ricerca (testo predefinito della ricerca) Protocollo UIUI Imposta NSForegroundColorAttributeName in placeholderAttributes.
Testo principale (applicato anche a testo di errore e dei messaggi) Metodo SDK Chiama primaryTextColor.
Evidenziazione principale del testo Metodo SDK Chiama primaryTextHighlightColor.
Testo secondario Metodo SDK Chiama secondaryTextColor.
Errore e testo del messaggio Metodo SDK Chiama primaryTextColor.
Sfondo cella cella 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 UIUI Chiama setColor sul proxy UIActivityIndicatorView.
Logo "Powered by Google", immagine cloud triste N/A La versione bianca o grigia viene selezionata automaticamente in base al contrasto dello sfondo.
Lenti d'ingrandimento e icone di testo chiare nel campo di testo della barra di ricerca N/A Per applicare uno stile, sostituisci le immagini predefinite con immagini del colore desiderato.

Utilizzo del protocollo UI aspetti

Puoi utilizzare il protocollo UIUI per ottenere il proxy di aspetto per un determinato elemento della UI, che puoi poi utilizzare per impostare il colore dell'elemento. Quando viene apportata una modifica, tutte le istanze di un determinato elemento della UI sono interessate. Ad esempio, il seguente esempio a livello globale modifica il colore di testo delle classi UITextField in verde quando sono contenute in un elemento UISearchBar:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil]
    setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];

Per ulteriori informazioni sulla definizione dei valori dei colori, consulta la pagina Riferimento classe UIColor.

I seguenti snippet di codice mostrano tutti i comandi proxy che devi utilizzare per definire lo stile nel controllo di completamento automatico dell'interfaccia utente 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à degli stili di controllo dell'interfaccia utente

Un sottoinsieme di elementi di controllo dell'interfaccia utente ha proprietà che non sono interessate dal protocollo UIUI e devono quindi essere impostate direttamente. L'esempio di codice riportato di seguito mostra la definizione dei colori di sfondo e di primo piano 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 previsioni a livello di luogo in modo programmatico

Puoi creare una UI personalizzata di ricerca come alternativa a quella fornita dal widget di completamento automatico. Per farlo, la tua app deve ottenere le previsioni dei luoghi in modo programmatico. La tua app può ricevere un elenco di nomi e/o indirizzi di luoghi previsti nei seguenti modi:

Chiamo GMSPlacesClient findAutocompletePredictionsFromQuery:

Per ottenere un elenco di nomi e/o indirizzi di luoghi previsti, innanzitutto incentiva CLIENTPlaces, poi chiama il metodo GMSPlacesClient findAutocompletePredictionsFromQuery: con i seguenti parametri:

  • Una stringa autocompleteQuery contenente il testo digitato dall'utente.
  • Una GMSAutocompleteSessionToken, che viene utilizzata per identificare ogni singola sessione. L'app deve trasmettere lo stesso token per ogni chiamata con completamento automatico e poi trasmettere il token insieme a un ID luogo nella chiamata successiva a fetchPlacefromPlaceID: per recuperare i dettagli del luogo selezionati dall'utente.
  • Un GMSAutocompleteFilter per:
    • Evita o limita i risultati a una regione specifica.
    • Limita i risultati a un tipo di luogo specifico.
    • Un oggetto GMSPlaceLocationBias/Restriction tendenzialmente i risultati a 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 al numero 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, trasmettendo un array di oggetti GMSAutocompletePrediction.

Ogni oggetto GMSAutocompletePrediction contiene le seguenti informazioni:

  • attributedFullText: il testo completo della previsione, sotto forma di NSAttributedString. Ad esempio, "Sydney Opera House, Sydney, New SouthGalles, 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 del luogo previsto. L'ID luogo è un identificatore testuale che identifica in modo univoco un luogo. Per scoprire di più sugli ID luogo, consulta la panoramica sull'ID luogo.
  • distanceMeters: la distanza in linea retta dall'elemento origin specificato alla destinazione. Se la proprietà origin non è impostata, non verrà restituito alcun valore di distanza.

L'esempio di codice riportato di seguito illustra come evidenziare in grassetto le parti del risultato che corrispondono a 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 automatico di completamento da zero, puoi utilizzare GMSAutocompleteFetcher, che esegue il wrapping del metodo autocompleteQuery su GMSPlacesClient. Il fetcher limita le richieste, restituendo solo i risultati del testo di ricerca inserito più di recente. Non fornisce elementi dell'interfaccia utente.

Per implementare GMSAutocompleteFetcher, procedi nel seguente modo:

  1. Implementa il protocollo GMSAutocompleteFetcherDelegate.
  2. Crea un oggetto GMSAutocompleteFetcher.
  3. Chiama sourceTextHasChanged nel motore di recupero mentre l'utente digita.
  4. Gestire le previsioni e gli errori utilizzando i metodi del protocollo didAutcompleteWithPredictions e didFailAutocompleteWithError.

Il seguente esempio di codice mostra l'uso del fetcher per recuperare le corrispondenze tra l'input dell'utente e il luogo di visualizzazione in una visualizzazione di testo. La funzionalità di selezione di un luogo è stata omessa. FetcherSampleViewController deriva da UIViewController inFetchSampleViewController.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 di una ricerca con completamento automatico dell'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 un luogo. Al termine di una sessione, il token non è più valido. L'app deve generare un token aggiornato per ogni sessione. Ti consigliamo di utilizzare i token di sessione per tutte le sessioni di completamento automatico programmatico (quando usi il controller a schermo intero o il controller dei risultati, l'API lo gestisce automaticamente).

L'SDK Places per iOS utilizza una GMSAutocompleteSessionToken per identificare ogni sessione. L'app deve trasmettere un nuovo token di sessione all'inizio di ogni nuova sessione e trasmettere 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 di sessione.

Utilizza il codice seguente per generare un nuovo token di sessione:

let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

Limiti di utilizzo

Visualizzare le attribuzioni nell'app

  • Se la tua app utilizza il servizio di completamento automatico in modo programmatico, la tua UI deve mostrare un'attribuzione "Powered by Google" oppure comparire in una mappa con brand Google.
  • Se la tua app utilizza il controllo di completamento automatico dell'interfaccia utente non è necessaria alcuna azione aggiuntiva (l'attribuzione richiesta viene visualizzata per impostazione predefinita).
  • Se recuperi e mostri informazioni aggiuntive sul luogo dopo aver ricevuto un luogo in base all'ID, devi indicare anche le attribuzioni di terze parti.

Per ulteriori dettagli, consulta la documentazione sulle attribuzione.

Controllare l'indicatore di attività della rete

Per controllare l'indicatore di 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 l'indicatore di rete.

  • Per GMSAutocompleteViewController devi implementare i metodi delegati didRequestAutocompletePredictions: e didUpdateAutocompletePredictions:.
  • Per GMSAutocompleteResultsViewController devi implementare i metodi delegati didRequestAutocompletePredictionsForResultsController: e didUpdateAutocompletePredictionsForResultsController:.
  • Per GMSAutocompleteTableDataSource devi implementare i metodi delegati didRequestAutocompletePredictionsForTableDataSource: e didUpdateAutocompletePredictionsForTableDataSource:.

Implementando questi metodi e impostando [UIApplication sharedApplication].networkActivityIndicatorVisible rispettivamente su YES e NO, la barra di stato corrisponderà alla UI del completamento automatico.

Limita risultati del completamento automatico

Puoi impostare il controllo dell'interfaccia utente di completamento automatico per vincolare i risultati a una regione geografica specifica e/o filtrare i risultati per uno o più tipi di luoghi o per un paese o paesi specifici. Per limitare i risultati, puoi procedere come segue:

  • Per preferire i risultati (bias) all'interno dell'area geografica definita, imposta locationBias su GMSAutocompleteFilter (alcuni risultati provenienti dall'esterno dell'area geografica definita potrebbero comunque essere restituiti). Se viene impostato anche locationRestriction, locationBias verrà ignorato.
  • Per mostrare solo (limitare) i risultati all'interno dell'area geografica definita, imposta locationRestriction in GMSAutocompleteFilter (verranno restituiti solo i risultati all'interno dell'area geografica).

    • Nota: questa restrizione si applica solo a interi percorsi. I risultati sintetici che si trovano al di fuori dei confini rettangolari possono essere restituiti in base a un percorso che si sovrappone alla limitazione di località.
  • Per restituire solo i risultati che corrispondono a un determinato tipo di luogo, imposta type su GMSAutocompleteFilter (ad esempio, se specifichi TypeFilter.ADDRESS), il widget restituirà solo risultati con un indirizzo preciso.

  • Per restituire solo risultati entro un massimo di cinque paesi specificati, imposta countries su GMSAutocompleteFilter.

Differenzia i risultati per una regione specifica

Per preferire (bias) i risultati all'interno dell'area geografica 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);

Limita i risultati a un'area geografica specifica

Per mostrare solo (limitare) i risultati all'interno dell'area geografica 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 entro 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 dei tipi

Limita i risultati in un determinato tipo o raccolta per tipo impostando la proprietà types di GMSAutoCompleteFilter. Utilizza questa proprietà per specificare i filtri elencati nelle tabelle 1, 2 e 3 di Tipi di luogo. Se non viene specificato alcun valore, vengono restituiti tutti i tipi.

Per specificare un tipo o un filtro di raccolta:

  • Utilizza la proprietà types per specificare fino a cinque valori type nella tabella 1 e nella tabella 2 mostrati in Place types (Tipi di luogo). I valori del tipo sono definiti dalle costanti in GMSPlaceType.

  • Utilizza la proprietà types per specificare una raccolta di tipi dalla tabella 3 mostrata in Tipi di luogo. I valori della raccolta dei tipi sono definiti dalle costanti in GMSPlaceType.

    È consentito un solo tipo di tabella 3. Se specifichi un valore della tabella 3, non puoi specificarne uno dalla tabella 1 o 2. In caso contrario, si verifica un errore.

Ad esempio, per restituire solo risultati corrispondenti a un determinato tipo di luogo, imposta types su GMSAutocompleteFilter. L'esempio seguente mostra come impostare il filtro in modo che restituisca solo i risultati con un indirizzo preciso:

  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];

Effettua l'ottimizzazione di completamento automatico

Questa sezione descrive le best practice per aiutarti a ottenere il massimo dal 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 per Android o il controllo interfaccia utente di completamento automatico di Places per iOS
  • Sviluppa una comprensione iniziale dei campi di dati di completamento automatico del luogo.
  • I campi di differenziazione della posizione e di limitazione della località sono facoltativi, ma possono avere un impatto significativo sulle prestazioni del completamento automatico.
  • Utilizza la gestione degli errori per assicurarti che l'app venga ridotta correttamente se l'API restituisce un errore.
  • Assicurati che la tua app sia gestita quando non è presente 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 di campo nei widget Place Details e Place Autocomplete per restituire solo i campi di dati dei luoghi necessari.

Ottimizzazione avanzata dei costi

Valuta la possibilità di implementare il completamento automatico dei luoghi per poter accedere ai prezzi per richiesta e richiedere i risultati dell'API Geocoding anziché i dettagli del luogo selezionato. I prezzi per richiesta abbinati all'API Geocoding sono più efficaci rispetto ai prezzi per sessione (basati su sessione) se vengono soddisfatte entrambe le seguenti condizioni:

  • Se ti serve soltanto la latitudine/longitudine o l'indirizzo del luogo selezionato dell'utente, l'API Geocoding fornisce queste informazioni a meno di una chiamata Dettagli luogo.
  • Se gli utenti selezionano una previsione di completamento automatico entro una media di quattro richieste di completamento automatico o meno, il prezzo per richiesta potrebbe essere più conveniente rispetto al prezzo per sessione.
Per assistenza nella scelta dell'implementazione di Place Autocomplete in base alle tue esigenze, seleziona la scheda che corrisponde alla tua risposta alla seguente domanda.

La tua applicazione richiede informazioni diverse dall'indirizzo e dalla latitudine/longitudine della previsione selezionata?

Sì, sono necessari ulteriori dettagli

Utilizza il completamento automatico dei luoghi basato sulla sessione con i dettagli del luogo.
Poiché la tua applicazione richiede dettagli relativi al luogo, come il nome del luogo, lo stato dell'attività o l'orario di apertura, l'implementazione del completamento automatico del luogo 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 più SKU di dati dei luoghi 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. Ciò include sia le richieste di completamento automatico del luogo sia la richiesta Dettagli luogo nella previsione selezionata. Assicurati di specificare il parametro fields per assicurarti di richiedere solo i campi di dati sui luoghi necessari.

Implementazione programmatica
Utilizza un token di sessione con le richieste di completamento automatico dei lavori in corso. Quando richiedi i dettagli del luogo relativi alla previsione selezionata, includi i seguenti parametri:

  1. L'ID luogo dalla risposta di completamento automatico del luogo
  2. Il token di sessione utilizzato nella richiesta di completamento automatico del luogo
  3. Il parametro fields che specifica i campi di dati dei luoghi necessari

No, richiede solo l'indirizzo e la località

L'API Geocoding potrebbe essere un'opzione più conveniente rispetto a Place Details per la tua applicazione, a seconda delle prestazioni dell'utilizzo del completamento automatico di Place. L'efficienza del completamento automatico di ogni applicazione varia a seconda dei dati per cui gli utenti accedono al programma, della località in cui viene utilizzata e se sono state implementate best practice per l'ottimizzazione delle prestazioni.

Per rispondere alla seguente domanda, analizza la quantità di caratteri digitata da un utente prima di selezionare una previsione di completamento automatico del posizionamento nella tua applicazione.

In media, gli utenti selezionano una previsione di completamento automatico del luogo in quattro richieste o meno?

Implementa Place Autocomplete in modo programmatico senza token di sessione e chiama l'API Geocoding sulla previsione di luoghi selezionata.
L'API Geocoding fornisce indirizzi e coordinate di latitudine/longitudine a 0,005 $per richiesta. L'esecuzione di quattro richieste Place Autocomplete - Per Request costa 0,01132 $, quindi il costo totale di quattro richieste più una chiamata Geocoding API sulla previsione di luoghi selezionata sarà 0,01632 $, che è inferiore al prezzo di completamento automatico per sessione di 0,017 $per sessione.1

Valuta la possibilità di utilizzare le best practice relative alle prestazioni per aiutare gli utenti a ottenere la previsione che cercano in una quantità ancora inferiore di caratteri.

No

Utilizza il completamento automatico dei luoghi basato sulla sessione con i dettagli del luogo.
Poiché il numero medio di richieste che dovresti effettuare prima che un utente selezioni una previsione di completamento automatico del luogo che supera il costo dei prezzi per sessione, la tua implementazione del completamento automatico del luogo dovrebbe utilizzare un token di sessione sia per le richieste di completamento automatico del luogo sia per la richiesta Dettagli luogo 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. Ciò include sia le richieste di completamento automatico del luogo sia la richiesta Dettagli luogo nella 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 di completamento automatico dei lavori in corso. Quando richiedi i dettagli del luogo relativi alla previsione selezionata, includi i seguenti parametri:

  1. L'ID luogo dalla risposta di completamento automatico del luogo
  2. Il token di sessione utilizzato nella richiesta di completamento automatico del luogo
  3. Il parametro fields che specifica i campi Dati di base, ad esempio indirizzo e geometria

Ritardo delle richieste di completamento automatico dei luoghi
Puoi utilizzare strategie per ritardare una richiesta di completamento automatico dei luoghi finché l'utente non ha digitato i primi tre o quattro caratteri, in modo che l'applicazione effettui un numero inferiore di richieste. Ad esempio, effettuando richieste di completamento automatico del posizionamento per ogni carattere dopo che l'utente ha digitato il terzo carattere, significa che se l'utente digita sette caratteri e poi seleziona una previsione per la quale si effettua una richiesta API Geocoding, il costo totale sarà pari a $0,01632 (4 * $0,00283 completamento automatico per richiesta + $0,005 geocodifica).1

Se le richieste in ritardo possono raggiungere un numero medio di richieste di pubblicità programmatica inferiore a quattro, puoi seguire le indicazioni per l'implementazione del completamento automatico dei luoghi con API Geocoding. Tieni presente che le richieste ritardate possono essere percepite come latenza dall'utente, che può aspettarsi di vedere le previsioni a ogni nuova sequenza di tasti.

Valuta la possibilità di utilizzare le best practice relative alle prestazioni per aiutare gli utenti a ottenere la previsione che cercano in un numero inferiore di caratteri.


  1. I costi elencati qui sono in dollari statunitensi. Consulta la pagina Fatturazione di Google Maps Platform per informazioni complete sui prezzi.

Best practice per il rendimento

Le seguenti linee guida descrivono i modi per ottimizzare il rendimento del completamento automatico dei luoghi:

  • Aggiungi limitazioni in base al paese, targeting per località e (per implementazioni programmatiche) le preferenze di lingua per l'implementazione di Place Autocomplete. La preferenza della lingua non è necessaria con i widget perché scelgono le preferenze relative alla lingua dal browser o dal dispositivo mobile dell'utente.
  • Se il completamento automatico del luogo è accompagnato da una mappa, puoi bias la posizione in base all'area visibile della mappa.
  • Nelle situazioni in cui un utente non sceglie una delle previsioni del completamento automatico, in genere perché nessuna di queste previsioni è l'indirizzo dei risultati desiderato, puoi riutilizzare l'input originale dell'utente per tentare di ottenere risultati più pertinenti:
    • Se prevedi che l'utente debba inserire solo informazioni relative all'indirizzo, puoi riutilizzare l'input utente originale durante una chiamata all'API Geocoding.
    • Se prevedi che l'utente inserisce query per un luogo specifico in base al nome o all'indirizzo, utilizza una richiesta Trova luogo. Se i risultati sono previsti solo in una regione specifica, utilizza la ponderazione della posizione.
    Altri scenari in cui è meglio utilizzare l'API Geocoding sono:
    • Gli utenti che inseriscono indirizzi di sottopreside in paesi in cui il supporto del completamento automatico degli indirizzi di pre-completamento è incompleto, ad esempio Cechia, Estonia e Lituania. Ad esempio, l'indirizzo ceco "Stroupežnického 3191/17, Praga" genera una previsione parziale nel completamento automatico del luogo.
    • Utenti che inseriscono indirizzi con prefissi del tratto di strada come "23-30 29th St, Queens" a New York City o "47-380 Kamehameha Hwy, Kaneohe" sull'isola di Kauai alle Hawaii.

Risoluzione dei problemi

Anche se è probabile che si verifichi un'ampia varietà di errori, è probabile che la maggior parte degli errori riscontrati dalla tua app sia dovuta a errori di configurazione (ad esempio se è stata usata la chiave API errata o è stata configurata in modo errato) o a errori di quota (la tua app ha superato la quota). Consulta la pagina relativa ai 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 di GMSPlacesErrorCode.