Autouzupełnianie miejsc

Usługa autouzupełniania w pakiecie SDK Miejsc dla iOS zwraca w odpowiedzi na zapytania użytkowników. Podczas pisania przez użytkownika parametr autouzupełnianie zwraca propozycje miejsc takich jak firmy, adresów, kodów plus oraz do ciekawych miejsc.

Autouzupełnianie możesz dodać do aplikacji na te sposoby:

Dodawanie elementu sterującego autouzupełniania do interfejsu

Element sterujący autouzupełniania w interfejsie to okno wyszukiwania z wbudowanym autouzupełnianiem funkcji. Gdy użytkownik wpisuje wyszukiwane hasło, element sterujący wyświetla z listy przewidywanych miejsc do wyboru. Gdy użytkownik dokona wyboru, GMSPlace może zostać użyta przez aplikację, aby uzyskać szczegółowe informacje wybrane miejsce.

Element interfejsu autouzupełniania możesz dodać do aplikacji w jeden z tych sposobów:

Dodawanie elementu sterującego na pełnym ekranie

Użyj go, jeśli potrzebujesz kontekstu modalnego. interfejs autouzupełniania tymczasowo zastępuje interfejs aplikacji do momentu, użytkownik dokonał wyboru. Ta funkcja jest udostępniana przez GMSAutocompleteViewController zajęcia. Gdy użytkownik wybierze miejsce, do aplikacji zostanie oddzwonione.

Aby dodać do aplikacji element sterujący na pełnym ekranie:

  1. Utwórz element interfejsu w głównej aplikacji, aby uruchomić w interfejsie element sterujący autouzupełniania. na przykład w ramach modułu obsługi dotykowej urządzenia UIButton.
  2. Wdrażanie GMSAutocompleteViewControllerDelegate w kontrolerze widoku nadrzędnego.
  3. Utwórz instancję GMSAutocompleteViewController i przypisać nadrzędny kontroler widoku danych jako właściwość przedstawiciela.
  4. Tworzenie GMSPlaceField aby zdefiniować typy danych miejsc do zwrócenia.
  5. Dodaj GMSAutocompleteFilter aby ograniczyć zapytanie do określonego typu miejsca.
  6. Zaprezentuj GMSAutocompleteViewController za pomocą [self presentViewController...].
  7. Zatwierdź wybór użytkownika w didAutocompleteWithPlace .
  8. Zamknij kontroler w aplikacji didAutocompleteWithPlace, didFailAutocompleteWithError i wasCancelled metod przekazywania.

Poniższy przykład przedstawia jeden z możliwych 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:@selector(autocompleteClicked) forControlEvents:UIControlEventTouchUpInside];
  [btnLaunchAc setTitle:@"Launch autocomplete" forState:UIControlStateNormal];
  btnLaunchAc.frame = CGRectMake(5.0, 150.0, 300.0, 35.0);
  btnLaunchAc.backgroundColor = [UIColor blueColor];
  [self.view addSubview:btnLaunchAc];
}

  // Handle the user's selection.
- (void)viewController:(GMSAutocompleteViewController *)viewController
didAutocompleteWithPlace:(GMSPlace *)place {
  [self dismissViewControllerAnimated:YES completion:nil];
  // Do something with the selected place.
  NSLog(@"Place name %@", place.name);
  NSLog(@"Place ID %@", place.placeID);
  NSLog(@"Place attributions %@", place.attributions.string);
}

- (void)viewController:(GMSAutocompleteViewController *)viewController
didFailAutocompleteWithError:(NSError *)error {
  [self dismissViewControllerAnimated:YES completion:nil];
  // TODO: handle the error.
  NSLog(@"Error: %@", [error description]);
}

  // User canceled the operation.
- (void)wasCancelled:(GMSAutocompleteViewController *)viewController {
  [self dismissViewControllerAnimated:YES completion:nil];
}

  // Turn the network activity indicator on and off again.
