Autouzupełnianie miejsc

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Usługa autouzupełniania w pakiecie Places SDK dla iOS zwraca prognozy w odpowiedzi na zapytania użytkowników. Gdy użytkownik wprowadza typ, usługa autouzupełniania zwraca sugestie miejsc, takich jak firmy, adresy, kody Plus Code i ciekawe miejsca.

Autouzupełnianie możesz dodać do aplikacji na kilka sposobów:

Dodawanie opcji autouzupełniania w interfejsie

Element sterujący autouzupełniania w oknie wyszukiwania to wbudowana funkcja autouzupełniania. Gdy użytkownik wpisuje wyszukiwane hasło, element sterujący wyświetla listę przewidywanych miejsc do wyboru. Gdy użytkownik dokona wyboru, zostanie zwrócone wystąpienie GMSPlace, którego aplikacja może następnie użyć do uzyskania szczegółowych informacji o tym miejscu.

Autouzupełnianie w interfejsie aplikacji możesz włączyć na te sposoby:

Dodawanie elementu sterującego na pełnym ekranie

Jeśli chcesz uzyskać kontekst modalny, użyj elementów pełnoekranowych, w którym interfejs autouzupełniania tymczasowo zastępuje interfejs aplikacji, dopóki użytkownik nie dokona wyboru. Ta funkcja jest udostępniana przez klasę GMSAutocompleteViewController. Gdy użytkownik wybierze miejsce, aplikacja oddzwoni.

Aby dodać element pełnoekranowy do aplikacji:

  1. Utwórz element interfejsu w swojej głównej aplikacji, by uruchomić autouzupełnianie w interfejsie – np. moduł dotykowy na urządzeniu UIButton.
  2. Wdróż protokół GMSAutocompleteViewControllerDelegate w kontrolerze widoku nadrzędnego.
  3. Utwórz instancję GMSAutocompleteViewController i przypisz nadrzędny kontroler widoku jako właściwość z przekazywaniem dostępu.
  4. Utwórz GMSPlaceField, aby określić typy danych miejsc do zwrócenia.
  5. Dodaj GMSAutocompleteFilter, aby ograniczyć zapytanie do określonego typu miejsca.
  6. Wyświetl GMSAutocompleteViewController za pomocą [self presentViewController...].
  7. Skonfiguruj wybór użytkownika za pomocą metody przekazywania didAutocompleteWithPlace.
  8. Zamknij kontroler w metodach didAutocompleteWithPlace, didFailAutocompleteWithError i wasCancelled przedstawicieli.

Poniższy przykład pokazuje jeden ze sposobów uruchomienia GMSAutocompleteViewController w odpowiedzi na kliknięcie przycisku.

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

Dodawanie kontrolera wyników

Jeśli chcesz uzyskać większą kontrolę nad interfejsem wprowadzania tekstu, użyj kontrolera wyników. Kontroler wyników dynamicznie przełącza widoczność listy wyników na podstawie zaznaczenia interfejsu użytkownika.

Aby dodać kontroler wyników do aplikacji:

  1. Utwórz GMSAutocompleteResultsViewController.
  2. Zaimplementuj protokół GMSAutocompleteResultsViewControllerDelegate w kontrolerze widoku nadrzędnego i przypisz nadrzędny kontroler widoku jako właściwość z przekazywaniem dostępu.
  3. Utwórz obiekt UISearchController, przekazując argument GMSAutocompleteResultsViewController jako argument kontrolera wyników.
  4. Ustaw GMSAutocompleteResultsViewController jako właściwość searchResultsUpdater elementu UISearchController.
  5. Dodaj searchBar dla UISearchController w interfejsie aplikacji.
  6. Skonfiguruj wybór użytkownika za pomocą metody przekazywania didAutocompleteWithPlace.

Pasek wyszukiwania usługi UISearchController możesz umieścić w interfejsie aplikacji na kilka sposobów:

Dodawanie paska wyszukiwania do paska nawigacyjnego

Poniższy przykład kodu pokazuje, jak dodać kontroler wyników, dodać searchBar do paska nawigacyjnego i obsługiwać wybór użytkownika:

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

Dodawanie paska wyszukiwania na górze widoku

W poniższym przykładowym kodzie widać searchBar w górnej części widoku.

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

Domyślnie UISearchController ukrywa pasek nawigacyjny podczas prezentacji (ten widok można wyłączyć). Jeśli pasek nawigacyjny jest niewidoczny, UISearchController nie ustawia go prawidłowo.

