Автозаполнение мест (устаревшая версия) возвращает подсказки мест в ответ на поисковые запросы пользователей. По мере ввода текста сервис автозаполнения предлагает варианты мест, например компаний, адресов, кодов Plus Code и объектов инфраструктуры.
Добавить автозаполнение в приложение можно следующими способами:
- Добавьте элемент управления пользовательского интерфейса с автозаполнением, чтобы сэкономить время на разработку и обеспечить единообразие интерфейса.
- Получайте подсказки мест программно, чтобы создать персонализированный интерфейс.
Добавление элемента управления пользовательского интерфейса с функцией автозаполнения

Элемент управления пользовательского интерфейса для автозаполнения – это диалоговое окно поиска со встроенной функцией автозаполнения. По мере того как пользователь вводит поисковый запрос, элемент управления предлагает список подсказок мест. Когда пользователь выбирает место, возвращается экземпляр GMSPlace, который приложение может использовать для получения сведений о выбранном месте.
Чтобы добавить элемент управления пользовательского интерфейса службы подсказки мест в приложение, можно использовать следующие методы:
- Как добавить элемент управления полноэкранным режимом
- Добавьте контроллер результатов
- Как использовать источник данных таблицы
Как добавить элемент управления полноэкранным режимом
Используйте полноэкранный режим, когда вам нужен модальный контекст, в котором интерфейс автозаполнения временно заменяет интерфейс вашего приложения, пока пользователь не сделает выбор. Эта функция предоставляется классом GMSAutocompleteViewController. Когда пользователь выбирает то или иное место, ваше приложение получает обратный вызов.
Чтобы добавить элемент управления полноэкранного режима в приложение, выполните следующие действия.
- Создайте в основном приложении элемент пользовательского интерфейса, который будет запускать элемент управления автозаполнением, например обработчик касаний для
UIButton. - Реализуйте протокол
GMSAutocompleteViewControllerDelegateв родительском контроллере представления. - Создайте экземпляр
GMSAutocompleteViewControllerи назначьте родительский контроллер представления в качестве свойства делегата. - Создайте
GMSPlaceField, чтобы определить типы данных о местах, которые нужно возвращать. - Добавьте параметр
GMSAutocompleteFilter, чтобы ограничить запрос определенным типом места. - Покажите
GMSAutocompleteViewControllerс помощью[self presentViewController...]. - Обработайте выбор пользователя в методе делегата
didAutocompleteWithPlace. - Закройте контроллер в методах делегата
didAutocompleteWithPlace,didFailAutocompleteWithErrorиwasCancelled.
В примере ниже показано, как запустить GMSAutocompleteViewController в ответ на нажатие кнопки пользователем.
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 = [kGMSPlaceTypeCollectionAddress] 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
Как добавить контроллер результатов
Контроллер результатов можно использовать, если вам необходим дополнительный контроль пользовательского интерфейса, используемого для ввода текста. Контроллер результатов динамически переключает видимость списка результатов в зависимости от фокуса ввода в пользовательском интерфейсе.
Чтобы добавить контроллер результатов в свое приложение, выполните следующие действия.
- Создайте
GMSAutocompleteResultsViewController.- Реализуйте протокол
GMSAutocompleteResultsViewControllerDelegateв родительском контроллере представления и назначьте родительский контроллер представления в качестве свойства делегата.
- Реализуйте протокол
- Создайте объект
UISearchController, передавGMSAutocompleteResultsViewControllerв качестве аргумента контроллера результатов. - Задайте
GMSAutocompleteResultsViewControllerкак свойствоsearchResultsUpdaterдляUISearchController. - Добавьте
searchBarдляUISearchControllerв интерфейс приложения. - Обработайте выбор пользователя в методе делегата
didAutocompleteWithPlace.
Есть несколько способов разместить строку поиска UISearchController в интерфейсе приложения:
- Как добавить строку поиска на панель навигации
- Как добавить строку поиска вверху представления
- Как добавить строку поиска с результатами во всплывающем окне
Добавление строки поиска на панель навигации
В примере кода ниже показано, как добавить контроллер результатов, добавить searchBar на панель навигации и обработать выбор пользователя.
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; }
Добавление строки поиска в верхней части представления
В примере кода ниже показано, как добавить searchBar в верхнюю часть представления.
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; }
По умолчанию UISearchController скрывает панель навигации во время презентации (эту функцию можно отключить). Если панель навигации видна и непрозрачна, UISearchController не может правильно разместить рекламу.
Для решения этой проблемы используйте следующий код:
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;
Как добавить строку поиска с результатами во всплывающем окне
В следующем примере кода показано, как разместить строку поиска в правой части панели навигации и отобразить результаты во всплывающем окне.
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; }
Использование источника данных таблицы
Если в вашем приложении есть специальный текстовый интерфейс поиска, вы можете использовать класс GMSAutocompleteTableDataSource, чтобы управлять таблицей с результатами в контроллере представления.
Чтобы использовать GMSAutocompleteTableDataSource в качестве источника данных и делегата UITableView в контроллере представления, выполните следующие действия:
- Реализуйте протоколы
GMSAutocompleteTableDataSourceDelegateиUISearchBarDelegateв контроллере представления. - Создайте экземпляр
GMSAutocompleteTableDataSourceи назначьте контроллер представления в качестве свойства делегата. - Задайте
GMSAutocompleteTableDataSourceв качестве источника данных и делегируйте свойства экземпляраUITableViewв контроллере представления. - В обработчике для ввода текста поиска вызовите
sourceTextHasChangedдляGMSAutocompleteTableDataSource.- Обработайте выбор пользователя в методе делегата
didAutocompleteWithPlace.
- Обработайте выбор пользователя в методе делегата
- Закройте контроллер в методах делегата
didAutocompleteWithPlace,didFailAutocompleteWithError,wasCancelled.
В примере кода ниже показано, как использовать класс GMSAutocompleteTableDataSource для управления табличным представлением UIViewController, когда UISearchBar добавляется отдельно.
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
Настройка цветов текста и фона
Вы можете задать цвета для всего текста и фона в элементе управления пользовательского интерфейса с автозаполнением, чтобы виджет лучше соответствовал внешнему виду вашего приложения. Для настройки цвета элемента управления пользовательского интерфейса существуют два способа:
- Используйте встроенный протокол UIAppearance для iOS, чтобы по возможности задавать глобальные стили для элементов управления пользовательского интерфейса. Эти настройки применяются ко многим, но не ко всем элементам управления пользовательского интерфейса.
- Используйте методы SDK в классах виджетов, чтобы задать свойства, которые не поддерживаются протоколом UIAppearance.
Как правило, в приложении используется сочетание протокола UIAppearance и методов SDK. На приведенной ниже диаграмме показано, для каких элементов можно изменить стиль.