- (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController *)viewController {
  [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}

- (void)didUpdateAutocompletePredictions:(GMSAutocompleteViewController *)viewController {
  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

@end

Dodawanie kontrolera wyników

Jeśli chcesz mieć większą kontrolę nad interfejsem wprowadzania tekstu, użyj kontrolera wyników. Kontroler wyników dynamicznie przełącza widoczność listy wyników według interfejsu wejściowego.

Aby dodać kontroler wyników do aplikacji:

  1. Utwórz GMSAutocompleteResultsViewController.
  2. Wdrażanie GMSAutocompleteResultsViewControllerDelegate w kontrolerze widoku nadrzędnego i przypisać kontroler widoku nadrzędnego jako właściwość przedstawiciela.
  3. Utwórz obiekt UISearchController, przekazując w parametrze GMSAutocompleteResultsViewController jako argumentu kontrolera wyników.
  4. Ustawianie GMSAutocompleteResultsViewController jako właściwość searchResultsUpdater elementu UISearchController.
  5. Dodaj pole searchBar dla aplikacji UISearchController do interfejsu użytkownika aplikacji.
  6. Zatwierdź wybór użytkownika w didAutocompleteWithPlace .

Pasek wyszukiwania elementu UISearchController możesz umieścić na kilka sposobów interfejsu aplikacji:

Dodawanie paska wyszukiwania do paska nawigacyjnego

Poniższy przykładowy kod pokazuje dodawanie kontrolera wyników, dodawania searchBar na pasku nawigacyjnym i przetwarzaj 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 u góry widoku

Poniższy przykładowy kod pokazuje dodawanie elementu searchBar na górze 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 (to ustawienie można wyłączyć). W przypadku, gdy: pasek nawigacyjny jest widoczny i nieprzezroczysty, UISearchController nie ustawia w odpowiednim miejscu docelowym.

Aby obejść ten problem, użyj następującego 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ącego okienka wyników

Poniższy przykładowy kod pokazuje umieszczanie paska wyszukiwania po prawej stronie pasek nawigacyjny, aby wyniki były wyświetlane w postaci wyskakującego okienka.

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

Za pomocą źródła danych tabeli

Jeśli Twoja aplikacja ma interfejs tekstowy wyszukiwania niestandardowego, możesz użyć GMSAutocompleteTableDataSource do kierowania widoku tabeli wyświetlającego wyniki na kontrolerze widoku.

Aby użyć narzędzia GMSAutocompleteTableDataSource jako źródło danych i przedstawiciela UITableView w kontrolerze widoku danych:

  1. Wdrażanie GMSAutocompleteTableDataSourceDelegate i UISearchBarDelegate w kontrolerze widoku danych.
  2. Tworzenie GMSAutocompleteTableDataSource i przypisać kontroler widoku danych jako właściwość przedstawiciela.
  3. Ustawianie GMSAutocompleteTableDataSource jako źródła danych i przeznacząć właściwości UITableView na kontrolerze widoku.
  4. W module obsługi wyszukiwania tekstu wywołaj sourceTextHasChanged w GMSAutocompleteTableDataSource
  5. Przetwórz wybór użytkownika w metodzie przekazywania dostępu w didAutocompleteWithPlace.
  6. Zamknij kontroler w didAutocompleteWithPlace, didFailAutocompleteWithError, wasCancelled metody przekazywania dostępu.

Poniższy przykładowy kod pokazuje korzystanie z GMSAutocompleteTableDataSource do kierowania widoku tabeli UIViewController, gdy UISearchBar jest dodany 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

Kolory całego tekstu i tła możesz ustawić w interfejsie autouzupełniania aby dostosować widżet do wyglądu aplikacji z całego świata. Kolory elementów sterujących interfejsu można ustawić na 2 sposoby:

  • Przez używanie natywnego protokołu UIAppearance na iOS w celu globalnego stylu elementów interfejsu, gdy jest to możliwe. Te ustawienia dotyczą wielu, ale nie wszystkich elementów interfejsu .
  • Przez wykorzystanie metod SDK w klasach widżetów do ustawienia właściwości, które nie są obsługiwane przez protokół UIAppearance.

Zwykle aplikacja używa kombinacji protokołu UIAppearance oraz metod SDK. Na poniższym diagramie pokazano, których elementów można stylizować:

Kolory elementów sterujących autouzupełniania interfejsu

Poniższa tabela zawiera listę wszystkich elementów interfejsu i wskazuje, jak każdy z nich stylu (protokół UIAppearance lub metoda SDK).

Element interfejsu Metoda Poradniki i styl
Odcień paska nawigacyjnego (tło) Protokół UIAppearance Wywołaj setBarTintColor przez serwer proxy UINavigationBar.
Kolor odcienia paska nawigacyjnego (karetka tekstu na pasku wyszukiwania i przycisk Anuluj) Protokół UIAppearance Wywołaj setTintColor przez serwer proxy UINavigationBar.
Kolor tekstu na pasku wyszukiwania Protokół UIAppearance Ustaw NSForegroundColorAttributeName w komórce searchBarTextAttributes.
Kolor odcienia paska wyszukiwania Nie dotyczy Pasek wyszukiwania jest półprzezroczysty i będzie wyświetlany jako zacieniona wersja. na pasku nawigacyjnym.
Kolor tekstu zastępczego paska wyszukiwania (domyślny tekst wyszukiwania) Protokół UIAppearance Ustaw NSForegroundColorAttributeName w komórce placeholderAttributes.
Tekst podstawowy (dotyczy również tekstu błędu i komunikatu) Metoda przy użyciu pakietu SDK Zadzwoń do firmy primaryTextColor.
Wyróżnienie tekstu głównego Metoda przy użyciu pakietu SDK Zadzwoń do firmy primaryTextHighlightColor.
Tekst dodatkowy Metoda przy użyciu pakietu SDK Zadzwoń do firmy secondaryTextColor.
Błąd i tekst wiadomości Metoda przy użyciu pakietu SDK Zadzwoń do firmy primaryTextColor.
Tło komórki tabeli Metoda przy użyciu pakietu SDK Zadzwoń do firmy tableCellBackgroundColor.
Kolor separatora komórek tabeli Metoda przy użyciu pakietu SDK Zadzwoń do firmy tableCellSeparatorColor.
„Spróbuj ponownie” przycisk Metoda przy użyciu pakietu SDK Zadzwoń do firmy tintColor.
Wskaźnik aktywności (wskaźnik postępu) Protokół UIAppearance Wywołaj setColor przez serwer proxy UIActivityIndicatorView.
„Technologia Google” logo, obraz z smutną chmurą Nie dotyczy Wersja biała lub szara jest wybierana automatycznie na podstawie kontrastu tła.
Ikony lupy i czystego tekstu w polu tekstowym na pasku wyszukiwania Nie dotyczy Aby zmienić styl, zastąp domyślne obrazy obrazami w wybranym kolorze.

Korzystanie z protokołu UIAppearance

Możesz używać protokołu UIAppearance aby pobrać proxy wyglądu dla danego elementu interfejsu, którego możesz potem użyć do ustaw kolor elementu interfejsu. W przypadku dokonania modyfikacji wszystkie wystąpienia danego elementu interfejsu. Na przykład poniższy przykład globalny zmienia kolor tekstu UITextField na zielony, gdy są dostępne zawarte w elemencie UISearchBar:

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

Więcej informacji na temat definiowania wartości kolorów znajdziesz w Dokumentacja klasy UIColor

Fragmenty kodu poniżej zawierają wszystkie polecenia serwera proxy, których należy użyć do stylu wszystkiego w elemencie sterującym autouzupełniania na pełnym ekranie. 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 elementów sterujących interfejsu

Część elementów sterujących interfejsu ma właściwości, na które nie ma wpływu UIAppearance, więc należy ustawić go bezpośrednio. Ten przykładowy kod pokazuje, jak określić kolory pierwszego planu i tła oraz stosować je w interfejsie instancji sterującej o nazwie acController. Dodaj ten kod do: onLaunchClicked w pliku 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 uzyskiwanie prognoz dotyczących miejsc

Możesz utworzyć niestandardowy interfejs wyszukiwania jako alternatywę dla interfejsu udostępnianego przez widżet autouzupełniania. Aby było to możliwe, aplikacja musi otrzymywać prognozy dotyczące miejsc automatycznie. Aplikacja może uzyskać listę przewidywanych nazw miejsc lub następujące sposoby:

Dzwonię do: GMSPlacesClient findAutocompletePredictionsFromQuery:

Aby uzyskać listę przewidywanych nazw miejsc i/lub adresów, najpierw instantiate GMSPlacesClient, a następnie wywołaj funkcję GMSPlacesClient findAutocompletePredictionsFromQuery:. z następującymi parametrami:

  • Ciąg tekstowy autocompleteQuery zawierający tekst wpisany przez użytkownika.
  • GMSAutocompleteSessionToken który służy do identyfikowania poszczególnych sesji. Aplikacja powinna przekazywać ten sam token dla każdego wywołania żądania autouzupełniania, a następnie przekazać ten token; wraz z identyfikatorem miejsca w kolejnym wywołaniu funkcji fetchPlacefromPlaceID:. w celu pobrania szczegółowych informacji o miejscu, które zostało wybrane przez użytkownika.
  • GMSAutocompleteFilter:
    • Uprzedź lub ogranicz wyniki do konkretnego regionu.
    • Ogranicz wyniki do określonego typu miejsca.
    • Obiekt GMSPlaceLocationBias/ograniczenia promujący wyniki do określonego obszaru określonego przez granice szerokości i długości geograficznej.
  • Metoda wywołania zwrotnego do obsługi zwróconych prognoz.

W przykładach poniżej pokazujemy wywołanie funkcji 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ę typu GMSAutocompletePrediction obiektów.

Co GMSAutocompletePrediction obiekt zawiera te informacje:

  • attributedFullText – pełny tekst podpowiedzi w formacie NSAttributedString. Na przykład „Sydney Opera House, Sydney, New South” w Australii”. Każdy zakres tekstu pasujący do danych wejściowych użytkownika ma kGMSAutocompleteMatchAttribute. Możesz użyć tego atrybutu, aby zaznacz pasujący tekst w zapytaniu użytkownika, np. jak pokazano poniżej.
  • placeID – identyfikator przewidywanego miejsca. Identyfikator miejsca to tekstowy identyfikator, który jednoznacznie identyfikuje miejsce. Więcej informacji na temat: identyfikatorów miejsc znajdziesz w artykule Identyfikatory miejsc – omówienie.
  • distanceMeters – odległość bezpośrednia od wskazanego miejsca. origin do celu podróży. Jeśli właściwość origin nie jest skonfigurowana, brak odległości .

Poniższy przykładowy kod pokazuje, jak pogrubiać fragmenty wyniku pasującego do tekstu zapytania użytkownika za pomocą funkcji 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;
    

Korzystanie z modułu pobierania

Jeśli chcesz utworzyć własny element sterujący autouzupełniania od zera, możesz użyć GMSAutocompleteFetcher opakowuje metodę autocompleteQuery w GMSPlacesClient. Moduł pobierania ogranicza liczbę żądań, zwracając tylko wyniki z ostatniej wpisany wyszukiwany tekst. Nie zawiera elementów interfejsu.

Aby zaimplementować GMSAutocompleteFetcher, wykonaj te czynności:

  1. Wdrażanie GMSAutocompleteFetcherDelegate protokołu.
  2. Utwórz obiekt GMSAutocompleteFetcher.
  3. Wywołuj funkcję sourceTextHasChanged w module pobierania, gdy użytkownik wpisuje tekst.
  4. Obsługa prognoz i błędów za pomocą interfejsu didAutcompleteWithPredictions i didFailAutocompleteWithError metod protokołu.

Ten przykładowy kod ilustruje użycie modułu pobierania do pobierania danych wejściowych użytkownika i wyświetlić dopasowania miejsc w widoku tekstowym. Funkcje wyboru miejsca został pominięty. FetcherSampleViewController pochodzi od: 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 użytkownika autouzupełniania w dyskretnej sesji na potrzeby rozliczeń. Sesja rozpoczyna się, gdy: użytkownik zaczyna wpisywać zapytanie, a kończy po wybraniu miejsca. Każdy sesja może zawierać wiele zapytań, po których następuje wybór jednego miejsca. Raz sesja się zakończyła, token utracił ważność. aplikacja musi wygenerować nowy token dla każdej sesji. Zalecamy korzystanie z tokenów sesji we wszystkich przypadkach sesji automatycznego autouzupełniania (jeśli używasz kontrolera pełnoekranowego, lub kontrolerze wyników, interfejs API zajmie się tym automatycznie).

Pakiet SDK Miejsc na iOS używa interfejsu GMSAutocompleteSessionToken identyfikować poszczególne sesje. Aplikacja powinna przekazywać nowy token sesji rozpoczyna każdą nową sesję, a następnie przekazuje ten sam token wraz z identyfikatorem miejsca, w kolejnym wywołaniu fetchPlacefromPlaceID: w celu pobrania szczegółowych informacji o miejscu, które zostało wybrane 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 aplikacja korzysta z usługi autouzupełniania automatycznie, interfejs użytkownika musi albo wyświetlić informację „Technologia Google” lub wyświetlać się w mapa marki Google.
  • Jeśli Twoja aplikacja używa elementu sterującego autouzupełniania w interfejsie użytkownika, nie musisz nic robić. (domyślnie wyświetlana jest wymagana atrybucja).
  • Jeśli pobierzesz i wyświetlisz dodatkowe informacje o miejscu po znajdowanie miejsca na podstawie identyfikatora, musisz też wyświetlać atrybucje zewnętrzne.

Więcej informacji znajdziesz w dokumentacji na temat atrybucje.

Sterowanie wskaźnikiem aktywności sieci

Aby sterować wskaźnikiem aktywności sieciowej na pasku stanu aplikacji, musi zaimplementować odpowiednie opcjonalne metody przekazywania dostępu do autouzupełniania w której używasz klasy, a następnie samodzielnie włącz i wyłącz wskaźnik sieci.

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

Poprzez wdrożenie tych metod i ustawienie [UIApplication sharedApplication].networkActivityIndicatorVisible na YES i NO, pasek stanu będzie prawidłowo .

Ogranicz wyniki autouzupełniania

W interfejsie autouzupełniania możesz ustawić ograniczenie wyników do określonego regionu geograficznego i/lub odfiltrować wyniki według co najmniej jednego typu miejsca, lub z konkretnego kraju lub kraju. Aby ograniczyć wyniki, możesz wykonać te czynności:

  • Aby preferować (odchylenia) wyniki w zdefiniowanym regionie, ustaw locationBias na GMSAutocompleteFilter (niektóre wyniki spoza zdefiniowanego regionu mogą ). Jeśli ustawiono także locationRestriction, parametr locationBias będzie ignorowany.
  • Aby wyświetlać (ograniczać) wyniki tylko w określonym regionie, ustaw locationRestriction z dnia GMSAutocompleteFilter (tylko wyniki w okresie zostanie zwrócony zdefiniowany region).

    • Uwaga: to ograniczenie dotyczy tylko całych tras, wyniki znajdujące się poza prostokątnymi granicami mogą być zwracane na podstawie trasy które pokrywa się z ograniczeniem dotyczącym lokalizacji.
  • Aby zwracać tylko wyniki pasujące do określonego typu miejsca, ustaw types w GMSAutocompleteFilter (na przykład określenie TypeFilter.ADDRESS) spowoduje, że widżet będzie zwracać tylko wyniki z dokładnym adresem).

  • Aby zwracać tylko wyniki z maksymalnie 5 określonych krajów, ustaw: countriesGMSAutocompleteFilter.

Uprzedzenia wyników w konkretnym regionie

Aby preferować (odchylenia) wyniki w zdefiniowanym 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);