Aby obejść ten problem, użyj tego kodu:

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;

Dodawanie paska wyszukiwania za pomocą wyskakujących okienek

Poniższy przykład kodu pokazuje, jak umieścić pasek wyszukiwania po prawej stronie paska nawigacyjnego i wyświetlać wyniki w wyskakującym okienku.

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

Korzystanie ze źródła danych tabeli

Jeśli Twoja aplikacja ma własny interfejs tekstowy wyszukiwania, możesz użyć klasy GMSAutocompleteTableDataSource, aby wyświetlić widok tabeli z wynikami w kontrolerze widoku.

Aby używać GMSAutocompleteTableDataSource jako źródła danych i przedstawiciela UITableView w kontrolerze widoku:

  1. Zaimplementuj protokoły GMSAutocompleteTableDataSourceDelegate i UISearchBarDelegate w kontrolerze widoku.
  2. utworzyć instancję GMSAutocompleteTableDataSource i przypisać kontroler widoku jako właściwość z przekazywaniem dostępu;
  3. Ustaw GMSAutocompleteTableDataSource jako źródło danych i właściwości przekazywania instancji UITableView w kontrolerze widoku.
  4. W module obsługi wprowadzania tekstu wyszukiwania wywołaj funkcję sourceTextHasChanged w elemencie GMSAutocompleteTableDataSource.
  5. Skonfiguruj wybór użytkownika w metodzie przekazywania dostępu didAutocompleteWithPlace.
  6. Zamknij kontroler w metodach z przekazywaniem uprawnień didAutocompleteWithPlace, didFailAutocompleteWithError i wasCancelled.

Ten przykładowy kod pokazuje, jak używać klasy GMSAutocompleteTableDataSource do wyświetlania widoku tabeli UIViewController, gdy właściwość UISearchBar jest dodawana oddzielnie.

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

      

Dostosowywanie kolorów tekstu i tła

Możesz dostosować kolory całego tekstu i tła, korzystając z opcji autouzupełniania w interfejsie, aby widżet lepiej pasował do wyglądu aplikacji. Kolory interfejsu UI możesz ustawić na 2 sposoby:

  • Przez wykorzystanie natywnego protokołu UI w iOS do globalnego kontrolowania elementów interfejsu w miarę możliwości. Te ustawienia mają zastosowanie do wielu elementów, ale nie do wszystkich elementów interfejsu.
  • Używając metod pakietu SDK w klasach widżetów, aby skonfigurować właściwości nieobsługiwane przez protokół UI.

Zazwyczaj aplikacja korzysta z kombinacji protokołu UI i metod pakietu SDK. Ten diagram pokazuje, które elementy można stylizować:

Autouzupełnianie kolorów sterujących interfejsu

Poniższa tabela zawiera listę wszystkich elementów interfejsu oraz sposób określania stylu każdego z nich (protokół UI, metoda SDK).

Element interfejsu Metoda Poradniki i styl
Odcień paska nawigacji (w tle) Protokół UILook Zadzwoń pod numer setBarTintColor na serwerze proxy UINavigationBar.
Kolor odcienia paska nawigacji (wskaźnik tekstu na pasku wyszukiwania i przycisk Anuluj) Protokół UILook Zadzwoń pod numer setTintColor na serwerze proxy UINavigationBar.
Kolor tekstu paska wyszukiwania Protokół UILook Ustaw NSForegroundColorAttributeName w searchBarTextAttributes.
Kolor odcienia paska wyszukiwania Nie dotyczy Pasek wyszukiwania jest półprzezroczysty i wyświetla się w zacienionej wersji paska nawigacyjnego.
Kolor tekstu zastępczego na pasku wyszukiwania (domyślny tekst wyszukiwania) Protokół UILook Ustaw NSForegroundColorAttributeName w placeholderAttributes.
Tekst główny (również stosowany do tekstu błędu i komunikatu) Metoda pakietu SDK Zadzwoń do firmy primaryTextColor.
Wyróżnienie głównego tekstu Metoda pakietu SDK Zadzwoń do firmy primaryTextHighlightColor.
Tekst dodatkowy Metoda pakietu SDK Zadzwoń do firmy secondaryTextColor.
Błąd i tekst wiadomości Metoda pakietu SDK Zadzwoń do firmy primaryTextColor.
Tło komórki tabeli Metoda pakietu SDK Zadzwoń do firmy tableCellBackgroundColor.
Kolor separatora komórek tabeli Metoda pakietu SDK Zadzwoń do firmy tableCellSeparatorColor.
Przycisk „Spróbuj ponownie” Metoda pakietu SDK Zadzwoń do firmy tintColor.
Wskaźnik aktywności (wskaźnik postępu) Protokół UILook Zadzwoń pod numer setColor na serwerze proxy UIActivityIndicatorView.
Logo „Powered by Google”, smutny obraz chmury Nie dotyczy Wersja biała lub szara jest wybierana automatycznie na podstawie kontrastu tła.
Ikony lupy i czystego tekstu w polu tekstowym paska wyszukiwania Nie dotyczy Styl możesz zastąpić domyślnymi obrazami.

