سرویس تکمیل خودکار در Places SDK برای iOS، پیشبینیهای مکانی را در پاسخ به جستجوهای کاربر برمیگرداند. همزمان با تایپ کاربر، سرویس تکمیل خودکار پیشنهادهایی را برای مکانهایی مانند مشاغل، آدرسها، به علاوه کدها و نقاط مورد علاقه ارائه میدهد.
شما میتوانید به روشهای زیر قابلیت تکمیل خودکار را به برنامه خود اضافه کنید:
- برای صرفهجویی در زمان توسعه و تضمین یک تجربه کاربری پایدار ، یک کنترل رابط کاربری تکمیل خودکار اضافه کنید .
- پیشبینیهای مکان را به صورت برنامهنویسی شده دریافت کنید تا یک تجربه کاربری سفارشی ایجاد کنید.
افزودن یک کنترل رابط کاربری تکمیل خودکار

کنترل رابط کاربری تکمیل خودکار، یک کادر محاورهای جستجو با قابلیت تکمیل خودکار داخلی است. هنگامی که کاربر عبارات جستجو را وارد میکند، این کنترل لیستی از مکانهای پیشبینیشده برای انتخاب را ارائه میدهد. هنگامی که کاربر انتخابی انجام میدهد، یک نمونه GMSPlace بازگردانده میشود که برنامه شما میتواند از آن برای دریافت جزئیات مربوط به مکان انتخابشده استفاده کند.
شما میتوانید کنترل رابط کاربری تکمیل خودکار را به روشهای زیر به برنامه خود اضافه کنید:
اضافه کردن یک کنترل تمام صفحه
وقتی میخواهید یک زمینهی modal داشته باشید، از کنترل تمام صفحه استفاده کنید، جایی که رابط کاربری تکمیل خودکار به طور موقت جایگزین رابط کاربری برنامه شما میشود تا زمانی که کاربر انتخاب خود را انجام دهد. این قابلیت توسط کلاس GMSAutocompleteViewController ارائه میشود. وقتی کاربر مکانی را انتخاب میکند، برنامه شما یک فراخوانی دریافت میکند.
برای افزودن یک کنترل تمام صفحه به برنامه خود:
- یک عنصر رابط کاربری در برنامه اصلی خود ایجاد کنید تا کنترل رابط کاربری تکمیل خودکار را اجرا کند، به عنوان مثال یک کنترل کننده لمس روی یک
UIButton. - پروتکل
GMSAutocompleteViewControllerDelegateرا در کنترلر نمای والد پیادهسازی کنید. - یک نمونه از
GMSAutocompleteViewControllerایجاد کنید و کنترلر نمای والد را به عنوان خاصیت delegate اختصاص دهید. - یک
GMSPlaceFieldبرای تعریف انواع دادههای مکانی که باید برگردانده شوند، ایجاد کنید. - برای محدود کردن پرسوجو به نوع خاصی از مکان، یک
GMSAutocompleteFilterاضافه کنید. - با استفاده از
[self presentViewController...]GMSAutocompleteViewControllerرا ارائه دهید. - انتخاب کاربر را در متد delegate به
didAutocompleteWithPlaceمدیریت کنید. - کنترلر موجود در متدهای نماینده
didAutocompleteWithPlace،didFailAutocompleteWithErrorوwasCancelledرا رد کنید.
مثال زیر یک روش ممکن برای اجرای GMSAutocompleteViewController در پاسخ به ضربه زدن کاربر روی یک دکمه را نشان میدهد.
سویفت
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 } }
هدف-سی
#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را در کنترلر نمای والد پیادهسازی کنید و کنترلر نمای والد را به عنوان ویژگی delegate اختصاص دهید.
- پروتکل
- یک شیء
UISearchControllerایجاد کنید وGMSAutocompleteResultsViewControllerرا به عنوان آرگومان کنترلکننده نتایج به آن ارسال کنید. -
GMSAutocompleteResultsViewControllerرا به عنوان ویژگیsearchResultsUpdaterازUISearchControllerتنظیم کنید. - نوار
searchBarمربوط بهUISearchControllerرا به رابط کاربری برنامه خود اضافه کنید. - انتخاب کاربر را در متد delegate به
didAutocompleteWithPlaceمدیریت کنید.
چندین روش برای قرار دادن نوار جستجوی یک UISearchController در رابط کاربری برنامه شما وجود دارد:
- اضافه کردن نوار جستجو به نوار ناوبری
- اضافه کردن نوار جستجو به بالای یک نما
- اضافه کردن نوار جستجو با استفاده از نتایج popover
اضافه کردن نوار جستجو به نوار ناوبری
مثال کد زیر نحوهی افزودن یک کنترلر نتایج، افزودن searchBar به نوار ناوبری و مدیریت انتخاب کاربر را نشان میدهد:
سویفت
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 } }
هدف-سی
- (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 به بالای یک view را نشان میدهد.
سویفت
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 } }
هدف-سی
- (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 محل قرارگیری را به درستی تنظیم نمیکند.
از کد زیر به عنوان راه حل استفاده کنید:
سویفت
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
هدف-سی
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;
افزودن نوار جستجو با استفاده از نتایج popover
مثال کد زیر، قرار دادن یک نوار جستجو در سمت راست نوار ناوبری و نمایش نتایج در یک پنجره پاپاوور را نشان میدهد.
سویفت
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 } }
هدف-سی
- (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را در view controller پیادهسازی کنید. - یک نمونه از
GMSAutocompleteTableDataSourceایجاد کنید و view controller را به عنوان خاصیت delegate اختصاص دهید. -
GMSAutocompleteTableDataSourceرا به عنوان منبع داده و ویژگیهای نماینده نمونهUITableViewدر کنترلر نما تنظیم کنید. - در هندلر مربوط به ورودی متن جستجو،
sourceTextHasChangedرا رویGMSAutocompleteTableDataSourceفراخوانی کنید.- انتخاب کاربر را در متد delegate به
didAutocompleteWithPlaceمدیریت کنید.
- انتخاب کاربر را در متد delegate به
- کنترلر را در متدهای delegate مربوط به
didAutocompleteWithPlace،didFailAutocompleteWithErrorوwasCancelledرد کنید.
مثال کد زیر استفاده از کلاس GMSAutocompleteTableDataSource را برای هدایت نمای جدولی یک UIViewController ، زمانی که UISearchBar به طور جداگانه اضافه شده است، نشان میدهد.
سویفت
// 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 } }
هدف-سی
// 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
سفارشیسازی رنگ متن و پسزمینه
شما میتوانید رنگ تمام متنها و پسزمینهها را در کنترل رابط کاربری تکمیل خودکار تنظیم کنید تا ویجت با ظاهر بصری برنامه شما مطابقت بیشتری داشته باشد. دو روش برای تنظیم رنگهای کنترل رابط کاربری وجود دارد:
- با استفاده از پروتکل داخلی iOS UIAppearance برای استایلدهی سراسری به کنترلهای رابط کاربری در صورت امکان. این تنظیمات برای بسیاری از عناصر کنترل رابط کاربری، اما نه همه آنها، اعمال میشود.
- با استفاده از متدهای SDK در کلاسهای ویجت برای تنظیم ویژگیهایی که توسط پروتکل UIAppearance پشتیبانی نمیشوند.
معمولاً برنامه شما از ترکیبی از پروتکل UIAppearance و متدهای SDK استفاده میکند. نمودار زیر نشان میدهد که کدام عناصر میتوانند استایلبندی شوند:

جدول زیر تمام عناصر رابط کاربری را فهرست میکند و نحوهی استایلدهی هر یک را نشان میدهد (پروتکل ظاهر رابط کاربری یا روش SDK).
| عنصر رابط کاربری | روش | نحوه استایل دادن |
|---|---|---|
| رنگ نوار ناوبری (پس زمینه) | پروتکل ظاهر رابط کاربری | تابع setBarTintColor روی پروکسی UINavigationBar فراخوانی کنید. |
| رنگ نوار ناوبری (هشتگ متن نوار جستجو و دکمه لغو) | پروتکل ظاهر رابط کاربری | تابع setTintColor روی پروکسی UINavigationBar فراخوانی کنید. |
| رنگ متن نوار جستجو | پروتکل ظاهر رابط کاربری | NSForegroundColorAttributeName را در searchBarTextAttributes تنظیم کنید. |
| رنگ نوار جستجو | ناموجود | نوار جستجو شفاف است و به صورت یک نسخه سایهدار از نوار ناوبری نمایش داده میشود. |
| رنگ متن جایگزین نوار جستجو (متن جستجوی پیشفرض) | پروتکل ظاهر رابط کاربری | NSForegroundColorAttributeName را در placeholderAttributes تنظیم کنید. |
| متن اصلی (همچنین برای متن خطا و پیام اعمال میشود) | روش SDK | تابع primaryTextColor را فراخوانی کنید. |
| هایلایت متن اصلی | روش SDK | تابع primaryTextHighlightColor را فراخوانی کنید. |
| متن ثانویه | روش SDK | تابع secondaryTextColor را فراخوانی کنید. |
| متن خطا و پیام | روش SDK | تابع primaryTextColor را فراخوانی کنید. |
| پسزمینه سلول جدول | روش SDK | تابع tableCellBackgroundColor را فراخوانی کنید. |
| رنگ جداکننده سلولهای جدول | روش SDK | تابع tableCellSeparatorColor را فراخوانی کنید. |
| دکمه «دوباره امتحان کنید» | روش SDK | تابع tintColor را فراخوانی کنید. |
| نشانگر فعالیت (چرخش پیشرفت) | پروتکل ظاهر رابط کاربری | تابع setColor روی پروکسی UIActivityIndicatorView فراخوانی کنید. |
| لوگوی «قدرت گرفته از گوگل»، تصویر ابر غمگین | ناموجود | نسخه سفید یا خاکستری به طور خودکار بر اساس کنتراست پس زمینه انتخاب میشود. |
| آیکونهای ذرهبین و متن شفاف در فیلد متنی نوار جستجو | ناموجود | برای استایل دادن، تصاویر پیشفرض را با تصاویری با رنگ دلخواه جایگزین کنید. |
استفاده از پروتکل UIAppearance
شما میتوانید از پروتکل UIAppearance برای دریافت appearance proxy برای یک عنصر UI مشخص استفاده کنید، که سپس میتوانید از آن برای تنظیم رنگ عنصر UI استفاده کنید. هنگامی که تغییری ایجاد میشود، تمام نمونههای یک عنصر UI مشخص تحت تأثیر قرار میگیرند. برای مثال، مثال زیر رنگ متن کلاسهای 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 را نمونهسازی کنید ، سپس متد GMSPlacesClient findAutocompletePredictionsFromQuery: را با پارامترهای زیر فراخوانی کنید:
- یک رشتهی کوئریِ
autocompleteQueryکه شامل متنی است که توسط کاربر تایپ شده است. - یک
GMSAutocompleteSessionTokenکه برای شناسایی هر جلسه جداگانه استفاده میشود. برنامه شما باید برای هر فراخوانی درخواست تکمیل خودکار، توکن یکسانی را ارسال کند، سپس آن توکن را به همراه یک شناسه مکان (Place ID) در فراخوانی بعدی بهfetchPlacefromPlaceID:ارسال کند تا جزئیات مکان را برای مکانی که توسط کاربر انتخاب شده است، بازیابی کند. - یک
GMSAutocompleteFilterبرای:- نتایج را به یک منطقه خاص محدود یا جانبدارانه کنید.
- نتایج را به نوع خاصی از مکان محدود کنید.
- یک شیء
GMSPlaceLocationBias/Restriction که نتایج را به یک منطقه خاص که توسط مرزهای طول و عرض جغرافیایی مشخص شده است، بایاس میکند.
- یک متد فراخوانی برای مدیریت پیشبینیهای برگشتی.
مثالهای کد زیر فراخوانی تابع findAutocompletePredictionsFromQuery:
سویفت
/** * 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)") } } })
هدف-سی
/** * 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. به عنوان مثال، 'Sydney Opera House, Sydney, New South Wales, Australia'. هر محدوده متنی که با ورودی کاربر مطابقت دارد، دارای یک ویژگی به نامkGMSAutocompleteMatchAttributeاست. میتوانید از این ویژگی برای برجسته کردن متن منطبق در کوئری کاربر، مانند آنچه در زیر نشان داده شده است، استفاده کنید. -
placeID– شناسه مکان مکان پیشبینیشده. شناسه مکان یک شناسه متنی است که بهطور منحصربهفرد یک مکان را مشخص میکند. برای اطلاعات بیشتر در مورد شناسههای مکان، به نمای کلی شناسه مکان مراجعه کنید. -
distanceMeters– فاصلهی مستقیم ازoriginمشخص شده تا مقصد. اگر ویژگیoriginتنظیم نشده باشد، هیچ مقدار مسافتی بازگردانده نمیشود.
مثال کد زیر نحوهی برجسته کردن بخشهایی از نتیجه که با متن موجود در کوئری کاربر مطابقت دارند را با استفاده از enumerateAttribute صورت پررنگ نشان میدهد:
سویفت
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
هدف-سی
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روی fetcher فراخوانی کنید. - پیشبینیها و خطاها را با استفاده از متدهای پروتکل
didAutcompleteWithPredictionsوdidFailAutocompleteWithErrorمدیریت کنید.
مثال کد زیر استفاده از fetcher را برای دریافت ورودی کاربر و نمایش تطابق مکانها در یک نمای متنی نشان میدهد. قابلیت انتخاب مکان حذف شده است. FetcherSampleViewController از UIViewController در فایل FetcherSampleViewController.h مشتق شده است.
سویفت
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 } }
هدف-سی
#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 برای iOS از یک GMSAutocompleteSessionToken برای شناسایی هر جلسه استفاده میکند. برنامه شما باید با شروع هر جلسه جدید، یک توکن جلسه جدید ارسال کند، سپس همان توکن را به همراه یک شناسه مکان، در فراخوانی بعدی fetchPlacefromPlaceID: ارسال کند تا جزئیات مکان را برای مکانی که توسط کاربر انتخاب شده است، بازیابی کند.
درباره توکنهای جلسه بیشتر بدانید .
برای ایجاد یک توکن جلسه جدید از کد زیر استفاده کنید:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
محدودیتهای استفاده
- استفاده از متد
GMSPlacesClient findAutocompletePredictionsFromQueryتابع محدودیتهای پرسوجوی چندلایه است. به مستندات مربوط به محدودیتهای استفاده مراجعه کنید.
نمایش انتسابها در برنامه شما
- اگر برنامه شما از سرویس تکمیل خودکار به صورت برنامهنویسیشده استفاده میکند، رابط کاربری شما باید یا عبارت «Powered by Google» را نمایش دهد، یا در یک نقشه با برند گوگل ظاهر شود.
- اگر برنامه شما از کنترل رابط کاربری تکمیل خودکار استفاده میکند، هیچ اقدام اضافی لازم نیست (به طور پیشفرض، انتساب مورد نیاز نمایش داده میشود).
- اگر پس از دریافت یک مکان بر اساس شناسه، اطلاعات اضافی مکان را بازیابی و نمایش دهید، باید نسبتهای شخص ثالث را نیز نمایش دهید.
برای جزئیات بیشتر، به مستندات مربوط به انتسابها مراجعه کنید.
کنترل نشانگر فعالیت شبکه
برای کنترل نشانگر فعالیت شبکه در نوار وضعیت برنامهها، باید متدهای نماینده اختیاری مناسب را برای کلاس تکمیل خودکار مورد استفاده خود پیادهسازی کنید و نشانگر شبکه را خودتان روشن و خاموش کنید.
- برای
GMSAutocompleteViewControllerشما باید متدهای delegate به نامهایdidRequestAutocompletePredictions:وdidUpdateAutocompletePredictions:را پیادهسازی کنید. - برای
GMSAutocompleteResultsViewControllerشما باید متدهای delegate به نامهایdidRequestAutocompletePredictionsForResultsController:وdidUpdateAutocompletePredictionsForResultsController:را پیادهسازی کنید. - برای
GMSAutocompleteTableDataSourceشما باید متدهای delegate به نامهایdidRequestAutocompletePredictionsForTableDataSource:وdidUpdateAutocompletePredictionsForTableDataSource:را پیادهسازی کنید.
با پیادهسازی این متدها و تنظیم [UIApplication sharedApplication].networkActivityIndicatorVisible به ترتیب روی YES و NO ، نوار وضعیت به درستی با رابط کاربری تکمیل خودکار مطابقت خواهد داشت.
محدود کردن نتایج تکمیل خودکار
شما میتوانید کنترل رابط کاربری تکمیل خودکار را طوری تنظیم کنید که نتایج را به یک منطقه جغرافیایی خاص محدود کند، و/یا نتایج را به یک یا چند نوع مکان، یا به یک یا چند کشور خاص فیلتر کند. برای محدود کردن نتایج، میتوانید موارد زیر را انجام دهید:
- برای ترجیح (بایاس) نتایج درون ناحیه تعریفشده،
locationBiasرویGMSAutocompleteFilterتنظیم کنید (ممکن است برخی از نتایج خارج از ناحیه تعریفشده همچنان بازگردانده شوند). اگرlocationRestrictionنیز تنظیم شده باشد،locationBiasنادیده گرفته میشود. برای نمایش (محدود کردن) نتایج فقط در محدوده تعریف شده،
locationRestrictionرویGMSAutocompleteFilterتنظیم کنید (فقط نتایجی که در محدوده تعریف شده باشند، بازگردانده میشوند).- توجه: این محدودیت فقط برای کل مسیرها اعمال میشود، نتایج مصنوعی واقع در خارج از مرزهای مستطیلی ممکن است بر اساس مسیری که با محدودیت مکان همپوشانی دارد، بازگردانده شوند.
برای بازگرداندن فقط نتایجی که با نوع مکان خاصی مطابقت دارند،
typesدرGMSAutocompleteFilterتنظیم کنید (برای مثال، مشخص کردن TypeFilter.ADDRESS باعث میشود ویجت فقط نتایجی را با آدرس دقیق برگرداند).برای اینکه فقط نتایجی که حداکثر شامل پنج کشور مشخص شده باشند را برگردانید، در
GMSAutocompleteFilter،countriesتنظیم کنید.
نتایج سوگیری به یک منطقه خاص
برای ترجیح دادن (بایاس) نتایج در محدوده تعریف شده، 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 ، نتایج را به نوع یا مجموعهای از انواع خاص محدود کنید. از این ویژگی برای تعیین فیلترهای فهرستشده در جداول ۱، ۲ و ۳ روی Place Types استفاده کنید. اگر چیزی مشخص نشود، همه نوعها بازگردانده میشوند.
برای مشخص کردن نوع یا فیلتر مجموعه نوع:
از ویژگی
typesبرای تعیین حداکثر پنج مقدار نوع از جدول ۱ و جدول ۲ نشان داده شده در Place Types استفاده کنید. مقادیر نوع توسط ثابتهای موجود درGMSPlaceTypeتعریف میشوند.از ویژگی
typesبرای مشخص کردن یک مجموعه نوع از جدول 3 نشان داده شده در Place Types استفاده کنید. مقادیر مجموعه نوع توسط ثابتهای موجود درGMSPlaceTypeتعریف میشوند.فقط یک نوع از جدول ۳ در درخواست مجاز است. اگر مقداری را از جدول ۳ مشخص کنید، نمیتوانید مقداری را از جدول ۱ یا جدول ۲ مشخص کنید. در این صورت، خطایی رخ میدهد.
برای مثال، برای بازگرداندن فقط نتایجی که با یک نوع مکان خاص مطابقت دارند، types در GMSAutocompleteFilter تنظیم کنید. مثال زیر تنظیم فیلتر را برای بازگرداندن فقط نتایج با آدرس دقیق نشان میدهد:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
بهینهسازی تکمیل خودکار مکان (Legacy)
این بخش بهترین شیوهها را برای کمک به شما در استفادهی حداکثری از سرویس تکمیل خودکار مکان (قدیمی) شرح میدهد.
در اینجا چند دستورالعمل کلی آورده شده است:
- سریعترین راه برای توسعه یک رابط کاربری کارآمد، استفاده از ویجت Maps JavaScript API Place Autocomplete (Legacy) ، ویجت Places SDK برای اندروید Place Autocomplete (Legacy) یا کنترل رابط کاربری Places SDK برای iOS Place Autocomplete (Legacy) است.
- از همان ابتدا فیلدهای داده ضروری Place Autocomplete (Legacy) را درک کنید.
- فیلدهای Location biasing و location restriction اختیاری هستند اما میتوانند تأثیر قابل توجهی بر عملکرد تکمیل خودکار داشته باشند.
- از مدیریت خطا استفاده کنید تا مطمئن شوید که برنامه شما در صورت بروز خطا توسط API، به طور مناسب از رده خارج میشود.
- مطمئن شوید که برنامه شما وقتی هیچ انتخابی وجود ندارد، کار میکند و به کاربران راهی برای ادامه ارائه میدهد.
بهترین شیوههای بهینهسازی هزینه
بهینهسازی هزینه پایه
برای بهینهسازی هزینه استفاده از سرویس تکمیل خودکار مکان (Legacy)، از ماسکهای فیلد در ویجتهای جزئیات مکان (Legacy) و تکمیل خودکار مکان (Legacy) استفاده کنید تا فقط فیلدهای داده تکمیل خودکار مکان (Legacy) مورد نیاز شما را برگردانید.
بهینهسازی پیشرفته هزینه
پیادهسازی برنامهریزیشدهی Place Autocomplete (Legacy) را برای دسترسی به SKU در نظر بگیرید: Autocomplete - Per Request pricing و درخواست نتایج Geocoding API در مورد مکان انتخابشده به جای Place Details (Legacy). قیمتگذاری بر اساس درخواست همراه با Geocoding API در صورت برآورده شدن هر دو شرط زیر، مقرونبهصرفهتر از قیمتگذاری بر اساس هر جلسه (مبتنی بر جلسه) است:
- اگر فقط به طول/عرض جغرافیایی یا آدرس مکان انتخاب شده کاربر نیاز دارید، API مربوط به Geocoding این اطلاعات را با هزینهای کمتر از فراخوانی Place Details (Legacy) ارائه میدهد.
- اگر کاربران یک پیشبینی تکمیل خودکار را در بین میانگین چهار درخواست پیشبینی تکمیل خودکار (قدیمی) یا کمتر انتخاب کنند، قیمتگذاری بر اساس هر درخواست ممکن است مقرونبهصرفهتر از قیمتگذاری بر اساس هر جلسه باشد.
آیا درخواست شما به اطلاعات دیگری غیر از آدرس و طول و عرض جغرافیایی پیشبینی انتخاب شده نیاز دارد؟
بله، نیاز به توضیحات بیشتر دارد
از تکمیل خودکار مکان مبتنی بر جلسه (Legacy) به همراه جزئیات مکان (Legacy) استفاده کنید.
از آنجایی که برنامه شما به جزئیات مکان (Legacy) مانند نام مکان، وضعیت کسب و کار یا ساعات کاری نیاز دارد، پیادهسازی شما از قابلیت تکمیل خودکار مکان (Legacy) باید از یک توکن جلسه ( به صورت برنامهنویسی یا ساخته شده در ویجتهای جاوا اسکریپت ، اندروید یا iOS ) به ازای هر جلسه به علاوه SKUهای داده مکانهای قابل اجرا، بسته به فیلدهای داده مکانی که درخواست میکنید، استفاده کند. 1
پیادهسازی ویجت
مدیریت جلسه به طور خودکار در ویجتهای جاوا اسکریپت ، اندروید یا iOS تعبیه شده است. این شامل درخواستهای تکمیل خودکار مکان (Legacy) و درخواست جزئیات مکان (Legacy) در پیشبینی انتخاب شده میشود. حتماً پارامتر fields را مشخص کنید تا مطمئن شوید که فقط فیلدهای داده تکمیل خودکار مکان (Legacy) مورد نیاز خود را درخواست میکنید.
پیادهسازی برنامهریزیشده
از یک توکن جلسه با درخواستهای تکمیل خودکار مکان (Legacy) خود استفاده کنید. هنگام درخواست جزئیات مکان (Legacy) در مورد پیشبینی انتخاب شده، پارامترهای زیر را وارد کنید:
- شناسه مکان از پاسخ تکمیل خودکار مکان (قدیمی)
- توکن جلسه مورد استفاده در درخواست تکمیل خودکار مکان (Legacy)
- پارامتر
fieldsکه فیلدهای داده Place Autocomplete (Legacy) مورد نیاز شما را مشخص میکند
خیر، فقط به آدرس و موقعیت مکانی نیاز دارد
بسته به عملکرد استفاده از قابلیت تکمیل خودکار مکان (Legacy)، API مربوط به ژئوکدینگ میتواند گزینه مقرونبهصرفهتری نسبت به جزئیات مکان (Legacy) برای برنامه شما باشد. کارایی تکمیل خودکار مکان (Legacy) هر برنامه بسته به اینکه کاربران چه اطلاعاتی را وارد میکنند، برنامه در کجا استفاده میشود و اینکه آیا بهترین شیوههای بهینهسازی عملکرد پیادهسازی شدهاند یا خیر، متفاوت است.
برای پاسخ به سوال زیر، قبل از انتخاب پیشبینی Place Autocomplete (Legacy) در برنامه خود، تجزیه و تحلیل کنید که کاربر به طور متوسط چند کاراکتر تایپ میکند.
آیا کاربران شما به طور متوسط در چهار درخواست یا کمتر، پیشبینی تکمیل خودکار مکان (Legacy) را انتخاب میکنند؟
بله
تکمیل خودکار مکان (Legacy) را به صورت برنامهنویسی شده و بدون توکنهای جلسه پیادهسازی کنید و API مربوط به Geocoding را روی پیشبینی مکان انتخاب شده فراخوانی کنید.
API ژئوکدینگ آدرسها و مختصات طول و عرض جغرافیایی را ارائه میدهد. انجام چهار درخواست تکمیل خودکار به ازای هر درخواست به علاوه یک فراخوانی API ژئوکدینگ در مورد پیشبینی مکان انتخاب شده، کمتر از هزینه تکمیل خودکار مکان (Legacy) به ازای هر جلسه به ازای هر جلسه است. 1
در نظر داشته باشید که از بهترین شیوههای عملکرد استفاده کنید تا به کاربران خود کمک کنید پیشبینی مورد نظر خود را با تعداد کاراکترهای کمتری دریافت کنند.
خیر
از تکمیل خودکار مکان مبتنی بر جلسه (Legacy) به همراه جزئیات مکان (Legacy) استفاده کنید.
از آنجایی که میانگین تعداد درخواستهایی که انتظار دارید قبل از انتخاب پیشبینی تکمیل خودکار مکان (Legacy) توسط کاربر انجام شود، از هزینه قیمتگذاری به ازای هر جلسه بیشتر است، پیادهسازی تکمیل خودکار مکان (Legacy) شما باید از یک توکن جلسه برای هر دو درخواست تکمیل خودکار مکان (Legacy) و درخواست جزئیات مکان (Legacy) مرتبط به ازای هر جلسه استفاده کند. 1
پیادهسازی ویجت
مدیریت جلسه به طور خودکار در ویجتهای جاوا اسکریپت ، اندروید یا iOS تعبیه شده است. این شامل درخواستهای تکمیل خودکار مکان (Legacy) و درخواست جزئیات مکان (Legacy) در پیشبینی انتخاب شده میشود. حتماً پارامتر fields را مشخص کنید تا مطمئن شوید که فقط فیلدهای مورد نیاز خود را درخواست میکنید.
پیادهسازی برنامهریزیشده
از یک توکن جلسه با درخواستهای تکمیل خودکار مکان (Legacy) خود استفاده کنید. هنگام درخواست جزئیات مکان (Legacy) در مورد پیشبینی انتخاب شده، پارامترهای زیر را وارد کنید:
- شناسه مکان از پاسخ تکمیل خودکار مکان (قدیمی)
- توکن جلسه مورد استفاده در درخواست تکمیل خودکار مکان (Legacy)
- پارامتر
fieldsکه فیلدهای داده پایه مانند آدرس و هندسه را مشخص میکند
درخواستهای تکمیل خودکار (قدیمی) را به تعویق بیندازید
شما میتوانید از استراتژیهایی مانند به تأخیر انداختن درخواست تکمیل خودکار مکان (Legacy) تا زمانی که کاربر سه یا چهار کاراکتر اول را تایپ کرده باشد، استفاده کنید تا برنامه شما درخواستهای کمتری ارسال کند. به عنوان مثال، ایجاد درخواستهای تکمیل خودکار مکان (Legacy) برای هر کاراکتر پس از تایپ کاراکتر سوم توسط کاربر به این معنی است که اگر کاربر هفت کاراکتر تایپ کند و سپس پیشبینیای را انتخاب کند که شما برای آن یک درخواست API Geocoding ارسال میکنید، هزینه کل برای 4 تکمیل خودکار مکان (Legacy) به ازای هر درخواست + Geocoding خواهد بود. 1
اگر تأخیر در درخواستها میتواند میانگین درخواستهای برنامهنویسی شما را به زیر چهار برساند، میتوانید از راهنماییهای مربوط به تکمیل خودکار مکان (Legacy) با پیادهسازی API Geocoding پیروی کنید. توجه داشته باشید که تأخیر در درخواستها میتواند توسط کاربری که انتظار دارد با هر ضربه کلید جدید، پیشبینیها را ببیند، به عنوان تأخیر تلقی شود.
استفاده از بهترین شیوههای عملکرد را در نظر بگیرید تا به کاربران خود کمک کنید پیشبینی مورد نظر خود را با تعداد کاراکترهای کمتری دریافت کنند.
برای اطلاع از هزینهها، به لیست قیمتهای پلتفرم نقشههای گوگل مراجعه کنید.
بهترین شیوههای عملکرد
دستورالعملهای زیر روشهای بهینهسازی عملکرد تکمیل خودکار مکان (Legacy) را شرح میدهند:
- محدودیتهای کشور، سوگیری موقعیت مکانی و (برای پیادهسازیهای برنامهنویسیشده) ترجیح زبان را به پیادهسازی تکمیل خودکار مکان (Legacy) خود اضافه کنید. ترجیح زبان با ویجتها لازم نیست زیرا آنها ترجیحات زبان را از مرورگر یا دستگاه تلفن همراه کاربر انتخاب میکنند.
- اگر قابلیت تکمیل خودکار مکان (Legacy) با نقشه همراه باشد، میتوانید مکان را بر اساس نمای نقشه تنظیم کنید.
- در شرایطی که کاربر یکی از پیشبینیهای Place Autocomplete (Legacy) را انتخاب نمیکند، عموماً به این دلیل که هیچکدام از این پیشبینیها آدرس-نتیجه مورد نظر نیستند، میتوانید از ورودی اصلی کاربر برای تلاش جهت دریافت نتایج مرتبطتر استفاده مجدد کنید:
- اگر انتظار دارید کاربر فقط اطلاعات آدرس را وارد کند، از ورودی اصلی کاربر در فراخوانی Geocoding API استفاده مجدد کنید.
- اگر انتظار دارید کاربر برای یک مکان خاص با نام یا آدرس جستجو کند، از درخواست Place Details (Legacy) استفاده کنید. اگر نتایج فقط در یک منطقه خاص مورد انتظار است، از location biasing استفاده کنید.
- کاربرانی که آدرسهای فرعی، مانند آدرسهای واحدها یا آپارتمانهای خاص در یک ساختمان را وارد میکنند. برای مثال، آدرس چکی "Stroupežnického 3191/17, Praha" در تکمیل خودکار مکان (Legacy) پیشبینی جزئی ارائه میدهد.
- کاربرانی که آدرسهایی با پیشوندهای قطعه جادهای مانند «خیابان بیست و نهم، شماره ۲۳-۳۰، کوئینز» در شهر نیویورک یا «بزرگراه کامهامها، شماره ۴۷-۳۸۰، کانئوهه» در جزیره کائوآئی در هاوایی وارد میکنند.
سوگیری مکانی
با ارسال پارامتر location و پارامتر radius ، نتایج را به یک منطقه مشخص شده متمایل میکند. این به Place Autocomplete (Legacy) دستور میدهد که ترجیح دهد نتایج را در منطقه تعریف شده نشان دهد. نتایج خارج از منطقه تعریف شده همچنان ممکن است نمایش داده شوند. میتوانید از پارامتر components برای فیلتر کردن نتایج استفاده کنید تا فقط مکانهای داخل یک کشور مشخص شده را نشان دهید.
محدود کردن موقعیت مکانی
با ارسال پارامتر locationRestriction ، نتایج را به یک ناحیه مشخص محدود کنید.
همچنین میتوانید با اضافه کردن پارامتر strictbounds ، نتایج را به ناحیهای که توسط location و پارامتر radius تعریف شده است، محدود کنید. این به Place Autocomplete (Legacy) دستور میدهد که فقط نتایج درون آن ناحیه را برگرداند.
عیبیابی
اگرچه طیف گستردهای از خطاها ممکن است رخ دهد، اما اکثر خطاهایی که احتمالاً برنامه شما با آنها مواجه میشود، معمولاً ناشی از خطاهای پیکربندی (به عنوان مثال، استفاده از کلید API اشتباه یا پیکربندی نادرست کلید API) یا خطاهای سهمیهبندی (برنامه شما از سهمیه خود فراتر رفته است) هستند. برای اطلاعات بیشتر در مورد سهمیهبندی، به محدودیتهای استفاده مراجعه کنید.
خطاهایی که در استفاده از کنترلهای تکمیل خودکار رخ میدهند، در متد didFailAutocompleteWithError() از پروتکلهای مختلف نماینده بازگردانده میشوند. ویژگی code شیء NSError ارائه شده، روی یکی از مقادیر شمارشی GMSPlacesErrorCode تنظیم شده است.