Ograniczanie wyników do konkretnego regionu

Aby wyświetlać (ograniczać) wyniki tylko w określonym regionie, ustaw locationRestriction na GMSAutocompleteFilter, jak 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 z maksymalnie 5 określonych krajów, włącz countries GMSAutocompleteFilter, jak tutaj:

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

Filtruj wyniki według typu miejsca lub typu kolekcji

Ogranicz zbieranie wyników do określonego typu lub typu, ustawiając parametr Właściwość types 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 kolekcji typu lub typu:

  • Użyj właściwości types, aby określić maksymalnie 5 wartości type z tabeli 1. i tabeli 2 przedstawionej w sekcji Typy miejsc. Wartości typu to: zdefiniowane przez stałe w parametrze GMSPlaceType.

  • Użyj właściwości types, aby określić zbiór typów z widocznej tabeli 3 w sekcji Typy miejsc. Wartości zbioru typów są definiowane przez stałe w narzędziu GMSPlaceType.

    W żądaniu dozwolony jest tylko jeden typ z tabeli 3. Jeśli podasz wartości z tabeli 3, nie można podać wartości z tabeli 1 ani 2. Jeśli to błąd.

Aby na przykład zwrócić tylko wyniki pasujące do określonego typu miejsca, ustaw typesGMSAutocompleteFilter. Ten przykład pokazuje, jak filtr, który zwróci tylko wyniki z dokładnym adresem:

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