В таблице ниже перечислены все элементы интерфейса и указано, как следует настраивать стиль каждого из них (протокол UIAppearance или метод SDK).
| Элемент интерфейса | Метод | Модные советы |
|---|---|---|
| Цвет панели навигации (фон) | Протокол UIAppearance | Вызов setBarTintColor на прокси-сервере UINavigationBar. |
| Цвет панели навигации (курсор в строке поиска и кнопка "Отмена") | Протокол UIAppearance | Вызов setTintColor на прокси-сервере UINavigationBar. |
| Цвет текста в строке поиска | Протокол UIAppearance | Задайте NSForegroundColorAttributeName в searchBarTextAttributes. |
| Цвет строки поиска | Н/Д | Строка поиска полупрозрачна и выглядит как затененная версия панели навигации. |
| Цвет текста-плейсхолдера в строке поиска (текст поиска по умолчанию) | Протокол UIAppearance | Задайте NSForegroundColorAttributeName в placeholderAttributes. |
| Основной текст (также применяется к тексту ошибок и сообщений) | Метод SDK | Позвоните в компанию "primaryTextColor". |
| Выделение основного текста | Метод SDK | Позвоните в компанию "primaryTextHighlightColor". |
| Дополнительный текст | Метод SDK | Позвоните в компанию "secondaryTextColor". |
| Ошибка и текст сообщения | Метод SDK | Позвоните в компанию "primaryTextColor". |
| Фон ячейки таблицы | Метод SDK | Позвоните в компанию "tableCellBackgroundColor". |
| Цвет разделителя ячеек таблицы | Метод SDK | Позвоните в компанию "tableCellSeparatorColor". |
| Кнопка "Повторить попытку" | Метод SDK | Позвоните в компанию "tintColor". |
| Индикатор активности (индикатор выполнения) | Протокол UIAppearance | Вызов setColor на прокси-сервере UIActivityIndicatorView. |
| Логотип "Технологии Google", изображение грустного облака | Н/Д | Белый или серый вариант выбирается автоматически в зависимости от контрастности фона. |
| Значки лупы и очистки текста в текстовом поле строки поиска | Н/Д | Чтобы изменить стиль, замените изображения по умолчанию на изображения нужного цвета. |
Использование протокола UIAppearance
Вы можете использовать протокол UIAppearance, чтобы получить прокси-сервер внешнего вида для определенного элемента пользовательского интерфейса, который затем можно использовать для установки цвета элемента пользовательского интерфейса. При изменении элемента пользовательского интерфейса затрагиваются все его экземпляры. Например, в следующем примере цвет текста классов UITextField, содержащихся в UISearchBar, глобально меняется на зеленый:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
Дополнительную информацию об определении значений цвета можно найти в справочнике по классу UIColor.
В приведенных ниже фрагментах кода показаны все команды прокси, которые нужно использовать для настройки стиля всех элементов в полноэкранном элементе управления пользовательского интерфейса автозаполнения. Добавьте этот код в метод didFinishLaunchingWithOptions в файле 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;
Настройка свойств стиля элементов управления пользовательского интерфейса
У некоторых элементов управления пользовательского интерфейса есть свойства, на которые не влияет протокол UIAppearance, поэтому их нужно задавать напрямую. В примере кода ниже показано, как определить цвета переднего плана и фона и применить их к экземпляру элемента управления пользовательского интерфейса с названием acController. Добавьте этот код в метод onLaunchClicked в файле 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;
Как программно получить подсказки мест
Вы можете создать собственный интерфейс поиска вместо того, который предоставляется виджетом автозаполнения. Для этого ваше приложение должно получать подсказки мест программным способом. Ваше приложение может получить список прогнозируемых названий мест и/или адресов одним из следующих способов:
- Позвонить по номеру
GMSPlacesClient findAutocompletePredictionsFromQuery: - Как использовать инструмент получения данных
GMSPlacesClient findAutocompletePredictionsFromQuery: – вызов
Чтобы получить список названий и/или адресов мест, сначала создайте экземпляр GMSPlacesClient, а затем вызовите метод GMSPlacesClient
findAutocompletePredictionsFromQuery: со следующими параметрами:
- Строка
autocompleteQuery, содержащая текст, введенный пользователем. GMSAutocompleteSessionToken, который используется для идентификации каждого отдельного сеанса. Приложение должно передавать один и тот же токен для каждого вызова запроса автозаполнения, а затем передавать этот токен вместе с идентификатором места в последующем вызовеfetchPlacefromPlaceID:, чтобы получить информацию о месте, выбранном пользователем.GMSAutocompleteFilter- Настроить предпочтение или ограничение результатов определенным регионом.
- Ограничить результаты определенным типом места.
- Объект
GMSPlaceLocationBias/Restriction, который позволяет отдавать предпочтение результатам в определенной области, заданной границами широты и долготы.
- Метод обратного вызова для обработки возвращенных подсказок.
В примерах кода ниже показан вызов 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 = [kGMSPlaceTypeBank] 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); } } }];
API вызывает указанный метод обратного вызова, передавая массив объектов GMSAutocompletePrediction.
Каждый объект GMSAutocompletePrediction содержит следующую информацию:
attributedFullText– полный текст подсказки в виде объектаNSAttributedString. Пример: "Сиднейский оперный театр, Сидней, Новый Южный Уэльс, Австралия". Каждый текстовый диапазон, соответствующий введенному пользователем тексту, имеет атрибутkGMSAutocompleteMatchAttribute. Этот атрибут можно использовать, чтобы выделить совпадающий текст в запросе пользователя, как показано ниже.placeID– идентификатор места. Идентификатор места – это уникальный текстовый идентификатор. Подробнее об идентификаторах мест…distanceMeters– расстояние по прямой от указанной точкиoriginдо пункта назначения. Если свойствоoriginне задано, значение расстояния не возвращается.
В следующем примере кода показано, как с помощью 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;
Как использовать инструмент извлечения
Если вы хотите создать собственный элемент управления автозаполнением с нуля, используйте GMSAutocompleteFetcher, который является оболочкой для метода autocompleteQuery в GMSPlacesClient. Загрузчик ограничивает запросы, возвращая результаты только для последнего введенного поискового запроса. Он не предоставляет элементы пользовательского интерфейса.
Чтобы реализовать GMSAutocompleteFetcher, выполните следующие действия:
- Реализуйте протокол
GMSAutocompleteFetcherDelegate. - Создайте объект
GMSAutocompleteFetcher. - Вызовите
sourceTextHasChangedдля средства извлечения, когда пользователь вводит текст. - Обрабатывайте подсказки и ошибки с помощью методов протокола
didAutcompleteWithPredictionsиdidFailAutocompleteWithError.
В примере кода ниже показано, как использовать сборщик, чтобы получить введенные пользователем данные и показать совпадения мест в текстовом представлении. Функция выбора места была опущена. FetcherSampleViewController наследуется от UIViewController в FetcherSampleViewController.h.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var textField: UITextField? var resultText: UITextView? var fetcher: GMSAutocompleteFetcher? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white edgesForExtendedLayout = [] // Set bounds to inner-west Sydney Australia. let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366, longitude: 151.134002) let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725, longitude: 151.200349) // Set up the autocomplete filter. let filter = GMSAutocompleteFilter() filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner) // Create a new session token. let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init() // Create the fetcher. fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter) fetcher?.delegate = self fetcher?.provide(token) textField = UITextField(frame: CGRect(x: 5.0, y: 10.0, width: view.bounds.size.width - 5.0, height: 64.0)) textField?.autoresizingMask = .flexibleWidth textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) let placeholder = NSAttributedString(string: "Type a query...") textField?.attributedPlaceholder = placeholder resultText = UITextView(frame: CGRect(x: 0, y: 65.0, width: view.bounds.size.width, height: view.bounds.size.height - 65.0)) resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0) resultText?.text = "No Results" resultText?.isEditable = false self.view.addSubview(textField!) self.view.addSubview(resultText!) } @objc func textFieldDidChange(textField: UITextField) { fetcher?.sourceTextHasChanged(textField.text!) } } extension ViewController: GMSAutocompleteFetcherDelegate { func didAutocomplete(with predictions: [GMSAutocompletePrediction]) { let resultsStr = NSMutableString() for prediction in predictions { resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText) resultsStr.appendFormat("Place ID: %@\n", prediction.placeID) } resultText?.text = resultsStr as String } func didFailAutocompleteWithError(_ error: Error) { resultText?.text = error.localizedDescription } }
Objective-C
#import "FetcherSampleViewController.h" #import <GooglePlaces/GooglePlaces.h> @interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate> @end @implementation FetcherSampleViewController { UITextField *_textField; UITextView *_resultText; GMSAutocompleteFetcher* _fetcher; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.edgesForExtendedLayout = UIRectEdgeNone; // Set bounds to inner-west Sydney Australia. CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(-33.843366, 151.134002); CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(-33.875725, 151.200349); GMSAutocompleteFilter *autocompleteFilter = [[GMSAutocompleteFilter alloc] init]; autocompleteFilter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner); // Create the fetcher. _fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:nil filter:filter]; _fetcher.delegate = self; // Set up the UITextField and UITextView. _textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 0, self.view.bounds.size.width - 5.0f, 44.0f)]; _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; _resultText =[[UITextView alloc] initWithFrame:CGRectMake(0, 45.0f, self.view.bounds.size.width, self.view.bounds.size.height - 45.0f)]; _resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f]; _resultText.text = @"No Results"; _resultText.editable = NO; [self.view addSubview:_textField]; [self.view addSubview:_resultText]; } - (void)textFieldDidChange:(UITextField *)textField { NSLog(@"%@", textField.text); [_fetcher sourceTextHasChanged:textField.text]; } #pragma mark - GMSAutocompleteFetcherDelegate - (void)didAutocompleteWithPredictions:(NSArray *)predictions { NSMutableString *resultsStr = [NSMutableString string]; for (GMSAutocompletePrediction *prediction in predictions) { [resultsStr appendFormat:@"%@\n", [prediction.attributedPrimaryText string]]; } _resultText.text = resultsStr; } - (void)didFailAutocompleteWithError:(NSError *)error { _resultText.text = [NSString stringWithFormat:@"%@", error.localizedDescription]; } @end
Токены сеансов
Токены сеансов группируют этапы запроса и выбора выполняемого пользователем поиска с функцией автозаполнения в отдельный сеанс для выставления счетов. Сеанс начинается в тот момент, когда пользователь начинает вводить запрос, а завершается тогда, когда он выбирает место. В каждом сеансе может быть несколько запросов, после которых следует выбор одного места. Когда сеанс завершается, токен перестает быть действительным. Ваше приложение должно создавать новый токен для каждого сеанса. Рекомендуем использовать токены сеансов для всех сеансов автозаполнения, выполняемых программно (при использовании контроллера полноэкранного режима или контроллера результатов API делает это автоматически).
Places SDK для iOS использует GMSAutocompleteSessionToken для идентификации каждого сеанса. Приложение должно передавать новый токен сеанса в начале каждого нового сеанса, а затем передавать этот же токен вместе с идентификатором места в последующем вызове fetchPlacefromPlaceID:, чтобы получить сведения о месте, выбранном пользователем.
Подробнее о токенах сеансов…
Чтобы создать новый токен сеанса, используйте следующий код:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
Лимиты на использование
- При использовании метода
GMSPlacesClient findAutocompletePredictionsFromQueryдействуют многоуровневые ограничения на количество запросов. Подробнее о лимитах на использование…
Как показывать сведения об авторах в приложении
- Если ваше приложение использует сервис автозаполнения программно, в интерфейсе должна быть надпись "На базе Google" или карта с логотипом Google.
- Если в вашем приложении используется элемент управления пользовательского интерфейса для автозаполнения, никаких дополнительных действий не требуется (необходимая атрибуция отображается по умолчанию).
- Если вы получаете и показываете дополнительную информацию о месте после получения места по идентификатору, вы также должны указывать авторство третьих сторон.
Подробную информацию можно найти в документации по атрибуции.
Управление индикатором сетевой активности
Чтобы управлять индикатором сетевой активности в строке состояния приложений, необходимо реализовать соответствующие необязательные методы делегирования для используемого класса автозаполнения и самостоятельно включать и выключать индикатор сети.
- Для
GMSAutocompleteViewControllerнеобходимо реализовать методы делегатаdidRequestAutocompletePredictions:иdidUpdateAutocompletePredictions:. - Для
GMSAutocompleteResultsViewControllerнеобходимо реализовать методы делегатаdidRequestAutocompletePredictionsForResultsController:иdidUpdateAutocompletePredictionsForResultsController:. - Для
GMSAutocompleteTableDataSourceнеобходимо реализовать методы делегатаdidRequestAutocompletePredictionsForTableDataSource:иdidUpdateAutocompletePredictionsForTableDataSource:.
Применив эти методы и установив для [UIApplication
sharedApplication].networkActivityIndicatorVisible значения YES и NO соответственно, вы обеспечите соответствие строки состояния интерфейсу автозаполнения.
Как ограничить результаты автозаполнения
Вы можете настроить элемент управления пользовательского интерфейса для автозаполнения так, чтобы результаты ограничивались определенным географическим регионом и/или фильтровались по одному или нескольким типам мест или по определенной стране или странам. Чтобы ограничить результаты, вы можете сделать следующее:
- Чтобы предпочитать результаты в пределах определенного региона, задайте
locationBiasвGMSAutocompleteFilter(некоторые результаты за пределами определенного региона все равно могут быть возвращены). Если также задано значениеlocationRestriction, тоlocationBiasбудет игнорироваться. Чтобы показывать только результаты в пределах определенного региона, задайте параметр
locationRestrictionвGMSAutocompleteFilter.- Примечание. Это ограничение применяется только к маршрутам целиком. Синтетические результаты, расположенные за пределами границ, могут быть возвращены на основе маршрута, который частично находится в них.
Чтобы возвращать только результаты, соответствующие определенному типу места, задайте
typesвGMSAutocompleteFilter(например, если указать kGMSPlaceTypeCollectionAddress, виджет будет возвращать только результаты с точным адресом).Чтобы получать результаты только по определенным странам (не более пяти), задайте параметр
countriesв объектеGMSAutocompleteFilter.
Как настроить предпочтение результатов из определенного региона
Чтобы отдавать предпочтение результатам в пределах определенного региона, задайте locationBias в GMSAutocompleteFilter, как показано ниже.
northEast = CLLocationCoordinate2DMake(39.0, -95.0); southWest =
CLLocationCoordinate2DMake(37.5, -100.0); GMSAutocompleteFilter *filter =
[[GMSAutocompleteFilter alloc] init]; filter.locationBias =
GMSPlaceRectangularLocationOption(northEast, southWest);
Как ограничить результаты определенным регионом
Чтобы показывать только результаты в пределах определенного региона, задайте параметр locationRestriction в GMSAutocompleteFilter, как показано ниже.
northEast = CLLocationCoordinate2DMake(39.0, -95.0); southWest =
CLLocationCoordinate2DMake(37.5, -100.0); GMSAutocompleteFilter *filter =
[[GMSAutocompleteFilter alloc] init]; filter.locationRestriction =
GMSPlaceRectangularLocationOption(northEast, southWest);
Фильтрация результатов по стране
Чтобы отфильтровать результаты по странам (не более пяти), задайте для countries значение GMSAutocompleteFilter, как показано в этом примере:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
Как отфильтровать результаты по типу места или коллекции типов
Чтобы ограничить результаты определенным типом или коллекцией типов, задайте свойство types объекта GMSAutoCompleteFilter.
Используйте это свойство, чтобы указать фильтры, перечисленные в таблицах 1, 2 и 3 в статье Типы мест. Если опустить этот параметр, в результатах поиска возвращаются все типы.
Чтобы указать фильтр по типу или коллекции типов, выполните следующие действия:
С помощью свойства
typesможно указать до пяти значений type из таблицы 1 и таблицы 2 в статье Типы мест. Типы значений определяются константами вGMSPlaceType.Используйте свойство
types, чтобы указать коллекцию типов из таблицы 3 в статье Типы мест. Значения коллекции типов определяются константами вGMSPlaceType.В запросе допускается только один тип из таблицы 3. Если вы укажете значение из таблицы 3, значение из таблицы 1 или 2 указать нельзя. В противном случае возникнет ошибка.
Например, чтобы получить только результаты, соответствующие определенному типу места, задайте types в GMSAutocompleteFilter. В примере ниже показано, как настроить фильтр, чтобы возвращались только результаты с точным адресом.
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
Оптимизация автозаполнения мест (устаревшая версия)
В этом разделе приведены рекомендации по эффективному использованию устаревшего сервиса автозаполнения мест.
Рассмотрим некоторые общие рекомендации.
- Чтобы быстро разработать пользовательский интерфейс, используйте виджет автозаполнения мест (Legacy) Maps JavaScript API, виджет автозаполнения мест (Legacy) Places SDK для Android или элемент управления пользовательского интерфейса автозаполнения мест (Legacy) Places SDK для iOS.
- В первую очередь ознакомьтесь с самыми важными полями данных автозаполнения мест (устаревшее).
- Поля с предпочтениями и ограничениями местоположений использовать не обязательно, но они могут значительно повлиять на производительность функции автозаполнения.
- Используйте обработку ошибок в приложении на случай, если API вернет ошибку.
- Убедитесь, что приложение сможет обработать тот случай, если пользователь не выберет место, и предложить вариант продолжения работы.
Рекомендации по оптимизации затрат
Базовая оптимизация затрат
Для оптимизации затрат на сервис автозаполнения мест (Legacy) используйте маски полей в виджетах информации о местах (Legacy) и автозаполнения мест (Legacy), чтобы они возвращали только нужные вам поля данных автозаполнения мест (Legacy).
Дополнительная оптимизация затрат
Рассмотрите возможность программно реализовать сервис Place Autocomplete (Legacy), чтобы получить доступ к тарифу Autocomplete – Per Request и запрашивать результаты Geocoding API о выбранном месте вместо Place Details (Legacy). Тариф Per Request в сочетании Geocoding API будет выгоднее, чем тариф Per Session (на основе сеансов), если соблюдаются два следующих условия:
- Если вам нужны только широта и долгота или адрес выбранного пользователем места, получить эту информацию с помощью Geocoding API дешевле, чем вызывать Place Details (Legacy).
- Если пользователи выбирают подсказку автозаполнения мест в среднем из первых четырех запросов автозаполнения мест (устаревшее) или из меньшего числа, тариф Per Request может быть выгоднее, чем Per Session.
| Что нужно для подачи заявки | Среднее количество запросов автозаполнения мест (Legacy), прежде чем пользователь выберет подсказку | Рекомендуемые решения |
|---|---|---|
| Информация о месте, кроме адреса и местоположения, например название, статус компании или часы работы. | Не ограничено | Автозаполнение мест на основе сеансов (устаревшая версия) с информацией о местах (устаревшая версия) |
| Только адрес и широта и долгота выбранной подсказки | Четыре или меньше | Автозаполнение мест (устаревшее) с оплатой за запрос и Geocoding API |
| Только адрес и широта и долгота выбранной подсказки | Больше четырех | Автозаполнение мест на основе сеансов (устаревшая версия) для приложений, работающих только с адресами |
Возможно, для вашего приложения Geocoding API будет более выгодным вариантом, чем Place Details (Legacy). Это зависит от того, насколько эффективно вы используете Place Autocomplete (Legacy). Эффективность функции автозаполнения мест (устаревшей) в каждом приложении зависит от того, какие запросы вводят пользователи, где используется приложение и реализованы ли рекомендации по оптимизации производительности.
Чтобы найти среднее количество запросов для таблицы, проанализируйте, сколько символов в среднем вводит пользователь, прежде чем выбирать подсказку автозаполнения мест (Legacy) в приложении.
Автозаполнение мест на основе сеансов (устаревшая версия) с информацией о местах (устаревшая версия)
Используйте сервис автозаполнения мест (устаревший) на основе сеансов совместно с информацией о местах (устаревшая версия).
Поскольку вашему приложению требуется информация о местах (устаревшая версия), например название места, статус компании или часы работы, в вашей реализации Place Autocomplete (устаревшая версия) должен использоваться токен сеанса (программно или встроенный в виджеты JavaScript, Android или iOS) за сеанс плюс применимые коды Places Data в зависимости от того, какие поля данных о местах вы запрашиваете.1
Реализация виджета
Функция автоматического управления сеансами встроена в виджеты для JavaScript, Android и iOS. В нее входят как запросы автозаполнения мест (Legacy), так и запрос информации о местах (Legacy) для выбранной подсказки. Обязательно укажите параметр fields, чтобы запрашивались только нужные поля данных автозаполнения мест (Legacy).
Программная реализация
Используйте токен сеанса с запросами Place Autocomplete (Legacy). При запросе информации о местах (Legacy) по выбранной подсказке укажите следующие параметры:
- идентификатор места из ответа автозаполнения мест (устаревшая версия)
- токен сеанса, использованный в запросе автозаполнения мест (устаревшая версия);
- Параметр
fields, указывающий нужные поля данных автозаполнения мест (устаревшее).
Автозаполнение мест с оплатой за запрос (устаревшая версия) с Geocoding API
Реализуйте автозаполнение мест (Legacy) программно без токенов сеансов и вызывайте Geocoding API для выбранной подсказки места.
Geocoding API предоставляет адреса и координаты широты и долготы.
Четыре запроса Autocomplete – Per Request вместе с вызовом Geocoding API о выбранной подсказке места стоят меньше, чем один сеанс автозаполнения мест (Legacy)1.
Вы можете применить рекомендации по оптимизации эффективности, чтобы помочь пользователям получать нужные подсказки, вводя минимальное количество символов.
Автозаполнение мест на основе сеансов (устаревшая версия) для приложений, работающих только с адресами
Используйте сервис автозаполнения мест (устаревший) на основе сеансов совместно с информацией о местах (устаревшая версия).
Поскольку среднее количество запросов, которые вы ожидаете сделать до того, как пользователь выберет подсказку автозаполнения мест (устаревшая версия), превышает стоимость тарифа за сеанс, в вашей реализации автозаполнения мест (устаревшая версия) должен использоваться токен сеанса как для запросов автозаполнения мест (устаревшая версия), так и для связанного запроса информации о местах (устаревшая версия)
за сеанс.
1
Реализация виджета
Функция автоматического управления сеансами встроена в виджеты для JavaScript, Android и iOS. В нее входят как запросы автозаполнения мест (Legacy), так и запрос информации о местах (Legacy) для выбранной подсказки. Обязательно укажите параметр fields, чтобы запрашивались только нужные поля.
Программная реализация
Используйте токен сеанса с запросами Place Autocomplete (Legacy).
Запрашивая у Place Details (Legacy) информацию о выбранной подсказке, указывайте следующие параметры:
- идентификатор места из ответа автозаполнения мест (устаревшая версия)
- токен сеанса, использованный в запросе автозаполнения мест (устаревшая версия);
- Параметр
fields, указывающий поля данных Basic Data, например адрес и геометрические данные.
Рассмотрите возможность откладывать запросы автозаполнения мест (Legacy)
Вы можете попробовать различные стратегии, например откладывать запрос автозаполнения мест (Legacy), пока пользователь не введет первые три или четыре символа, чтобы ваше приложение совершало меньше запросов. Например, если вы отправляете запросы Place Autocomplete (Legacy) для каждого символа после того, как пользователь ввел третий символ, то, если пользователь введет семь символов и выберет подсказку, для которой вы отправите один запрос Geocoding API, общая стоимость будет равна стоимости четырех запросов Place Autocomplete (Legacy) Per Request и одного запроса Geocoding API1.
Если при откладывании запросов среднее число автоматизированных запросов станет меньше четырех, вы сможете эффективно использовать сервис автозаполнения мест (Legacy) с Geocoding API. Обратите внимание, что пользователь, ожидающий появления подсказок с каждым введенным символом, может принять откладывание запросов за задержку.
Вы можете применить рекомендации по оптимизации эффективности, чтобы помочь пользователям получать нужные подсказки, вводя меньше символов.
-
Цены указаны в прейскурантах платформы Google Карт.
Рекомендации по повышению эффективности
В рекомендациях ниже описаны способы оптимизации производительности автозаполнения мест (Legacy):
- Добавьте в свою реализацию Place Autocomplete (Legacy) ограничения по стране, предпочтение местоположений и (для программных реализаций) предпочитаемый язык. Предпочитаемый язык не нужен в случае виджетов, потому что для них язык определяется на основе языковых настроек браузера или мобильного устройства.
- Если вместе с автозаполнением мест (Legacy) отображается карта, вы можете сделать предпочитаемым местоположением видимую область карты.
- Если пользователь не выберет ни одну из подсказок автозаполнения мест (Legacy) – чаще всего такое бывает, если ни одна из них не соответствует искомому адресу, — вы можете повторно использовать изначально введенные пользователем данные, чтобы получить более подходящие результаты:
- Если вы рассчитываете, что пользователь будет вводить только информацию об адресе, повторно используйте изначально введенные им данные в вызове Geocoding API.
- Если пользователь скорее всего будет вводить запросы для определенного места по названию или адресу, используйте запрос информации о местах (устаревший). Если ожидается, что результаты будут из определенного региона, используйте предпочтение местоположений.
- Пользователи вводят адреса, содержащие номер квартиры или офиса. Так, для адреса в Чехии "Stroupežnického 3191/17, Praha" автозаполнение мест (устаревшее) покажет частичную подсказку.
- Пользователь вводит адрес с префиксом для ряда домов, например "23-30 29th St, Queens" в Нью-Йорке или "47-380 Kamehameha Hwy, Kaneohe" на острове Кауаи (Гавайи).
Привязка к местоположению
Настроить предпочтение результатов из определенной области с помощью параметров location и radius. Это указывает автозаполнению мест (Legacy) предпочитать результаты в пределах заданной области. однако более отдаленные точки также могут быть включены в ответ. С помощью параметра includedRegionCodes можно отфильтровать результаты, чтобы в них показывались только места в указанной стране.
Ограничение местоположений
Ограничить результаты определенной областью, передав параметр locationRestriction.
Вы также можете ограничить результаты регионом, заданным параметрами location и radius, добавив параметр strictbounds. В этом случае автозаполнение мест (устаревшее) будет возвращать результаты только из указанного региона.
Устранение неполадок
Хотя могут возникать самые разные ошибки, большинство из них обычно связано с конфигурацией (например, используется неправильный ключ API или ключ API настроен неправильно) или квотами (приложение превысило квоту). Подробную информацию о квотах можно найти в разделе Лимиты на использование.
Ошибки, возникающие при использовании элементов управления автозаполнением, возвращаются в методе didFailAutocompleteWithError() различных протоколов делегатов. Свойство code объекта NSError, переданного в функцию, принимает одно из значений перечисления GMSPlacesErrorCode.