Korzystanie z protokołu UILook

Aby uzyskać pomoc dotyczącą wyglądu określonego elementu interfejsu, możesz użyć protokołu UI, który następnie pozwala ustawić kolor elementu interfejsu. Wprowadzenie zmian ma wpływ na wszystkie wystąpienia danego elementu interfejsu użytkownika. Na przykład ten przykład globalnie zmienia kolor tekstu klas UITextField na zielony, jeśli znajdują się one w tagu UISearchBar:

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

Więcej informacji o definiowaniu wartości kolorów znajdziesz w dokumentacji klasy UIUI.

Poniższe fragmenty kodu zawierają wszystkie polecenia serwera proxy, których musisz użyć, aby dodać styl do całego interfejsu autouzupełniania w interfejsie. Dodaj ten kod do metody didFinishLaunchingWithOptions w 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;

Ustawianie właściwości stylu elementu sterującego interfejsu użytkownika

Część elementów sterujących interfejsu ma właściwości, na które nie wpływa protokół UILook, dlatego należy je ustawić bezpośrednio. Poniższy przykład kodu pokazuje, jak definiować kolory pierwszego planu i tła oraz stosować je do elementu sterującego interfejsu o nazwie acController. Dodaj ten kod do metody onLaunchClicked w metodzie 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;

Automatyczne prognozowanie miejsc

Zamiast interfejsu dostarczonego przez widżet autouzupełniania możesz utworzyć własny interfejs wyszukiwania. Aby to zrobić, aplikacja musi automatycznie generować prognozy miejsc. Aplikacja może uzyskać listę przewidywanych nazw miejsc lub adresów na jeden z tych sposobów:

Dzwonię do: GMSPlacesClient findAutocompletePredictionsFromQuery:

Aby uzyskać listę prognozowanych nazw lub adresów miejsc, najpierw zintegruj GMSPlacesClient, a następnie wywołaj metodę GMSPlacesClient findAutocompletePredictionsFromQuery: z tymi parametrami:

  • Ciąg tekstowy autocompleteQuery zawierający tekst wpisany przez użytkownika.
  • GMSAutocompleteSessionToken, który służy do identyfikowania każdej sesji. Aplikacja powinna przekazywać ten sam token przy każdym wywołaniu żądania autouzupełniania, a następnie przekazywać ten token wraz z identyfikatorem miejsca w kolejnym wywołaniu fetchPlacefromPlaceID:, aby pobrać szczegóły miejsca wybranego przez użytkownika.
  • GMSAutocompleteFilter na:
    • Ogranicz wyniki lub ogranicz wyniki do określonego regionu.
    • Ogranicz wyniki do określonego typu miejsca.
    • Obiekt GMSPlaceLocationBias/ograniczenie ogranicza wyniki do określonego obszaru określonego przez szerokość i długość geograficzną.
  • Metoda wywołania zwrotnego umożliwiająca obsługę zwróconych prognoz.

Te przykładowe fragmenty kodu wywołują wywołanie 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);
    }
  }
}];

Interfejs API wywołuje określoną metodę wywołania zwrotnego, przekazując tablicę obiektów GMSAutocompletePrediction.

Każdy obiekt GMSAutocompletePrediction zawiera te informacje:

  • attributedFullText – pełny tekst prognozy w formacie NSAttributedString. Na przykład „Sydney Opera House, Sydney, Nowa Południowa Walia, Australia”. Każdy zakres tekstowy pasujący do danych wejściowych użytkownika ma atrybut kGMSAutocompleteMatchAttribute. Możesz go użyć do podświetlenia pasującego tekstu w zapytaniu użytkownika, na przykład poniżej.
  • placeID – identyfikator miejsca z prognozowanego miejsca. Identyfikator miejsca to identyfikator tekstowy, który jednoznacznie identyfikuje miejsce. Więcej informacji o identyfikatorach miejsc znajdziesz w artykule Omówienie identyfikatorów miejsc.
  • distanceMeters – linia pionowa od podanego origin do miejsca docelowego. Jeśli właściwość origin nie jest ustawiona, wartość odległości nie jest zwracana.