Optymalizacja miejsca autouzupełniania

W tej sekcji znajdziesz sprawdzone metody, które pomogą Ci w pełni wykorzystać Usługa autouzupełniania miejsca.

Oto kilka ogólnych wskazówek:

  • Najszybszym sposobem na stworzenie działającego interfejsu użytkownika jest wykorzystanie Maps JavaScript API – widżet autouzupełniania, Widżet autouzupełniania Miejsc Google na Androida, lub pakietu SDK Miejsc dla systemu iOS elementów sterujących w interfejsie autouzupełniania
  • Omówienie najważniejszych zasad autouzupełniania miejsc pola danych.
  • Pola promowania lokalizacji i ograniczenia lokalizacji są opcjonalne, ale mogą mają istotny wpływ na działanie autouzupełniania.
  • Zapewnianie płynnego pogorszenia stanu aplikacji dzięki obsłudze błędów jeśli interfejs API zwróci błąd.
  • Upewnij się, że aplikacja działa, gdy nie ma możliwości wyboru, i daje użytkownikom możliwość wyboru aby kontynuować.

Sprawdzone metody optymalizacji kosztów

Podstawowa optymalizacja kosztów

Optymalizacja kosztów korzystania z autouzupełniania miejsc należy używać masek pól w widżetach Szczegóły miejsca i autouzupełniania, aby zwracać tylko rozmieść pola danych, których potrzebujesz.

