Dịch vụ tự động hoàn thành trong SDK địa điểm dành cho iOS trả về vị trí để phản hồi các truy vấn tìm kiếm của người dùng. Khi người dùng nhập, dịch vụ tự động hoàn thành sẽ trả về đề xuất cho các địa điểm như doanh nghiệp, địa chỉ, mã cộng và địa điểm yêu thích.
Bạn có thể thêm tính năng tự động hoàn thành vào ứng dụng của mình theo các cách sau:
- Thêm chế độ điều khiển tự động hoàn thành trên giao diện người dùng để lưu thời gian phát triển và đảm bảo trải nghiệm người dùng nhất quán.
- Nhận thông tin dự đoán về địa điểm theo phương thức lập trình để tạo người dùng tùy chỉnh của bạn.
Thêm thành phần điều khiển tự động hoàn thành trên giao diện người dùng
Thành phần điều khiển tự động hoàn thành trên giao diện người dùng là một hộp thoại tìm kiếm có tích hợp sẵn tính năng tự động hoàn thành
của Google. Khi người dùng nhập cụm từ tìm kiếm, chế độ kiểm soát này sẽ hiển thị
danh sách địa điểm dự đoán để chọn. Khi người dùng đưa ra lựa chọn,
GMSPlace
thực thể được trả về mà sau đó ứng dụng có thể dùng để lấy thông tin chi tiết về
địa điểm đã chọn.
Bạn có thể thêm điều khiển tự động hoàn thành trên giao diện người dùng vào ứng dụng của mình theo các cách sau:
Thêm chế độ điều khiển toàn màn hình
Sử dụng chế độ điều khiển toàn màn hình khi bạn muốn xem ngữ cảnh, trong đó
giao diện người dùng tự động hoàn thành tạm thời thay thế giao diện người dùng của ứng dụng cho đến khi
người dùng đã đưa ra lựa chọn. Chức năng này được cung cấp bởi
GMSAutocompleteViewController
. Khi người dùng chọn một địa điểm, ứng dụng sẽ nhận được một lệnh gọi lại.
Cách thêm chế độ điều khiển toàn màn hình vào ứng dụng:
- Tạo một thành phần trên giao diện người dùng trong ứng dụng chính của bạn để chạy tính năng điều khiển tự động hoàn thành trên giao diện người dùng,
ví dụ: trình xử lý cảm ứng trên
UIButton
. - Triển khai
GMSAutocompleteViewControllerDelegate
giao thức trong bộ điều khiển chế độ xem gốc. - Tạo một thực thể của
GMSAutocompleteViewController
rồi chỉ định bộ điều khiển chế độ xem gốc làm thuộc tính uỷ quyền. - Tạo một
GMSPlaceField
để xác định loại dữ liệu địa điểm cần trả về. - Thêm một
GMSAutocompleteFilter
để ràng buộc truy vấn với một loại địa điểm cụ thể. - Trình bày
GMSAutocompleteViewController
khi sử dụng[self presentViewController...]
. - Xử lý lựa chọn của người dùng trong
didAutocompleteWithPlace
uỷ quyền. - Loại bỏ bộ điều khiển trong
didAutocompleteWithPlace
, Phương thức uỷ quyềndidFailAutocompleteWithError
vàwasCancelled
.
Ví dụ sau minh hoạ một cách khả thi để khởi chạy
GMSAutocompleteViewController
để phản hồi khi người dùng nhấn vào một nút.
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
Thêm bộ điều khiển kết quả
Sử dụng trình điều khiển kết quả khi bạn muốn kiểm soát nhiều hơn đối với giao diện người dùng nhập văn bản. Trình điều khiển kết quả tự động bật/tắt chế độ hiển thị của danh sách kết quả dựa trên tiêu điểm đầu vào là giao diện người dùng.
Để thêm bộ điều khiển kết quả vào ứng dụng của bạn:
- Tạo một
GMSAutocompleteResultsViewController
. - Triển khai
GMSAutocompleteResultsViewControllerDelegate
giao thức trong bộ điều khiển chế độ xem gốc và chỉ định trình điều khiển chế độ xem gốc làm thuộc tính uỷ quyền. - Tạo đối tượng
UISearchController
, truyền vào giá trịGMSAutocompleteResultsViewController
làm đối số của bộ điều khiển kết quả. - Đặt
GMSAutocompleteResultsViewController
làm thuộc tínhsearchResultsUpdater
củaUISearchController
. - Thêm
searchBar
choUISearchController
vào giao diện người dùng của ứng dụng. - Xử lý lựa chọn của người dùng trong
didAutocompleteWithPlace
uỷ quyền.
Có một số cách để đặt thanh tìm kiếm của UISearchController
vào
giao diện người dùng của ứng dụng:
- Thêm một thanh tìm kiếm vào thanh điều hướng
- Thêm thanh tìm kiếm vào đầu chế độ xem
- Thêm thanh tìm kiếm bằng cách sử dụng kết quả cửa sổ bật lên
Thêm một thanh tìm kiếm vào thanh điều hướng
Ví dụ về mã sau đây minh hoạ cách thêm trình điều khiển kết quả, thêm thuộc tính
searchBar
vào thanh điều hướng và xử lý lựa chọn của người dùng:
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; }
Thêm thanh tìm kiếm vào đầu chế độ xem
Ví dụ về mã sau đây cho thấy cách thêm searchBar
vào đầu một khung hiển thị.
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; }
Theo mặc định, UISearchController
ẩn thanh điều hướng khi trình bày (bạn có thể tắt tính năng này). Trong trường hợp
thanh điều hướng hiển thị và mờ, UISearchController
không được đặt
vị trí một cách chính xác.
Hãy sử dụng mã sau đây để khắc phục vấn đề:
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;
Thêm thanh tìm kiếm bằng cách sử dụng kết quả cửa sổ bật lên
Ví dụ về mã sau đây cho thấy việc đặt thanh tìm kiếm ở bên phải thanh điều hướng và hiển thị kết quả trong cửa sổ bật lên.
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; }
Sử dụng nguồn dữ liệu bảng
Nếu ứng dụng của bạn có giao diện người dùng văn bản tìm kiếm tuỳ chỉnh, bạn có thể sử dụng
GMSAutocompleteTableDataSource
để điều khiển chế độ xem theo bảng hiển thị kết quả trên trình điều khiển chế độ xem.
Để sử dụng GMSAutocompleteTableDataSource
làm nguồn dữ liệu và được uỷ quyền của UITableView
trong bộ điều khiển chế độ xem:
- Triển khai
GMSAutocompleteTableDataSourceDelegate
vàUISearchBarDelegate
giao thức trong bộ điều khiển chế độ xem. - Tạo một
GMSAutocompleteTableDataSource
thực thể và chỉ định bộ điều khiển chế độ xem làm thuộc tính uỷ quyền. - Đặt
GMSAutocompleteTableDataSource
làm thuộc tính nguồn dữ liệu và uỷ quyền củaUITableView
thực thể trên bộ điều khiển chế độ xem. - Trong trình xử lý để nhập văn bản tìm kiếm, hãy gọi
sourceTextHasChanged
trênGMSAutocompleteTableDataSource
. - Xử lý lựa chọn của người dùng trong phương thức uỷ quyền
didAutocompleteWithPlace
. - Đóng bộ điều khiển trong
didAutocompleteWithPlace
,didFailAutocompleteWithError
wasCancelled
phương thức uỷ quyền.
Ví dụ về mã sau đây minh hoạ cách sử dụng
GMSAutocompleteTableDataSource
để lái chế độ xem theo bảng của UIViewController
khi UISearchBar
được thêm riêng biệt.
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
Tuỳ chỉnh văn bản và màu nền
Bạn có thể đặt màu cho tất cả văn bản và nền trong giao diện người dùng tự động hoàn thành điều khiển, để làm cho tiện ích phù hợp với giao diện trực quan của ứng dụng hơn một cách chặt chẽ. Có 2 cách để thiết lập màu cho thành phần điều khiển giao diện người dùng:
- Sử dụng giao thức UIAppearance gốc của iOS để tạo kiểu toàn cục cho các chế độ điều khiển giao diện người dùng nếu có thể. Các chế độ cài đặt này áp dụng cho nhiều, nhưng không phải tất cả, thành phần điều khiển trên giao diện người dùng phần tử.
- Sử dụng các phương thức SDK trên các lớp tiện ích để đặt thuộc tính không được giao thức UIAppearance hỗ trợ.
Thông thường, ứng dụng của bạn sẽ sử dụng một số tổ hợp của giao thức UIAppearance và các phương thức SDK. Sơ đồ dưới đây cho thấy những phần tử có thể được tạo kiểu:
Bảng sau đây liệt kê tất cả thành phần trên giao diện người dùng và cho biết cách mỗi thành phần một giao diện nên được định kiểu (giao thức UIAppearance hoặc phương thức SDK).
Phần tử trên giao diện người dùng | Phương thức | Hướng dẫn định phong cách |
---|---|---|
Phủ màu thanh điều hướng (nền) | Giao thức UIAppearance | Gọi setBarTintColor trên UINavigationBar proxy. |
Màu phủ màu trên thanh điều hướng (dấu nháy văn bản trên thanh tìm kiếm và nút Huỷ) | Giao thức UIAppearance | Gọi setTintColor trên UINavigationBar proxy. |
Màu văn bản trên Thanh tìm kiếm | Giao thức UIAppearance | Thiết lập NSForegroundColorAttributeName trong searchBarTextAttributes . |
Màu phủ thanh tìm kiếm | Không áp dụng | Thanh tìm kiếm trong suốt và sẽ hiển thị dưới dạng phiên bản được tô bóng của Thanh điều hướng. |
Màu văn bản phần giữ chỗ trên thanh tìm kiếm (văn bản tìm kiếm mặc định) | Giao thức UIAppearance | Thiết lập NSForegroundColorAttributeName trong placeholderAttributes . |
Văn bản chính (cũng áp dụng cho nội dung lỗi và nội dung thông báo) | Phương thức SDK | Gọi cho primaryTextColor . |
Văn bản chính được đánh dấu | Phương thức SDK | Gọi cho primaryTextHighlightColor . |
Văn bản phụ | Phương thức SDK | Gọi cho secondaryTextColor . |
Lỗi và nội dung thông báo | Phương thức SDK | Gọi cho primaryTextColor . |
Nền ô trong bảng | Phương thức SDK | Gọi cho tableCellBackgroundColor . |
Màu dấu phân cách ô trong bảng | Phương thức SDK | Gọi cho tableCellSeparatorColor . |
"Thử lại" nút | Phương thức SDK | Gọi cho tintColor . |
Chỉ báo hoạt động (vòng quay tiến trình) | Giao thức UIAppearance | Gọi setColor trên UIActivityIndicatorView proxy. |
"Do Google cung cấp" biểu trưng, hình ảnh đám mây buồn | Không áp dụng | Phiên bản màu trắng hoặc màu xám được chọn tự động dựa trên độ tương phản của nền. |
Kính lúp và biểu tượng văn bản rõ ràng trong trường văn bản trên Thanh tìm kiếm | Không áp dụng | Để tạo kiểu, hãy thay thế hình ảnh mặc định bằng hình ảnh có màu mong muốn. |
Sử dụng giao thức UIAppearance
Bạn có thể dùng giao thức UIAppearance
để lấy proxy giao diện cho một phần tử giao diện người dùng nhất định mà sau đó bạn có thể sử dụng để
đặt màu cho phần tử trên giao diện người dùng. Khi thực hiện sửa đổi, tất cả các bản sao của
một thành phần trên giao diện người dùng nhất định sẽ bị ảnh hưởng. Ví dụ: ví dụ sau đây trên toàn hệ thống
sẽ thay đổi màu văn bản của các lớp UITextField
thành màu xanh lục khi các lớp đó
có trong UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
Để biết thêm thông tin về cách xác định giá trị màu, hãy tham khảo Tài liệu tham khảo về lớp UIColor.
Các đoạn mã sau đây cho thấy tất cả lệnh proxy mà bạn cần dùng để
tạo kiểu cho mọi thứ trong thành phần điều khiển tự động hoàn thành toàn màn hình trên giao diện người dùng. Thêm mã này
đối với phương thức didFinishLaunchingWithOptions
trong App menu.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;
Đặt thuộc tính kiểu điều khiển giao diện người dùng
Một nhóm nhỏ các phần tử điều khiển trên giao diện người dùng có các thuộc tính không chịu ảnh hưởng của
Giao thức UIAppearance, v.v. phải được thiết lập trực tiếp. Ví dụ về mã sau đây
hiển thị việc xác định màu nền trước và nền sau, đồng thời áp dụng các màu này cho giao diện người dùng
thực thể điều khiển có tên acController
. Thêm mã này vào onLaunchClicked
trong 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;
Nhận gợi ý địa điểm theo phương thức lập trình
Bạn có thể tạo giao diện người dùng tìm kiếm tuỳ chỉnh để thay thế cho giao diện người dùng do tính năng tiện ích tự động hoàn thành. Để làm được điều này, ứng dụng của bạn phải nhận được thông tin dự đoán địa điểm theo phương thức lập trình. Ứng dụng của bạn có thể tải danh sách tên địa điểm được dự đoán và/hoặc địa chỉ theo một trong các cách sau:
Đang gọi cho GMSPlacesClient findAutocompletePredictionsFromQuery:
Để xem danh sách tên và/hoặc địa chỉ địa điểm dự đoán, trước tiên
tạo thực thể GMSPlacesClient,
sau đó gọi hàm
GMSPlacesClient findAutocompletePredictionsFromQuery:
bằng các tham số sau:
- Chuỗi
autocompleteQuery
chứa văn bản do người dùng nhập. GMSAutocompleteSessionToken
, mã này được dùng để xác định từng phiên riêng lẻ. Ứng dụng của bạn sẽ chuyển cùng một mã thông báo cho mỗi lệnh gọi yêu cầu tự động hoàn thành, sau đó chuyển mã thông báo đó, cùng với Mã địa điểm, trong lệnh gọi tiếp theo tớifetchPlacefromPlaceID:
để truy xuất Thông tin chi tiết về địa điểm cho địa điểm đã được người dùng chọn.GMSAutocompleteFilter
để:- Thiên vị hoặc hạn chế kết quả ở một khu vực cụ thể.
- Giới hạn kết quả ở một loại địa điểm cụ thể.
GMSPlaceLocationBias
/Đối tượng hạn chế xu hướng kết quả đến một khu vực cụ thể được xác định theo giới hạn vĩ độ và kinh độ.
- Phương thức gọi lại để xử lý các cụm từ gợi ý được trả về.
Các mã ví dụ dưới đây cho thấy lệnh gọi đến 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); } } }];
API gọi phương thức gọi lại được chỉ định, truyền vào một mảng
GMSAutocompletePrediction
.
Mỗi GMSAutocompletePrediction
đối tượng chứa các thông tin sau:
attributedFullText
– Nội dung đầy đủ của dự đoán, dưới dạngNSAttributedString
. Ví dụ: "Nhà hát Opera Sydney, Sydney, New South Xứ Wales, Úc'. Mỗi dải văn bản khớp với hoạt động đầu vào của người dùng sẽ có một giá trịkGMSAutocompleteMatchAttribute
. Bạn có thể sử dụng thuộc tính này để đánh dấu văn bản phù hợp trong truy vấn của người dùng, ví dụ như minh hoạ dưới đây.placeID
– Mã địa điểm của địa điểm được dự đoán. Mã địa điểm là một giá trị nhận dạng dạng văn bản xác định duy nhất một địa điểm. Để biết thêm thông tin về mã địa điểm, hãy xem Tổng quan về mã địa điểm.distanceMeters
– Khoảng cách theo đường thẳng từ giá trị được chỉ địnhorigin
đến đích đến. Nếu thuộc tínhorigin
không được thiết lập thì sẽ không có khoảng cách sẽ được trả về.
Ví dụ về mã sau đây minh hoạ cách đánh dấu các phần bằng chữ in đậm
của kết quả khớp với văn bản trong truy vấn của người dùng, sử dụng 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;
Sử dụng trình tìm nạp
Nếu muốn tạo chế độ kiểm soát tự động hoàn thành của riêng mình từ đầu, bạn có thể sử dụng
GMSAutocompleteFetcher
!
Phương thức này gói phương thức autocompleteQuery
trên GMSPlacesClient
.
Trình tìm nạp điều tiết các yêu cầu, chỉ trả về kết quả cho các yêu cầu gần đây nhất
nội dung tìm kiếm đã nhập. Không cung cấp thành phần trên giao diện người dùng.
Để triển khai GMSAutocompleteFetcher
,
hãy thực hiện các bước sau:
- Triển khai
GMSAutocompleteFetcherDelegate
giao thức. - Tạo một đối tượng
GMSAutocompleteFetcher
. - Gọi
sourceTextHasChanged
trên trình tìm nạp khi người dùng nhập. - Xử lý các cụm từ gợi ý và lỗi bằng
didAutcompleteWithPredictions
vàdidFailAutocompleteWithError
giao thức.
Ví dụ về mã sau đây minh hoạ cách sử dụng trình tìm nạp để lấy hoạt động đầu vào của người dùng
và địa điểm hiển thị trùng khớp trong chế độ xem văn bản. Chức năng chọn địa điểm
đã bị bỏ qua. FetcherSampleViewController
bắt nguồn từ UIViewController
trong LoadSampleViewController.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
Mã thông báo phiên
Mã thông báo phiên sẽ nhóm các giai đoạn truy vấn và lựa chọn trong quá trình tự động hoàn thành của người dùng tìm kiếm vào một phiên riêng biệt cho mục đích thanh toán. Phiên hoạt động bắt đầu khi người dùng bắt đầu nhập truy vấn và kết thúc khi họ chọn một địa điểm. Một có thể có nhiều truy vấn, theo sau là một lựa chọn địa điểm. Khi phiên hoạt động đã kết thúc, mã thông báo không còn hợp lệ; ứng dụng của bạn phải tạo ra một mã thông báo mới cho mỗi phiên. Bạn nên sử dụng mã thông báo phiên cho tất cả phiên tự động hoàn thành có lập trình (khi bạn sử dụng bộ điều khiển toàn màn hình, hoặc trình kiểm soát kết quả, thì API sẽ tự động xử lý việc này).
SDK Địa điểm dành cho iOS sử dụng GMSAutocompleteSessionToken
để xác định từng phiên. Ứng dụng của bạn sẽ truyền mã thông báo phiên mới khi
bắt đầu mỗi phiên mới, sau đó chuyển cùng mã thông báo đó, cùng với ID địa điểm,
trong lệnh gọi tiếp theo tới fetchPlacefromPlaceID:
để truy xuất Thông tin chi tiết về địa điểm cho địa điểm đã được người dùng chọn.
Tìm hiểu thêm về mã thông báo phiên.
Sử dụng mã sau để tạo mã thông báo phiên mới:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
Hạn mức sử dụng
- Việc sử dụng
GMSPlacesClient findAutocompletePredictionsFromQuery
phụ thuộc vào giới hạn truy vấn theo cấp. Xem tài liệu về giới hạn sử dụng.
Hiển thị thông tin ghi nhận sự đóng góp trong ứng dụng
- Nếu ứng dụng của bạn sử dụng dịch vụ tự động hoàn thành theo phương thức lập trình, thì giao diện người dùng phải hoặc hiển thị biểu tượng "Do Google cung cấp" hoặc xuất hiện trong Bản đồ mang thương hiệu Google.
- Nếu ứng dụng của bạn sử dụng chế độ điều khiển tự động hoàn thành trên giao diện người dùng thì bạn không cần làm gì thêm (thuộc tính bắt buộc sẽ hiển thị theo mặc định).
- Nếu bạn truy xuất và hiển thị thông tin bổ sung về địa điểm sau khi nhận một địa điểm theo mã nhận dạng, bạn cũng phải hiển thị thông tin ghi nhận sự đóng góp của bên thứ ba.
Để biết thêm thông tin, hãy xem tài liệu về phân bổ.
Kiểm soát chỉ báo hoạt động mạng
Để kiểm soát chỉ báo hoạt động mạng trên thanh trạng thái ứng dụng, bạn phải triển khai các phương thức uỷ quyền (không bắt buộc) thích hợp cho tính năng tự động hoàn thành lớp mà bạn đang sử dụng cũng như bật và tắt chỉ báo mạng.
- Đối với
GMSAutocompleteViewController
, bạn phải triển khai các phương thức uỷ quyềndidRequestAutocompletePredictions:
vàdidUpdateAutocompletePredictions:
. - Đối với
GMSAutocompleteResultsViewController
, bạn phải triển khai các phương thức uỷ quyềndidRequestAutocompletePredictionsForResultsController:
vàdidUpdateAutocompletePredictionsForResultsController:
. - Đối với
GMSAutocompleteTableDataSource
, bạn phải triển khai các phương thức uỷ quyềndidRequestAutocompletePredictionsForTableDataSource:
vàdidUpdateAutocompletePredictionsForTableDataSource:
.
Bằng cách triển khai các phương thức này và thiết lập [UIApplication sharedApplication].networkActivityIndicatorVisible
với YES
và NO
tương ứng, thanh trạng thái sẽ khớp chính xác với
giao diện người dùng tự động hoàn thành.
Giới hạn kết quả tự động hoàn thành
Bạn có thể thiết lập chế độ điều khiển tự động hoàn thành trên giao diện người dùng để ràng buộc kết quả ở một khu vực địa lý và/hoặc lọc kết quả theo một hoặc nhiều loại địa điểm hoặc một hoặc nhiều quốc gia cụ thể. Để ràng buộc kết quả, bạn có thể làm như sau:
- Để ưu tiên kết quả (độ lệch) trong khu vực đã xác định, hãy đặt
locationBias
thànhGMSAutocompleteFilter
(một số kết quả từ bên ngoài vùng đã xác định có thể vẫn được trả về). Nếu bạn cũng đặtlocationRestriction
,locationBias
sẽ bị bỏ qua. Để chỉ hiển thị (hạn chế) kết quả trong khu vực đã xác định, hãy đặt
locationRestriction
trênGMSAutocompleteFilter
(chỉ kết quả trong vòng khu vực đã xác định sẽ được trả về).- Lưu ý: Quy định hạn chế này chỉ áp dụng cho toàn bộ các tuyến đường, dữ liệu tổng hợp kết quả nằm ngoài ranh giới hình chữ nhật có thể được trả về dựa trên một tuyến đường trùng lặp với giới hạn vị trí.
Để chỉ trả về kết quả phù hợp với một loại địa điểm cụ thể, hãy đặt
types
trênGMSAutocompleteFilter
, (ví dụ: chỉ định TypeFilter.ADDRESS sẽ khiến tiện ích chỉ trả về kết quả có địa chỉ chính xác).Để chỉ trả về kết quả trong tối đa 5 quốc gia được chỉ định, hãy đặt
countries
vàoGMSAutocompleteFilter
.
Kết quả sai lệch đến một khu vực cụ thể
Để ưu tiên kết quả (độ lệch) trong khu vực đã xác định, hãy đặt locationBias
thành
GMSAutocompleteFilter
, như minh hoạ dưới đây:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);
Giới hạn kết quả ở một khu vực cụ thể
Để chỉ hiển thị (hạn chế) kết quả trong khu vực đã xác định, hãy đặt
locationRestriction
trên GMSAutocompleteFilter
, như minh hoạ dưới đây:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationRestriction = GMSPlaceRectangularLocationOption(northEast, southWest);
Lọc kết quả theo quốc gia
Để lọc kết quả ở tối đa 5 quốc gia được chỉ định, hãy đặt countries
trên
GMSAutocompleteFilter
như minh hoạ dưới đây:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
Lọc kết quả theo loại địa điểm hoặc loại bộ sưu tập
Hạn chế kết quả thuộc loại hoặc loại bộ sưu tập nhất định bằng cách đặt giá trị
Thuộc tính types
của
GMSAutoCompleteFilter
.
Sử dụng thuộc tính này để xác định các bộ lọc được liệt kê trong Bảng 1, 2 và 3 trên
Loại địa điểm. Nếu bạn không nêu rõ giá trị, hàm sẽ trả về tất cả các loại.
Để chỉ định một loại hoặc bộ lọc bộ sưu tập kiểu:
Sử dụng thuộc tính
types
để chỉ định tối đa 5 giá trị type trong Bảng 1 và Bảng 2 được hiển thị trên Loại địa điểm. Các giá trị loại là được xác định bởi các hằng số trongGMSPlaceType
.Sử dụng thuộc tính
types
để chỉ định một tập hợp kiểu trong Bảng 3 dưới đây trên Loại địa điểm. Giá trị tập hợp loại được xác định bởi các hằng số trongGMSPlaceType
.Chỉ cho phép một loại duy nhất từ Bảng 3 trong yêu cầu. Nếu bạn chỉ định một trong Bảng 3, bạn không thể chỉ định một giá trị trong Bảng 1 hoặc Bảng 2. Nếu bạn làm như vậy thì sẽ có lỗi xảy ra.
Ví dụ: để chỉ trả về kết quả phù hợp với một loại địa điểm cụ thể, đặt
types
vào GMSAutocompleteFilter
. Ví dụ sau đây cho thấy việc đặt
bộ lọc để chỉ trả về những kết quả có địa chỉ chính xác:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
Tối ưu hoá tính năng Tự động hoàn thành địa điểm
Phần này mô tả các phương pháp hay nhất để giúp bạn khai thác tối đa Dịch vụ Tự động hoàn thành địa điểm.
Dưới đây là một số nguyên tắc chung:
- Cách nhanh nhất để phát triển một giao diện người dùng hoạt động tốt là sử dụng Tiện ích Tự động hoàn thành của API Maps JavaScript, Tiện ích Tự động hoàn thành của SDK Địa điểm dành cho Android, hoặc SDK Địa điểm dành cho iOS Kiểm soát giao diện người dùng tự động hoàn thành
- Hiểu rõ về tính năng Tự động hoàn thành địa điểm thiết yếu trường dữ liệu ngay từ đầu.
- Các trường xu hướng vị trí và giới hạn vị trí là không bắt buộc nhưng có thể có tác động đáng kể đến hiệu suất tự động hoàn thành.
- Sử dụng tính năng xử lý lỗi để đảm bảo ứng dụng của bạn xuống cấp nhẹ nếu API trả về lỗi.
- Đảm bảo ứng dụng của bạn xử lý khi không có lựa chọn nào và cung cấp cho người dùng một cách để tiếp tục.
Các phương pháp hay nhất để tối ưu hoá chi phí
Tối ưu hoá chi phí cơ bản
Để tối ưu hoá chi phí khi sử dụng tính năng Tự động hoàn thành về địa điểm hãy sử dụng mặt nạ trường trong các tiện ích Chi tiết địa điểm và Tự động hoàn thành về địa điểm để chỉ trả về trường dữ liệu địa điểm mà bạn cần.
Tối ưu hoá chi phí nâng cao
Cân nhắc việc triển khai tính năng Tự động hoàn thành địa điểm theo phương thức lập trình để truy cập vào chế độ Giá theo mỗi yêu cầu và yêu cầu kết quả API mã hoá địa lý về địa điểm đã chọn thay vì Thông tin chi tiết về địa điểm. Đặt giá Cho mỗi yêu cầu được kết hợp với API mã hoá địa lý sẽ tiết kiệm chi phí hơn so với đặt giá Mỗi phiên (dựa trên phiên) nếu đáp ứng cả hai điều kiện sau:
- Nếu bạn chỉ cần vĩ độ/kinh độ hoặc địa chỉ của địa điểm mà người dùng đã chọn, thì API mã hoá địa lý sẽ cung cấp thông tin này trong ít hơn một lệnh gọi Chi tiết địa điểm.
- Nếu người dùng chọn một cụm từ gợi ý tự động hoàn thành trong số trung bình 4 yêu cầu dự đoán Tự động hoàn thành trở xuống, thì phương thức đặt giá Theo yêu cầu có thể tiết kiệm chi phí hơn so với phương thức đặt giá Theo phiên.
Ứng dụng của bạn có yêu cầu thông tin nào khác ngoài địa chỉ và vĩ độ/kinh độ của cụm từ gợi ý đã chọn không?
Có, cần thêm thông tin
Sử dụng tính năng Tự động hoàn thành địa điểm dựa trên phiên cùng với Thông tin chi tiết về địa điểm.
Vì ứng dụng của bạn yêu cầu Thông tin chi tiết về địa điểm, chẳng hạn như tên địa điểm, trạng thái doanh nghiệp hoặc giờ mở cửa, nên việc triển khai tính năng Tự động hoàn thành địa điểm sẽ dùng mã thông báo phiên (theo phương thức lập trình hoặc tích hợp vào tiện ích JavaScript, Android hoặc iOS) với tổng chi phí là 0, 017 USD cho mỗi phiên cộng với SKU dữ liệu địa điểm có thể áp dụng tuỳ thuộc vào các trường dữ liệu địa điểm
Triển khai tiện ích
Tính năng quản lý phiên được tự động tích hợp vào tiện ích JavaScript, Android hoặc iOS. Dữ liệu này bao gồm cả yêu cầu Tự động hoàn thành về địa điểm và thông tin chi tiết về địa điểm trên cụm từ gợi ý đã chọn. Hãy nhớ chỉ định tham số fields
để đảm bảo rằng bạn chỉ yêu cầu
trường dữ liệu địa điểm mà bạn cần.
Triển khai có lập trình
Sử dụng mã thông báo phiên với các yêu cầu Tự động hoàn thành địa điểm. Khi yêu cầu Thông tin chi tiết về địa điểm về cụm từ gợi ý đã chọn, hãy bao gồm các thông số sau:
- Mã địa điểm trong phản hồi Tự động hoàn thành về địa điểm
- Mã thông báo phiên được dùng trong yêu cầu Tự động hoàn thành địa điểm
- Tham số
fields
chỉ định trường dữ liệu địa điểm mà bạn cần
Không, chỉ cần địa chỉ và vị trí
API mã hoá địa lý có thể là một lựa chọn tiết kiệm chi phí hơn so với Chi tiết địa điểm cho ứng dụng của bạn, tuỳ thuộc vào hiệu suất của việc sử dụng tính năng Tự động hoàn thành địa điểm. Hiệu quả của tính năng Tự động hoàn thành của mỗi ứng dụng sẽ khác nhau tuỳ thuộc vào nội dung người dùng đang nhập, nơi ứng dụng đang được dùng và việc các phương pháp hay nhất để tối ưu hoá hiệu suất có được triển khai hay không.
Để trả lời câu hỏi sau, hãy phân tích số lượng ký tự trung bình người dùng nhập vào trước khi chọn dự đoán Tự động hoàn thành địa điểm trong ứng dụng của bạn.
Trung bình, người dùng có chọn một cụm từ gợi ý của tính năng Tự động hoàn thành về địa điểm trong tối đa 4 yêu cầu không?
Có
Triển khai tính năng Tự động hoàn thành địa điểm theo phương thức lập trình mà không cần mã thông báo phiên và gọi API mã hoá địa lý trên thông tin dự đoán về địa điểm đã chọn.
API mã hoá địa lý cung cấp các địa chỉ và vĩ độ/kinh độ của địa chỉ $0,005 cho mỗi yêu cầu. Việc tạo 4 yêu cầu Tự động hoàn thành theo địa điểm – Theo yêu cầu có chi phí là 0,01132 USD, do đó, tổng chi phí của 4 yêu cầu cộng với lệnh gọi API mã hoá địa lý về thông tin dự đoán địa điểm được chọn sẽ là 0,01632 USD, thấp hơn giá Tự động hoàn thành mỗi phiên là 0,017 USD/phiên.1
Hãy cân nhắc áp dụng các phương pháp hay nhất về hiệu suất để giúp người dùng nhận được thông tin gợi ý mà họ đang tìm với ít ký tự hơn nữa.
Không
Sử dụng tính năng Tự động hoàn thành địa điểm dựa trên phiên cùng với Thông tin chi tiết về địa điểm.
Vì số lượng yêu cầu trung bình mà bạn dự kiến sẽ đưa ra trước khi người dùng chọn thông tin dự đoán của tính năng Tự động hoàn thành về địa điểm vượt quá chi phí để tính giá mỗi phiên, nên việc triển khai tính năng Tự động hoàn thành địa điểm phải dùng một mã thông báo phiên cho cả yêu cầu Tự động hoàn thành về địa điểm và yêu cầu Thông tin chi tiết về địa điểm được liên kết với tổng chi phí là 0,017 USD cho mỗi phiên.1
Triển khai tiện ích
Tính năng quản lý phiên được tự động tích hợp vào tiện ích JavaScript, Android hoặc iOS. Dữ liệu này bao gồm cả yêu cầu Tự động hoàn thành về địa điểm và thông tin chi tiết về địa điểm trên cụm từ gợi ý đã chọn. Hãy nhớ chỉ định tham số fields
để đảm bảo bạn chỉ yêu cầu các trường Dữ liệu cơ bản.
Triển khai có lập trình
Sử dụng mã thông báo phiên với các yêu cầu Tự động hoàn thành địa điểm. Khi yêu cầu Thông tin chi tiết về địa điểm về cụm từ gợi ý đã chọn, hãy bao gồm các thông số sau:
- Mã địa điểm trong phản hồi Tự động hoàn thành về địa điểm
- Mã thông báo phiên được dùng trong yêu cầu Tự động hoàn thành địa điểm
- Tham số
fields
chỉ định các trường Dữ liệu cơ bản, chẳng hạn như địa chỉ và hình học
Cân nhắc trì hoãn các yêu cầu Tự động hoàn thành địa điểm
Bạn có thể sử dụng các chiến lược như trì hoãn yêu cầu Tự động hoàn thành địa điểm cho đến khi người dùng nhập 3 hoặc 4 ký tự đầu tiên để ứng dụng của bạn đưa ra ít yêu cầu hơn. Ví dụ: thực hiện yêu cầu Tự động hoàn thành địa điểm cho từng ký tự sau khi người dùng nhập ký tự thứ ba có nghĩa là nếu người dùng nhập 7 ký tự sau đó chọn gợi ý mà bạn thực hiện một yêu cầu API mã hóa địa lý, tổng chi phí sẽ là $0,01632 (4 * $0,00283 Tự động hoàn thành mỗi yêu cầu + $0,005 Mã hóa địa lý).1
Nếu việc trì hoãn yêu cầu có thể khiến yêu cầu có lập trình trung bình của bạn dưới 4, bạn có thể làm theo hướng dẫn triển khai Tự động hoàn thành địa điểm bằng cách sử dụng API mã hoá địa lý. Lưu ý rằng việc trì hoãn yêu cầu có thể được xem là độ trễ của người dùng vì họ có thể thấy cụm từ gợi ý mỗi khi nhấn phím mới.
Cân nhắc áp dụng các phương pháp hay nhất về hiệu suất để giúp người dùng nhận được thông tin gợi ý mà họ đang tìm kiếm với ít ký tự hơn.
-
Các chi phí được liệt kê ở đây được tính bằng đô la Mỹ. Vui lòng tham khảo trang Thanh toán trên Nền tảng Google Maps để biết thông tin đầy đủ về giá.
Các phương pháp hay nhất về hiệu suất
Các nguyên tắc sau đây mô tả cách để tối ưu hoá hiệu suất của tính năng Tự động hoàn thành về địa điểm:
- Thêm hạn chế theo quốc gia, thiên vị vị trí, và lựa chọn ngôn ngữ ưu tiên (đối với việc triển khai có lập trình) cho tính năng Tự động hoàn thành địa điểm trong quá trình triển khai. Không cần lựa chọn ưu tiên ngôn ngữ với các tiện ích vì chúng chọn tuỳ chọn ngôn ngữ từ trình duyệt hoặc thiết bị di động của người dùng.
- Nếu tính năng Tự động hoàn thành địa điểm đi kèm với một bản đồ, thì bạn có thể dịch chuyển vị trí theo khung nhìn của bản đồ.
- Trong trường hợp người dùng không chọn một trong các cụm từ gợi ý Tự động hoàn thành,
bởi vì không có dự đoán nào trong số đó là địa chỉ kết quả mong muốn, nên bạn có thể sử dụng lại
hoạt động đầu vào của người dùng để cố gắng nhận được kết quả có liên quan hơn:
- Nếu bạn muốn người dùng chỉ nhập thông tin địa chỉ, hãy sử dụng lại thông tin đầu vào ban đầu của người dùng trong lệnh gọi đến API mã hoá địa lý.
- Nếu bạn muốn người dùng nhập truy vấn về một địa điểm cụ thể theo tên hoặc địa chỉ, hãy sử dụng yêu cầu Tìm địa điểm. Nếu kết quả chỉ dự kiến có ở một khu vực cụ thể, hãy sử dụng xu hướng vị trí.
- Người dùng nhập địa chỉ con ở những quốc gia có hỗ trợ tính năng Tự động hoàn thành bằng địa điểm địa chỉ phụ không hoàn chỉnh, ví dụ: Cộng hoà Séc, Estonia và Lithuania. Ví dụ: Địa chỉ bằng tiếng Séc "Stroupe Sửanického 3191/17, Praha" đưa ra dự đoán một phần tại vị trí Tự động hoàn thành.
- Người dùng nhập địa chỉ có tiền tố đoạn đường như "23-30 29th St, Queens" inch New York City hoặc "47-380 Kamehameha Hwy, Kaneohe" trên đảo Kauai ở Hawaii.
Khắc phục sự cố
Mặc dù nhiều loại lỗi có thể xảy ra, nhưng phần lớn lỗi ứng dụng có khả năng gặp phải thường là do lỗi cấu hình (đối với ví dụ: sử dụng khoá API không chính xác hoặc khoá API đã được định cấu hình không chính xác) hoặc lỗi hạn mức (ứng dụng của bạn đã vượt quá hạn mức). Xem Hạn mức sử dụng để biết thêm thông tin về hạn mức.
Lỗi xảy ra khi sử dụng các tùy chọn điều khiển tự động hoàn thành được trả về trong
didFailAutocompleteWithError()
của các giao thức uỷ quyền khác nhau. Chiến lược phát hành đĩa đơn
Thuộc tính code
của đối tượng NSError
đã cung cấp được đặt thành một trong các giá trị của
bản liệt kê GMSPlacesErrorCode
.