Poniższy przykład kodu ilustruje, jak za pomocą enumerateAttribute wyróżniać pogrubione fragmenty tekstu pasującego do zapytania użytkownika.

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;
    

Korzystanie z modułu pobierania

Jeśli chcesz utworzyć własną opcję autouzupełniania od podstaw, możesz użyć narzędzia GMSAutocompleteFetcher, które otacza metodę autocompleteQuery w GMSPlacesClient. Moduł pobierania ogranicza liczbę żądań, wyświetlając tylko wyniki dotyczące ostatnio wprowadzonego tekstu. Nie zawiera elementów interfejsu.

Aby wdrożyć GMSAutocompleteFetcher, wykonaj te czynności:

  1. Zaimplementuj protokół GMSAutocompleteFetcherDelegate.
  2. Utwórz obiekt GMSAutocompleteFetcher.
  3. Wywołaj sourceTextHasChanged w module pobierania, gdy użytkownik wpisuje tekst.
  4. Obsługiwanie prognoz i błędów przy użyciu metod didAutcompleteWithPredictions i didFailAutocompleteWithError.

Poniższy przykład kodu pokazuje, jak za pomocą modułu pobierania pobrać dane użytkownika o dopasowaniu do miejsca i wyświetlić je w widoku tekstowym. Funkcja wyboru miejsca została pominięta. FetcherSampleViewController pochodzi z UIViewController w FetcherSampleViewController.h.

Swift

import UIKit
import GooglePlaces

class ViewController: UIViewController {

  var textField: UITextField?
  var resultText: UITextView?
  var fetcher: GMSAutocompleteFetcher?

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .white
    edgesForExtendedLayout = []

    // Set bounds to inner-west Sydney Australia.
    let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366,
                                                longitude: 151.134002)
    let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725,
                                                longitude: 151.200349)

    // Set up the autocomplete filter.
    let filter = GMSAutocompleteFilter()
    filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner)

    // Create a new session token.
    let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

    // Create the fetcher.
    fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter)
    fetcher?.delegate = self
    fetcher?.provide(token)

    textField = UITextField(frame: CGRect(x: 5.0, y: 10.0,
                                          width: view.bounds.size.width - 5.0,
                                          height: 64.0))
    textField?.autoresizingMask = .flexibleWidth
    textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)),
                         for: .editingChanged)
    let placeholder = NSAttributedString(string: "Type a query...")

    textField?.attributedPlaceholder = placeholder

    resultText = UITextView(frame: CGRect(x: 0, y: 65.0,
                                          width: view.bounds.size.width,
                                          height: view.bounds.size.height - 65.0))
    resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
    resultText?.text = "No Results"
    resultText?.isEditable = false

    self.view.addSubview(textField!)
    self.view.addSubview(resultText!)
  }

  @objc func textFieldDidChange(textField: UITextField) {
    fetcher?.sourceTextHasChanged(textField.text!)
  }

}

extension ViewController: GMSAutocompleteFetcherDelegate {
  func didAutocomplete(with predictions: [GMSAutocompletePrediction]) {
    let resultsStr = NSMutableString()
    for prediction in predictions {
      resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText)
      resultsStr.appendFormat("Place ID: %@\n", prediction.placeID)
    }

    resultText?.text = resultsStr as String
  }

  func didFailAutocompleteWithError(_ error: Error) {
    resultText?.text = error.localizedDescription
  }
}

Objective-C

#import "FetcherSampleViewController.h"
#import <GooglePlaces/GooglePlaces.h>
#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

Tokeny sesji

Tokeny sesji grupują fazy zapytania i wyboru w autouzupełnianiu wyszukiwań użytkowników w osobne sesje do celów rozliczeniowych. Sesja rozpoczyna się, gdy użytkownik zacznie wpisywać zapytanie, a kończy, gdy wybierze miejsce. Każda sesja może zawierać wiele zapytań z 1 wybranym miejscem. Po zakończeniu sesji token jest nieważny – aplikacja musi wygenerować nowy token dla każdej sesji. Zalecamy używanie tokenów sesji dla wszystkich zautomatyzowanych sesji autouzupełniania (gdy używasz kontrolera pełnoekranowego lub kontrolera wyników, interfejs API zajmuje się tym automatycznie).