Zaawansowana optymalizacja kosztów

Rozważ zautomatyzowaną implementację autouzupełniania miejsc, aby uzyskać dostęp do cen na żądanie i wysyłać żądania wyników interfejsu Geocoding API dotyczących wybranego miejsca zamiast szczegółów miejsca. Model cenowy za żądanie w połączeniu z interfejsem Geocoding API jest bardziej opłacalny niż model cenowy za 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 przez użytkownika miejsca, interfejs Geocoding API dostarcza te informacje dla mniej niż wywołania Place Details.
  • Jeśli użytkownicy wybiorą podpowiedź autouzupełniania w zakresie nie więcej niż 4 żądań podpowiedzi autouzupełniania, model cenowy za żądanie może być bardziej opłacalny niż model płatności za sesję.
Aby uzyskać pomoc dotyczącą odpowiedniego wdrożenia autouzupełniania miejsc, wybierz kartę odpowiadającą Twojej odpowiedzi na poniższe pytanie.

Czy aplikacja wymaga innych informacji poza adresem i szerokością geograficzną wybranej prognozy?

Tak, potrzebujemy więcej informacji

Korzystaj z autouzupełniania miejsc opartego na sesji, korzystając z szczegółów miejsca.
Twoja aplikacja wymaga informacji o miejscach, takich jak nazwa miejsca, status firmy czy godziny otwarcia, dlatego implementacja autouzupełniania miejsc powinna korzystać z tokenu sesji (programowego lub wbudowanego w widżety JavaScript, Android lub iOS.Ich łączny koszt wynosi 0,017 USD za sesję i dodatkowe kody SKU danych miejsc w zależności od tego, o jakie pola danych miejsc prosisz}.