Pakiet SDK Miejsc na iOS używa modułu GMSAutocompleteSessionToken do identyfikowania każdej sesji. Po rozpoczęciu każdej nowej sesji aplikacja powinna przekazać nowy token sesji, a potem ten sam token wraz z identyfikatorem miejsca w kolejnym wywołaniu fetchPlacefromPlaceID:. Dzięki temu uzyskasz szczegółowe informacje o miejscu wybranym przez użytkownika.

Więcej informacji o tokenach sesji

Aby wygenerować nowy token sesji, użyj tego kodu:

let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

Limity wykorzystania

Wyświetlanie atrybucji w aplikacji

  • Jeśli Twoja aplikacja korzysta z usługi autouzupełniania w sposób zautomatyzowany, Twój interfejs użytkownika musi wyświetlać atrybucję „Technologia Google” lub być widoczny na mapie marki Google.
  • Jeśli Twoja aplikacja korzysta z funkcji autouzupełniania w interfejsie użytkownika, nie jest wymagane żadne dodatkowe działanie (jest ona wyświetlana domyślnie).
  • Jeśli po uzyskaniu identyfikatora według miejsca pobierasz i wyświetlasz dodatkowe informacje o miejscu, musisz też podać atrybucję firm zewnętrznych.

Więcej informacji znajdziesz w dokumentacji dotyczącej atrybucji.

Kontrolowanie wskaźnika aktywności sieci

Aby kontrolować wskaźnik aktywności w sieci na pasku stanu aplikacji, musisz wdrożyć odpowiednie opcjonalne metody przekazywania dostępu do używanej klasy autouzupełniania, a następnie samodzielnie włączyć lub wyłączyć ten wskaźnik.

  • W przypadku GMSAutocompleteViewController musisz zastosować metody przekazywania didRequestAutocompletePredictions: i didUpdateAutocompletePredictions:.
  • W przypadku GMSAutocompleteResultsViewController musisz zastosować metody przekazywania didRequestAutocompletePredictionsForResultsController: i didUpdateAutocompletePredictionsForResultsController:.
  • W przypadku GMSAutocompleteTableDataSource musisz zastosować metody przekazywania didRequestAutocompletePredictionsForTableDataSource: i didUpdateAutocompletePredictionsForTableDataSource:.

Jeśli zastosujesz te metody i ustawisz [UIApplication sharedApplication].networkActivityIndicatorVisible na YES i NO, pasek stanu będzie poprawnie pasował do interfejsu autouzupełniania.

Ograniczanie wyników autouzupełniania

Możesz ustawić opcję autouzupełniania w celu ograniczenia wyników do określonego regionu geograficznego lub filtrowanie ich według jednego lub kilku typów miejsc albo dla określonego kraju lub kraju. Aby ograniczyć wyniki, możesz wykonać te czynności:

  • Aby preferować (odchylenia) w określonym regionie, ustaw locationBias na GMSAutocompleteFilter (niektóre wyniki spoza tego regionu mogą wciąż być zwracane). Jeśli zasada locationRestriction jest również ustawiona, locationBias jest ignorowana.
  • Aby wyświetlać tylko wyniki (ograniczenie) z określonego regionu, ustaw locationRestriction na GMSAutocompleteFilter (zostaną zwrócone tylko wyniki z określonego regionu).

    • Uwaga: to ograniczenie jest stosowane tylko do całych tras. Wyniki syntetyczne położone poza prostokątnymi granicami mogą być zwracane na podstawie trasy pokrywającej się z ograniczeniami lokalizacji.
  • Aby wyświetlić tylko wyniki zgodne z konkretnym typem miejsca, ustaw type w polu GMSAutocompleteFilter (np. określenie TypeType.ADDRESS spowoduje, że widżet będzie zwracać tylko wyniki z dokładnym adresem).

  • Aby wyświetlać tylko wyniki dotyczące maksymalnie 5 określonych krajów, ustaw GMSAutocompleteFilter na countries.

Promowanie wyników w konkretnym regionie

Aby preferować (odchylenia) w określonym regionie, ustaw locationBias na GMSAutocompleteFilter, jak pokazano tutaj:

  northEast = CLLocationCoordinate2DMake(39.0, -95.0);
  southWest = CLLocationCoordinate2DMake(37.5, -100.0);
  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);

Ogranicz wyniki do określonego regionu

Aby ustawić wyświetlanie tylko wyników (ograniczonych) w zdefiniowanym regionie, ustaw locationRestriction na GMSAutocompleteFilter, jak pokazano tutaj:

  northEast = CLLocationCoordinate2DMake(39.0, -95.0);
  southWest = CLLocationCoordinate2DMake(37.5, -100.0);
  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.locationRestriction = GMSPlaceRectangularLocationOption(northEast, southWest);

Filtruj wyniki według kraju

Aby filtrować wyniki w maksymalnie 5 określonych krajach, ustaw countries na GMSAutocompleteFilter, jak pokazano tutaj:

  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.countries = @[ @"au", @"nz" ];

Filtruj wyniki według typu miejsca lub kolekcji

Ogranicz wyniki do określonego typu lub zbioru, ustawiając właściwość types właściwości GMSAutoCompleteFilter. Użyj tej właściwości, aby określić filtry wymienione w tabelach 1, 2 i 3 w sekcji Typy miejsc. Jeśli nic nie zostanie określone, zwracane są wszystkie typy.

Aby określić filtr typu lub typu kolekcji:

  • Użyj właściwości types, aby określić do 5 wartości typu z tabel 1 i tabeli 2 wyświetlanych w sekcji Typy miejsc. Wartości typów są definiowane w postaci stałych w GMSPlaceType.

  • Użyj właściwości types, aby określić kolekcję typów z tabeli 3 w typach miejsc. Wartości kolekcji typów są zdefiniowane stałymi w GMSPlaceType.

    W żądaniu można podać tylko jeden typ z tabeli 3. Jeśli określisz wartość w tabeli 3, nie możesz określić wartości z tabeli 1 lub tabeli 2. Jeśli to zrobisz, wystąpi błąd.

Aby na przykład zwracać tylko wyniki pasujące do określonego typu miejsca, ustaw types w GMSAutocompleteFilter. Poniższy przykład pokazuje, jak ustawić filtr, aby zwracać tylko wyniki z dokładnym adresem:

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

Optymalizacja autouzupełniania miejsc

W tej sekcji znajdziesz sprawdzone metody, które pomogą Ci w pełni wykorzystać możliwości usługi autouzupełniania miejsc.

Oto kilka ogólnych wskazówek:

  • Najszybszym sposobem na utworzenie działającego interfejsu użytkownika jest użycie widżetu autouzupełniania w interfejsie Maps JavaScript, widżetu autouzupełniania w pakiecie SDK do Androida lub sposobu kontroli interfejsu użytkownika autouzupełniania w pakiecie SDK dla iOS.
  • Naucz się najważniejszych pól danych autouzupełniania miejsc od samego początku.
  • Pola promowania ze względu na lokalizację i ograniczenia dotyczące lokalizacji są opcjonalne, ale mogą mieć duży wpływ na skuteczność autouzupełniania.
  • Użyj obsługi błędów, aby aplikacja działała płynnie w przypadku błędu interfejsu API.
  • Dopilnuj, aby aplikacja obsługiwała, gdy nie jest wybrana żadna opcja, i aby użytkownicy mogli go kontynuować.

Sprawdzone metody optymalizacji kosztów

Podstawowa optymalizacja kosztów

Aby zoptymalizować koszt korzystania z usługi autouzupełniania miejsc, użyj masek pól w szczegółach szczegółów miejsca i widżetów autouzupełniania miejsc, aby zwracać tylko wymagane pola danych o miejscach.

Zaawansowana optymalizacja kosztów

Rozważ użycie implementacji autouzupełniania miejsc, aby uzyskać dostęp do cennika według żądania i poprosić o wyniki interfejsu API dotyczące geokodowania dotyczące wybranego miejsca zamiast szczegółowych informacji o miejscu. Ceny na żądanie w połączeniu z interfejsem API kodowania geograficznego są bardziej opłacalne niż model na sesję (na podstawie sesji), jeśli spełnione są oba te warunki:

  • Jeśli potrzebujesz tylko szerokości i długości geograficznej lub adresu wybranego miejsca użytkownika, interfejs Geocoding API dostarcza te informacje w przypadku mniejszej liczby wywołań miejsca.
  • Jeśli użytkownicy wybiorą prognozę autouzupełniania w średnio 4 żądaniach autouzupełniania prognozowanych lub niższych, ustalanie cen na żądanie może być bardziej opłacalne niż model cenowy sesji.