Implementacja widżetu
Zarządzanie sesjami jest automatycznie wbudowane w widżety JavaScript oraz Android i iOS. Obejmuje to zarówno żądania autouzupełniania miejsc, jak i żądania szczegółów miejsca dotyczące wybranej prognozy. Określ parametr fields, aby mieć pewność, że żądania są wysyłane tylko umieścić w odpowiednim miejscu pola danych.

Implementacja automatyczna
W żądaniach autouzupełniania miejsc używaj tokena sesji. W żądaniu Szczegóły miejsca dotyczące wybranej prognozy podaj te parametry:

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

Nie, wymaga tylko adresu i lokalizacji

Interfejs Geocoding API może być tańszą opcją niż informacje o miejscu, w zależności od tego, jak dobrze korzystasz z autouzupełniania. Skuteczność autouzupełniania każdej aplikacji różni się w zależności od tego, co wpisują użytkownicy, gdzie aplikacja jest używana i czy wdrożone zostały sprawdzone metody dotyczące optymalizacji wydajności.

Aby odpowiedzieć na poniższe pytanie, przed wybraniem podpowiedzi autouzupełniania miejsca w aplikacji sprawdź, ile znaków średnio wpisuje użytkownik.

Czy użytkownicy wybierają podpowiedzi autouzupełniania miejsca średnio w przypadku 4 żądań lub mniejszej liczby żądań?