Aby uzyskać pomoc w implementacji autouzupełniania miejsc, należy wybrać kartę odpowiadającą odpowiedzi na poniższe pytanie.

Czy Twoja aplikacja wymaga podania jakichkolwiek informacji innych niż adres lub szerokość i długość geograficzna wybranej prognozy?

Tak, chcę więcej informacji

Korzystaj z autouzupełniania miejsc na podstawie sesji z informacjami o miejscu.
Twoja aplikacja wymaga szczegółowych informacji o miejscu, takich jak nazwa miejsca, status firmy czy godziny otwarcia, dlatego implementacja autouzupełniania powinna korzystać z tokena sesji (automatycznego albo wbudowanego w widżety JavaScript, Androida lub iOS) za łączny koszt wynoszący 0, 017 USD na sesję plus odpowiednie kody danych miejsca w zależności od żądanych pól danych o miejscu.

Implementacja widżetów
Zarządzanie sesją jest automatycznie wbudowane w widżety
JavaScript, Android lub iOS. Obejmuje to zarówno żądania autouzupełniania miejsc, jak i żądania miejsc dotyczące wybranych prognoz. Określ parametr fields, aby mieć pewność, że wysyłasz tylko wymagane pola danych o miejscach.

Wdrażanie automatyzacji
W przypadku żądań autouzupełniania w miejscu użyj tokena sesji. Żądając szczegółów miejsca dotyczących wybranej prognozy, podaj te parametry:

  1. Identyfikator miejsca z odpowiedzi autouzupełniania miejsca.
  2. Token sesji używany w żądaniu autouzupełniania miejsc
  3. Parametr fields określający pola danych miejsca, których potrzebujesz.

Nie, wymaga tylko adresu i lokalizacji

W zależności od wydajności użycia funkcji autouzupełniania w miejscu docelowym aplikacja Geocoding API może być bardziej opłacalną opcją niż szczegóły miejsca. Wydajność autouzupełniania każdej aplikacji różni się w zależności od tego, co użytkownicy wpisują, gdzie jest używana i czy zastosowano sprawdzone metody optymalizacji skuteczności.

Aby odpowiedzieć na to pytanie, przeanalizuj średnią liczbę znaków wpisywanych przez użytkownika przed wybraniem podpowiedzi autouzupełniania w aplikacji.

Czy użytkownicy częściej wybierają prognozę autouzupełniania miejsc w maksymalnie 4 żądaniach?

Tak

Zaimplementuj automatyczne uzupełnianie miejsc bez tokenów sesji i wywołuj interfejs Geocoding API w prognozie dotyczącej wybranego miejsca.
Interfejs Geocode API udostępnia adresy i szerokość i szerokość geograficzną w cenie 0,005 USD za żądanie. Wystąpienie 4 żądań autouzupełniania miejsc – na żądanie kosztuje 0,01132 USD, więc łączny koszt 4 żądań plus wywołanie Geocoding API dotyczące prognozy wybranego miejsca wyniesie 0,01632 USD, czyli mniej niż cena autouzupełniania na sesję wynoszącą 0,017 USD.1

Rozważ zastosowanie sprawdzonych metod dotyczących skuteczności, aby ułatwić użytkownikom wyświetlanie podpowiedzi, których jeszcze nie używają.

Nie

Korzystaj z autouzupełniania miejsc na podstawie sesji z informacjami o miejscu.
Ponieważ średnia liczba żądań, które oczekujesz od użytkownika, zanim użytkownik wybierze prognozę prognozy dotyczącej autouzupełniania miejsc, przekracza koszt ceny na sesję, w Twojej implementacji autouzupełniania miejsc należy użyć tokena sesji zarówno w przypadku żądań autouzupełniania miejsc, jak i powiązanych żądań informacji o miejscu.Ten koszt wynosi 0,017 USD na sesję.1

Implementacja widżetów
Zarządzanie sesją jest automatycznie wbudowane w widżety JavaScript, Android lub iOS. Obejmuje to zarówno żądania autouzupełniania miejsc, jak i żądania miejsc dotyczące wybranych prognoz. Określ parametr fields, aby mieć pewność, że wysyłasz tylko żądania dotyczące danych podstawowych.

Wdrażanie automatyzacji
W przypadku żądań autouzupełniania w miejscu użyj tokena sesji. Żądając szczegółów miejsca dotyczących wybranej prognozy, podaj te parametry:

  1. Identyfikator miejsca z odpowiedzi autouzupełniania miejsca.
  2. Token sesji używany w żądaniu autouzupełniania miejsc
  3. Parametr fields określający pola Podstawowe dane, takie jak adres i geometria.

Rozważ opóźnienie żądań autouzupełniania miejsc
Możesz stosować strategie, takie jak opóźnienie żądania autouzupełniania miejsc, dopóki użytkownik nie wpisze pierwszych 3 lub 4 znaków, aby Twoja aplikacja wysyłała mniej żądań. Na przykład wysyłanie żądań autouzupełniania miejsc dla każdego znaku po wpisaniu trzeciego znaku oznacza, że jeśli użytkownik wpisze 7 znaków, a potem wybierze prognozę, w przypadku której wyślesz 1 żądanie interfejsu Geocoding API, całkowity koszt wyniesie 0,01632 PLN (4 * 0,00283 autouzupełniania na żądanie + 0,005 PLN).

Jeśli opóźnione żądania mogą spowodować żądanie średniej automatyzacji poniżej 4, możesz postępować zgodnie ze wskazówkami dotyczącymi implementacji autouzupełniania miejsc z użyciem interfejsu Geocode API. Opóźnienie żądań może być odbierane przez użytkowników, którzy mogą oczekiwać podpowiedzi po każdym nowym naciśnięciu klawisza.

Rozważ zastosowanie sprawdzonych metod dotyczących skuteczności, aby ułatwić użytkownikom wyświetlanie podpowiedzi, których szuka (mniej znaków).


  1. Wymienione tutaj koszty są w dolarach amerykańskich. Pełne ceny znajdziesz na stronie Płatności w Google Maps Platform.

Sprawdzone metody dotyczące skuteczności

Te wskazówki opisują sposoby optymalizacji skuteczności autouzupełniania miejsc:

  • Dodaj ograniczenia językowe, promowania lokalizacji i preferencji języka w implementacji autouzupełniania miejsc. W przypadku widżetów wybór języka jest niepotrzebny, ponieważ to one wybierają przeglądarkę w przeglądarce lub na urządzeniu mobilnym użytkownika.
  • Jeśli umiejscowieniu autouzupełniania miejsca towarzyszy mapa, możesz odchylenia lokalizacji na podstawie widocznego obszaru mapy.
  • Jeśli użytkownik nie wybierze jednego z podpowiedzi autouzupełniania, zwykle dlatego, że żadna z nich nie jest pożądanym adresem wyniku. Aby uzyskać trafniejsze wyniki, możesz ponownie użyć danych wejściowych użytkownika:
    • Jeśli oczekujesz, że użytkownik wpisze tylko informacje adresowe, użyj ponownie danych wejściowych użytkownika w wywołaniu interfejsu Geocoding API.
    • Jeśli spodziewasz się, że użytkownik wpisze zapytania dotyczące określonego miejsca według nazwy lub adresu, użyj opcji Znajdź miejsce. Jeśli wyniki są oczekiwane tylko w określonym regionie, skorzystaj z funkcji promowania lokalizacji.
    Inne scenariusze, w których najlepiej jest wrócić do interfejsu Geocoding API, to:
    • Użytkownicy wpisują adresy podrzędne w krajach, w których funkcja autouzupełniania adresów miejsc jest niekompletna, np. w Czechach, Estonii i na Litwie. Na przykład czeski adres „Stroupežnického 3191/17, Praha” generuje częściową prognozę w autouzupełnianiu miejsca.
    • Użytkownik wpisuje adres z prefiksem segmentu drogi, np. „23-30 29th St, Queens” w Nowym Jorku lub „47-380 Kamehameha Hwy, Kaneohe” na wyspie Kauai na Hawai'i.

Rozwiązywanie problemów

Błędy mogą występować w różnym stopniu, ale większość z nich prawdopodobnie wynika z błędów konfiguracji (np. użyto nieprawidłowego klucza interfejsu API, nieprawidłowo ustawiono klucz interfejsu API) lub błędów limitu (aplikacja przekroczyła limit). Więcej informacji o limitach znajdziesz w artykule Limity wykorzystania.

Błędy występujące w przypadku użycia elementów autouzupełniania są zwracane w metodzie didFailAutocompleteWithError() różnych protokołów przekazywania. Właściwość code podanego obiektu NSError jest ustawiona na jedną z wartości wyliczenia GMSPlacesErrorCode.