Tak

Zaimplementuj autouzupełnianie miejsc automatycznie bez tokenów sesji i wywołuj interfejs Geocoding API dla prognozy wybranego miejsca.
Geocoding API dostarcza adresy oraz współrzędne szerokości i długości geograficznej za 0,005 USD na żądanie. Utworzenie 4 żądań typu Place Autocomplete – Per Request (Autouzupełnianie – według żądania) kosztuje 0,01132 USD, więc łączny koszt 4 żądań plus wywołania Geocoding API dla wybranej prognozy miejsca wynosi 0,01632 USD, czyli mniej niż cena autouzupełniania na sesję, która wynosi 0,017 USD za sesję1.

Zastanów się nad skorzystaniem ze sprawdzonych metod dotyczących skuteczności, aby pomóc użytkownikom uzyskać podpowiedzi, których szukają, przy użyciu jeszcze mniejszej liczby znaków.

Nie

Korzystaj z autouzupełniania miejsc opartego na sesji, korzystając z szczegółów miejsca.
Średnia liczba spodziewanych żądań, które zostaną wysłane przed wybraniem podpowiedzi autouzupełniania miejsca, przekracza koszt ceny za sesję. Dlatego Twoja implementacja autouzupełniania miejsc powinna korzystać z tokenu sesji zarówno dla żądań autouzupełniania miejsc, jak i powiązanych z nimi żądań informacji o miejscach. Ich łączny koszt to 0,017 USD za sesję1.

Implementacja widżetu
Zarządzanie sesjami jest automatycznie wbudowane w widżety JavaScript oraz Android i iOS. Obejmuje to zarówno żądania autouzupełniania miejsc, jak i żądania szczegółów miejsca dotyczące wybranej prognozy. Pamiętaj, by określić parametr fields, aby mieć pewność, że żądanie dotyczy tylko pól danych podstawowych.

Implementacja automatyczna
W żądaniach autouzupełniania miejsc używaj tokena sesji. W żądaniu Szczegóły miejsca dotyczące wybranej prognozy podaj te parametry:

  1. identyfikator miejsca z odpowiedzi na autouzupełnianie miejsca,
  2. Token sesji używany w żądaniu autouzupełniania miejsca.
  3. Parametr fields określający pola Dane podstawowe, takie jak adres i geometria

Rozważ opóźnienie prośby o autouzupełnianie miejsc
Aby zmniejszyć liczbę żądań, możesz zastosować strategie, takie jak opóźnienie żądania autouzupełniania miejsca do czasu wpisania przez użytkownika pierwszych trzech lub czterech znaków. Na przykład wykonywanie żądań autouzupełniania miejsc dla każdego znaku po wpisaniu trzeciego znaku przez użytkownika oznacza, że jeśli użytkownik wpisze 7 znaków, a potem wybierze prognozę, dla której utworzysz jedno żądanie do interfejsu Geocoding API, łączny koszt wyniesie 0,01632 USD (4 * 0,00283 Autouzupełniaj na żądanie + 0,005 USD za kodowanie geograficzne)1.

Jeśli opóźnienie żądań może spowodować, że średnia liczba żądań automatyzacji spadnie poniżej 4, postępuj zgodnie ze wskazówkami dotyczącymi skutecznej implementacji autouzupełniania miejsc za pomocą interfejsu Geocoding API. Pamiętaj, że opóźnienie żądań może być postrzegane jako opóźnienie przez użytkownika, który może oczekiwać podpowiedzi po każdym naciśnięciu klawisza.

Zastanów się nad skorzystaniem ze sprawdzonych metod dotyczących skuteczności, aby pomóc użytkownikom uzyskać spodziewaną prognozę przy użyciu mniejszej liczby znaków.


  1. Podane tu koszty są podane w dolarach amerykańskich. Pełne ceny znajdziesz na stronie płatności za Google Maps Platform.

Sprawdzone metody zwiększania skuteczności

Poniższe wskazówki opisują sposoby optymalizacji skuteczności autouzupełniania miejsc:

  • Dodaj ograniczenia związane z krajem, promowanie lokalizacji, (w przypadku implementacji automatycznych) ustawienia języka na autouzupełnianie miejsc. implementacji. Nie musisz wybierać języka dzięki widżetom, które wybierają język z przeglądarki użytkownika lub urządzenia mobilnego.
  • Jeśli wraz z mapą jest wyświetlana mapa, możesz dostosować lokalizację według widocznego obszaru mapy.
  • Jeśli użytkownik nie wybierze żadnej z podpowiedzi autouzupełniania, ponieważ żadne z tych podpowiedzi nie są pożądanym adresem wynikowym, możesz ponownie użyć oryginalnego adresu dane wejściowe użytkownika, aby uzyskać trafniejsze wyniki:
    • Jeśli spodziewasz się, że użytkownik wpisze tylko informacje adresowe, użyj tych samych danych wejściowych co użytkownik w wywołaniu Geocoding API.
    • Jeśli spodziewasz się, że użytkownicy będą wpisywać zapytania dotyczące konkretnego miejsca po nazwie lub adresie, skorzystaj z prośby o znajdowanie miejsca. Jeśli oczekiwane wyniki dotyczą tylko konkretnego regionu, użyj funkcji promowanie lokalizacji.
    Inne sytuacje, w których najlepiej użyć interfejsu Geocoding API, to:
    • Użytkownicy podający adresy podrzędne w krajach, w których autouzupełnianie obsługuje adresy obiektów podrzędnych są niekompletne, np. Czechy, Estonia i Litwa. Na przykład parametr Adres czeski „Stroupežnického 3191/17, Praha” daje częściową prognozę w miejscu Autouzupełnianie.
    • użytkownicy, którzy wpisują adresy z prefiksami fragmentu drogi, np. „23–30 29th St, Wrocław”; cale New York City lub „47-380 Kamehameha Hwy, Kaneohe” na wyspie Kauai na Hawajach.

Rozwiązywanie problemów

Błędy mogą być różne, jednak większość z nich prawdopodobnie są spowodowane błędami konfiguracji (w przypadku np. użyto niewłaściwego klucza interfejsu API lub skonfigurowano klucz interfejsu API nieprawidłowo) lub błędy limitu (aplikacja przekroczyła swój limit). Zobacz Limity wykorzystania .

Błędy, które wystąpią w przypadku korzystania z elementów sterujących autouzupełniania, są zwracane w sekcji Metoda didFailAutocompleteWithError() różnych protokołów przekazywania. Właściwość code podanego obiektu NSError jest ustawiona na jedną z wartości wyliczenie GMSPlacesErrorCode.