تعرض خدمة الإكمال التلقائي في حزمة تطوير البرامج (SDK) للأماكن بنظام التشغيل iOS توقعات الأماكن استجابةً لطلبات بحث المستخدم. أثناء إنشاء المستخدمين، تعرض خدمة الإكمال التلقائي اقتراحات لأماكن مثل الأنشطة التجارية والعناوين ورموز Plus Codes ونقاط الاهتمام.
يمكنك إضافة ميزة الإكمال التلقائي إلى تطبيقك بالطرق التالية:
- إضافة عنصر تحكّم في ميزة الإكمال التلقائي في واجهة المستخدم لتوفير وقت التطوير وضمان تجربة متّسقة للمستخدم
- الحصول على توقّعات الأماكن آليًا لإنشاء تجربة مخصّصة للمستخدم
إضافة عنصر تحكّم في الإكمال التلقائي لواجهة المستخدم
عنصر التحكم في واجهة المستخدم للإكمال التلقائي هو مربّع حوار للبحث باستخدام وظيفة
الإكمال التلقائي المضمّنة. ومع إدخال المستخدم لعبارات البحث، يعرض عنصر التحكّم قائمة بالأماكن المتوقّعة للاختيار منها. عندما يختار المستخدم أحد الاختيارات، يتم عرض مثيل GMSPlace
، والذي يمكن أن يستخدمه تطبيقك بعد ذلك للحصول على تفاصيل حول المكان المحدّد.
يمكنك إضافة عنصر التحكم في الإكمال التلقائي لواجهة المستخدم إلى تطبيقك بالطرق التالية:
إضافة عنصر تحكّم في وضع ملء الشاشة
استخدِم عنصر التحكّم بملء الشاشة عندما تريد سياقًا مشروطًا، حيث تحل واجهة مستخدم الإكمال التلقائي محل واجهة مستخدم تطبيقك مؤقتًا إلى أن يختار المستخدم ذلك. توفّر فئة
GMSAutocompleteViewController
هذه الوظيفة. عندما يختار المستخدم مكانًا، يتلقى تطبيقك معاودة اتصال.
لإضافة عنصر تحكّم في وضع ملء الشاشة إلى تطبيقك:
- يمكنك إنشاء عنصر واجهة مستخدم في تطبيقك الرئيسي لتشغيل عنصر التحكم في الإكمال التلقائي لواجهة المستخدم،
على سبيل المثال، معالِج اللمس على
UIButton
. - نفِّذ البروتوكول
GMSAutocompleteViewControllerDelegate
في وحدة التحكم الرئيسية. - أنشِئ نسخة افتراضية من
GMSAutocompleteViewController
وخصِّص وحدة التحكّم الرئيسية للعرض كمفوّض. - أنشئ
GMSPlaceField
لتحديد أنواع بيانات الأماكن التي تريد عرضها. - أضِف
GMSAutocompleteFilter
لتقييد طلب البحث بنوع محدّد من الأماكن. - يمكنك مشاركة عرض
GMSAutocompleteViewController
باستخدام[self presentViewController...]
. - يمكنك اختيار المستخدم في طريقة التفويض
didAutocompleteWithPlace
. - إغلاق وحدة التحكُّم في طرق تفويض
didAutocompleteWithPlace
وdidFailAutocompleteWithError
وwasCancelled
يوضّح المثال التالي طريقة محتملة لإطلاق
GMSAutocompleteViewController
استجابةً للمستخدم الذي ينقر على زر.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { override func viewDidLoad() { makeButton() } // Present the Autocomplete view controller when the button is pressed. @objc func autocompleteClicked(_ sender: UIButton) { let autocompleteController = GMSAutocompleteViewController() autocompleteController.delegate = self // Specify the place data types to return. let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) | UInt(GMSPlaceField.placeID.rawValue))! autocompleteController.placeFields = fields // Specify a filter. let filter = GMSAutocompleteFilter() filter.types = [.address] autocompleteController.autocompleteFilter = filter // Display the autocomplete view controller. present(autocompleteController, animated: true, completion: nil) } // Add a button to the view. func makeButton() { let btnLaunchAc = UIButton(frame: CGRect(x: 5, y: 150, width: 300, height: 35)) btnLaunchAc.backgroundColor = .blue btnLaunchAc.setTitle("Launch autocomplete", for: .normal) btnLaunchAc.addTarget(self, action: #selector(autocompleteClicked), for: .touchUpInside) self.view.addSubview(btnLaunchAc) } } extension ViewController: GMSAutocompleteViewControllerDelegate { // Handle the user's selection. func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) { print("Place name: \(place.name)") print("Place ID: \(place.placeID)") print("Place attributions: \(place.attributions)") dismiss(animated: true, completion: nil) } func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) { // TODO: handle the error. print("Error: ", error.localizedDescription) } // User canceled the operation. func wasCancelled(_ viewController: GMSAutocompleteViewController) { dismiss(animated: true, completion: nil) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
#import "ViewController.h" @import GooglePlaces; @interface ViewController () <GMSAutocompleteViewControllerDelegate> @end @implementation ViewController { GMSAutocompleteFilter *_filter; } - (void)viewDidLoad { [super viewDidLoad]; [self makeButton]; } // Present the autocomplete view controller when the button is pressed. - (void)autocompleteClicked { GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init]; acController.delegate = self; // Specify the place data types to return. GMSPlaceField fields = (GMSPlaceFieldName | GMSPlaceFieldPlaceID); acController.placeFields = fields; // Specify a filter. _filter = [[GMSAutocompleteFilter alloc] init]; _filter.types = @[ kGMSPlaceTypeBank ]; acController.autocompleteFilter = _filter; // Display the autocomplete view controller. [self presentViewController:acController animated:YES completion:nil]; } // Add a button to the view. - (void)makeButton{ UIButton *btnLaunchAc = [UIButton buttonWithType:UIButtonTypeCustom]; [btnLaunchAc addTarget:self action:NSSelectorFromString(@"autocompleteClicked") forControlEvents:UIControlEventTouchUpInside]; [btnLaunchAc setTitle:@"Launch autocomplete" forState:UIControlStateNormal]; btnLaunchAc.frame = CGRectMake(5.0, 150.0, 300.0, 35.0); btnLaunchAc.backgroundColor = [UIColor blueColor]; [self.view addSubview:btnLaunchAc]; } // Handle the user's selection. - (void)viewController:(GMSAutocompleteViewController *)viewController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place ID %@", place.placeID); NSLog(@"Place attributions %@", place.attributions.string); } - (void)viewController:(GMSAutocompleteViewController *)viewController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // User canceled the operation. - (void)wasCancelled:(GMSAutocompleteViewController *)viewController { [self dismissViewControllerAnimated:YES completion:nil]; } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; } @end
إضافة وحدة تحكُّم في النتائج
استخدِم وحدة تحكُّم النتائج إذا أردت المزيد من التحكُّم في واجهة مستخدم إدخال النص. تعمل وحدة التحكُّم في النتائج على تبديل إمكانية رؤية قائمة النتائج بشكل ديناميكي استنادًا إلى تركيز واجهة المستخدم على الإدخال.
لإضافة وحدة تحكُّم في النتائج إلى تطبيقك:
- أنشِئ
GMSAutocompleteResultsViewController
. - نفِّذ بروتوكول
GMSAutocompleteResultsViewControllerDelegate
في وحدة تحكُّم العرض الرئيسي وحدِّد وحدة التحكُّم الرئيسية للعرض كموقع مفوَّض. - يمكنك إنشاء عنصر
UISearchController
، وتمريره إلىGMSAutocompleteResultsViewController
كوسيطة للتحكّم في النتائج. - اضبط السمة
GMSAutocompleteResultsViewController
على أنها السمةsearchResultsUpdater
للسمةUISearchController
. - أضِف
searchBar
إلىUISearchController
إلى واجهة المستخدم الخاصة بتطبيقك. - يمكنك اختيار المستخدم في طريقة التفويض
didAutocompleteWithPlace
.
هناك عدة طرق لوضع شريط البحث في UISearchController
ضمن
واجهة مستخدم تطبيقك:
- إضافة شريط بحث إلى شريط التنقّل
- إضافة شريط بحث إلى أعلى العرض
- إضافة شريط بحث باستخدام النتائج المنبثقة
إضافة شريط البحث إلى شريط التنقل
يوضّح مثال الرمز التالي إضافة وحدة تحكّم النتائج وإضافة searchBar
إلى شريط التنقّل والتعامل مع اختيار المستخدم:
Swift
class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Put the search bar in the navigation bar. searchController?.searchBar.sizeToFit() navigationItem.titleView = searchController?.searchBar // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Prevent the navigation bar from being hidden when searching. searchController?.hidesNavigationBarDuringPresentation = false } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Put the search bar in the navigation bar. [_searchController.searchBar sizeToFit]; self.navigationItem.titleView = _searchController.searchBar; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Prevent the navigation bar from being hidden when searching. _searchController.hidesNavigationBarDuringPresentation = NO; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { _searchController.active = NO; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
إضافة شريط بحث إلى أعلى أحد العروض
يوضّح مثال الرمز التالي إضافة searchBar
إلى أعلى طريقة العرض.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController let subView = UIView(frame: CGRect(x: 0, y: 65.0, width: 350.0, height: 45.0)) subView.addSubview((searchController?.searchBar)!) view.addSubview(subView) searchController?.searchBar.sizeToFit() searchController?.hidesNavigationBarDuringPresentation = false // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 65.0, 250, 50)]; [subView addSubview:_searchController.searchBar]; [_searchController.searchBar sizeToFit]; [self.view addSubview:subView]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
يُخفي UISearchController
تلقائيًا شريط التنقل عند مشاركة العرض (يمكن إيقاف ذلك). وفي الحالات التي يكون فيها شريط التنقل مرئيًا ومبهمًا، لا يحدّد UISearchController
موضع الإعلان بشكل صحيح.
يمكنك استخدام الرمز التالي كحل بديل:
Swift
navigationController?.navigationBar.translucent = false searchController?.hidesNavigationBarDuringPresentation = false // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = true self.edgesForExtendedLayout = .top
Objective-C
self.navigationController.navigationBar.translucent = NO; _searchController.hidesNavigationBarDuringPresentation = NO; // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = YES; self.edgesForExtendedLayout = UIRectEdgeTop;
إضافة شريط بحث باستخدام النتائج المنبثقة
يوضّح مثال الرمز التالي وضع شريط البحث على يسار شريط التنقل، وعرض النتائج في نافذة منبثقة.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. searchController?.searchBar.frame = (CGRect(x: 0, y: 0, width: 250.0, height: 44.0)) navigationItem.rightBarButtonItem = UIBarButtonItem(customView: (searchController?.searchBar)!) // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Keep the navigation bar visible. searchController?.hidesNavigationBarDuringPresentation = false searchController?.modalPresentationStyle = .popover } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. _searchController.searchBar.frame = CGRectMake(0, 0, 250.0f, 44.0f); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_searchController.searchBar]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Keep the navigation bar visible. _searchController.hidesNavigationBarDuringPresentation = NO; _searchController.modalPresentationStyle = UIModalPresentationPopover; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
استخدام مصدر بيانات الجدول
إذا كان تطبيقك يحتوي على واجهة مستخدم نصية مخصّصة للبحث، يمكنك استخدام فئة GMSAutocompleteTableDataSource
للاستفادة من عرض الجدول الذي يعرض النتائج في وحدة التحكُّم في العرض.
لاستخدام GMSAutocompleteTableDataSource
كمصدر البيانات وتفويض UITableView
في وحدة تحكُّم الملف الشخصي:
- نفِّذ البروتوكولَين
GMSAutocompleteTableDataSourceDelegate
وUISearchBarDelegate
في وحدة التحكُّم في العرض. - أنشئ مثيل
GMSAutocompleteTableDataSource
وخصِّص وحدة تحكُّم العرض كموقع مفوَّض. - اضبط
GMSAutocompleteTableDataSource
كمصدر البيانات وتفويض السمات لمثيلUITableView
في وحدة التحكم في العرض. - في معالج إدخال نص البحث، اطلب
sourceTextHasChanged
علىGMSAutocompleteTableDataSource
. - يمكن التعامل مع اختيار المستخدم في طريقة تفويض
didAutocompleteWithPlace
. - إغلاق وحدة التحكُّم في طرق تفويض
didAutocompleteWithPlace
وdidFailAutocompleteWithError
wasCancelled
يوضّح مثال الرمز التالي استخدام الفئة
GMSAutocompleteTableDataSource
لزيادة طريقة عرض الجدول UIViewController
عند إضافة UISearchBar
بشكل منفصل.
Swift
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import GooglePlaces import UIKit class PlaceAutocompleteViewController: UIViewController { private var tableView: UITableView! private var tableDataSource: GMSAutocompleteTableDataSource! override func viewDidLoad() { super.viewDidLoad() let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: self.view.frame.size.width, height: 44.0)) searchBar.delegate = self view.addSubview(searchBar) tableDataSource = GMSAutocompleteTableDataSource() tableDataSource.delegate = self tableView = UITableView(frame: CGRect(x: 0, y: 64, width: self.view.frame.size.width, height: self.view.frame.size.height - 44)) tableView.delegate = tableDataSource tableView.dataSource = tableDataSource view.addSubview(tableView) } } extension PlaceAutocompleteViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // Update the GMSAutocompleteTableDataSource with the search text. tableDataSource.sourceTextHasChanged(searchText) } } extension PlaceAutocompleteViewController: GMSAutocompleteTableDataSourceDelegate { func didUpdateAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator off. UIApplication.shared.isNetworkActivityIndicatorVisible = false // Reload table data. tableView.reloadData() } func didRequestAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator on. UIApplication.shared.isNetworkActivityIndicatorVisible = true // Reload table data. tableView.reloadData() } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didAutocompleteWith place: GMSPlace) { // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didFailAutocompleteWithError error: Error) { // Handle the error. print("Error: \(error.localizedDescription)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didSelect prediction: GMSAutocompletePrediction) -> Bool { return true } }
Objective-C
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #import "PlaceAutocompleteViewController.h" @import GooglePlaces; @import UIKit; @interface PlaceAutocompleteViewController () <GMSAutocompleteTableDataSourceDelegate, UISearchBarDelegate> @end @implementation PlaceAutocompleteViewController { UITableView *tableView; GMSAutocompleteTableDataSource *tableDataSource; } - (void)viewDidLoad { [super viewDidLoad]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)]; searchBar.delegate = self; [self.view addSubview:searchBar]; tableDataSource = [[GMSAutocompleteTableDataSource alloc] init]; tableDataSource.delegate = self; tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 44)]; tableView.delegate = tableDataSource; tableView.dataSource = tableDataSource; [self.view addSubview:tableView]; } #pragma mark - GMSAutocompleteTableDataSourceDelegate - (void)didUpdateAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator off. UIApplication.sharedApplication.networkActivityIndicatorVisible = NO; // Reload table data. [tableView reloadData]; } - (void)didRequestAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator on. UIApplication.sharedApplication.networkActivityIndicatorVisible = YES; // Reload table data. [tableView reloadData]; } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didAutocompleteWithPlace:(GMSPlace *)place { // Do something with the selected place. NSLog(@"Place name: %@", place.name); NSLog(@"Place address: %@", place.formattedAddress); NSLog(@"Place attributions: %@", place.attributions); } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didFailAutocompleteWithError:(NSError *)error { // Handle the error NSLog(@"Error %@", error.description); } - (BOOL)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didSelectPrediction:(GMSAutocompletePrediction *)prediction { return YES; } #pragma mark - UISearchBarDelegate - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { // Update the GMSAutocompleteTableDataSource with the search text. [tableDataSource sourceTextHasChanged:searchText]; } @end
تخصيص ألوان النص والخلفية
يمكنك ضبط ألوان كل النصوص والخلفيات في عنصر التحكّم في ميزة "الإكمال التلقائي" لواجهة المستخدم، وذلك لجعل الأداة تتطابق مع المظهر المرئي لتطبيقك عن كثب. هناك طريقتان لضبط ألوان واجهة المستخدم:
- باستخدام بروتوكول UIUI على نظام التشغيل iOS إلى عناصر التحكم في واجهة المستخدم بنمط عام، حيثما أمكن. وتنطبق هذه الإعدادات على العديد من عناصر تحكم واجهة المستخدم، ولكن ليس كلها.
- باستخدام طرق حزم تطوير البرامج (SDK) في فئات التطبيقات المصغّرة، يمكنك ضبط السمات التي لا تتوافق مع بروتوكول UIالمظهر.
عادةً ما سيستخدم تطبيقك جزءًا من بروتوكول شكل الظهور في واجهة المستخدم وطرق 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 . |
شعار "بواسطة Google"، صورة سحابة حزينة | لا ينطبق | يتم تلقائيًا اختيار النسخة البيضاء أو الرمادية استنادًا إلى تباين الخلفية. |
عدسة مكبرة ورموز نصية واضحة في حقل نص "شريط البحث" | لا ينطبق | لتحديد نمط، عليك استبدال الصور التلقائية بصور اللون المطلوب. |
استخدام بروتوكول UIالمظهر
يمكنك استخدام بروتوكول UIالمظهر
للحصول على الخادم الوكيل للشكل لعنصر في واجهة مستخدم محدد، والذي يمكنك استخدامه بعد ذلك
لتحديد لون عنصر واجهة المستخدم. وعند إجراء تعديل، تتأثر جميع مثيلات عنصر واجهة مستخدم معيّن. على سبيل المثال، يؤدي المثال التالي في جميع أنحاء العالم إلى تغيير لون النص إلى UITextField
إلى الأخضر عندما تكون متضمّنة في UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
للحصول على مزيد من المعلومات حول تحديد قيم الألوان، يمكنك الاطّلاع على مرجع فئة UIUI.
تعرض مقتطفات الرمز التالية جميع أوامر الخادم الوكيل التي تحتاج إلى استخدامها لنمط كل شيء في عنصر التحكم في الإكمال التلقائي لواجهة المستخدم في وضع ملء الشاشة. أضِف هذا الرمز
إلى الطريقة 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;
إعداد خصائص نمط التحكم في واجهة المستخدم
تحتوي مجموعة فرعية من عناصر التحكّم في واجهة المستخدم على خصائص لا تتأثر ببروتوكول واجهة UI ، لذلك يجب ضبطها مباشرةً. يوضّح مثال الرمز التالي
تحديد ألوان الواجهة والخلفية، وتطبيقها على مثيل عنصر تحكّم
واجهة المستخدم باسم 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:
للحصول على قائمة بأسماء الأماكن و/أو العناوين المتوقّعة، عليك أولاً تحديد قيمة {9/}PLACESClient ثمّ اتّباع الطريقة
GMSPlacesClient findAutocompletePredictionsFromQuery:
مع المعلَمات التالية:
- سلسلة
autocompleteQuery
تحتوي على النص الذي كتبه المستخدم. GMSAutocompleteSessionToken
، الذي يتم استخدامه لتحديد كل جلسة فردية. يجب أن يمرّر تطبيقك الرمز المميّز نفسه لكل مكالمة طلب إكمال تلقائي، ثم يمرّر هذا الرمز المميّز مع رقم تعريف المكان في المكالمة التالية إلىfetchPlacefromPlaceID:
لاسترداد تفاصيل المكان للمكان الذي اختاره المستخدم.GMSAutocompleteFilter
لإجراء ما يلي:- الانحياز أو تقييد النتائج على منطقة معيّنة.
- حصر النتائج على نوع مكان محدّد.
- يعمل كائن
GMSPlaceLocationBias
/Restriction على انحياز النتائج إلى منطقة محددة يتم تحديدها من خلال حدود خطوط الطول والعرض.
- طريقة معاودة الاتصال للتعامل مع عبارات البحث المقترحة المعروضة
تعرض أمثلة الرموز أدناه مكالمة إلى findAutocompletePredictionsFromQuery:
.
Swift
/** * Create a new session token. Be sure to use the same token for calling * findAutocompletePredictions, as well as the subsequent place details request. * This ensures that the user's query and selection are billed as a single session. */ let token = GMSAutocompleteSessionToken.init() // Create a type filter. let filter = GMSAutocompleteFilter() filter.types = [.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); } } }];
تستدعي واجهة برمجة التطبيقات طريقة معاودة الاتصال المحدّدة، مع ضبط صفيف في
كائنات GMSAutocompletePrediction
.
يحتوي كل عنصر من عناصر GMSAutocompletePrediction
على المعلومات التالية:
attributedFullText
: النص الكامل لعبارة البحث المقترَحة، على شكلNSAttributedString
. على سبيل المثال، "دار أوبرا سيدني، سيدني، نيو ساوث ويلز، أستراليا". ويتضمّن كل نطاق نصي يتطابق مع إدخال المستخدم سمةkGMSAutocompleteMatchAttribute
. ويمكنك استخدام هذه السمة لتمييز النص المُطابق في طلب البحث الذي يقدّمه المستخدم، على النحو الموضّح أدناه.placeID
: معرّف المكان للمكان المتوقّع معرّف المكان هو معرّف نصي يحدِّد مكانًا بشكل فريد. ولمزيد من المعلومات عن أرقام تعريف الأماكن، اطّلِع على نظرة عامة على رقم تعريف المكان.distanceMeters
– مسافة الخط المستقيم منorigin
المحدّد إلى الوجهة. وإذا لم يتم ضبط السمةorigin
، لن يتم عرض قيمة المسافة.
يوضّح مثال الرمز التالي كيفية تمييز أجزاء النتيجة المطابقة للنص في طلب بحث المستخدم، وذلك باستخدام enumerateAttribute
:
Swift
let regularFont = UIFont.systemFont(ofSize: UIFont.labelFontSize) let boldFont = UIFont.boldSystemFont(ofSize: UIFont.labelFontSize) let bolded = prediction.attributedFullText.mutableCopy() as! NSMutableAttributedString bolded.enumerateAttribute(kGMSAutocompleteMatchAttribute, in: NSMakeRange(0, bolded.length), options: []) { (value, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in let font = (value == nil) ? regularFont : boldFont bolded.addAttribute(NSFontAttributeName, value: font, range: range) } label.attributedText = bolded
Objective-C
UIFont *regularFont = [UIFont systemFontOfSize:[UIFont labelFontSize]]; UIFont *boldFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; NSMutableAttributedString *bolded = [prediction.attributedFullText mutableCopy]; [bolded enumerateAttribute:kGMSAutocompleteMatchAttribute inRange:NSMakeRange(0, bolded.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { UIFont *font = (value == nil) ? regularFont : boldFont; [bolded addAttribute:NSFontAttributeName value:font range:range]; }]; label.attributedText = bolded;
استخدام أداة الجلب
إذا كنت تريد إنشاء عنصر تحكّم في ميزة الإكمال التلقائي من البداية، يمكنك استخدام
GMSAutocompleteFetcher
،
الذي يؤدي إلى التفاف طريقة autocompleteQuery
على GMSPlacesClient
.
يتم تقييد عملية الجلب التي تعرض طلب البحث، ولا تعرض سوى نتائج أحدث نص بحث
تم إدخاله مؤخرًا. لا يوفّر أي عناصر لواجهة المستخدم.
لتطبيق GMSAutocompleteFetcher
،
اتّبِع الخطوات التالية:
- طبِّق بروتوكول
GMSAutocompleteFetcherDelegate
. - أنشِئ عنصر
GMSAutocompleteFetcher
. - اتصل بـ
sourceTextHasChanged
في أداة الجلب أثناء أنواع المستخدمين. - التعامل مع التوقعات والأخطاء باستخدام طريقتَي البروتوكول
didAutcompleteWithPredictions
وdidFailAutocompleteWithError
يوضّح مثال الرمز التالي استخدام أداة الجلب لإظهار إدخال المستخدم
وعرض الأماكن المطابقة في عرض نصي. تم حذف وظيفة اختيار المكان. FetcherSampleViewController
مشتق من UIViewController
في
FetchSampleViewController.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
الرموز المميزة للجلسة
تعمل الرموز المميّزة للجلسة على تجميع طلبات البحث ومراحل الاختيار في عملية الإكمال التلقائي للمستخدم في جلسة منفصلة لأغراض الفوترة. وتبدأ الجلسة عندما يبدأ المستخدم في كتابة طلب بحث، وتنتهي عند اختيار مكان. يمكن أن تحتوي كل جلسة على طلبات بحث متعددة، يتبعها اختيار مكان واحد. بعد انتهاء الجلسة، يصبح الرمز المميّز غير صالح، ويجب أن ينشئ تطبيقك رمزًا مميّزًا جديدًا لكل جلسة. ننصح باستخدام الرموز المميّزة للجلسة في جميع جلسات الإكمال التلقائي المبرمَج (عند استخدام وحدة التحكّم بملء الشاشة، أو وحدة تحكّم النتائج، ستتولّى واجهة برمجة التطبيقات هذا الإجراء تلقائيًا).
تستخدم حزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل iOS علامة GMSAutocompleteSessionToken
لتحديد كل جلسة. يجب أن يمرّر التطبيق رمزًا مميزًا جديدًا للجلسة عند بدء كل جلسة جديدة، ثم يمرّر ذلك الرمز المميّز نفسه، مع معرّف المكان، في المكالمة التالية إلى fetchPlacefromPlaceID:
لاسترداد تفاصيل المكان للمكان الذي اختاره المستخدم.
مزيد من المعلومات حول الرموز المميّزة للجلسة
استخدِم الرمز التالي لإنشاء رمز مميّز جديد للجلسة:
let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()
حدود الاستخدام
- يخضع استخدام طريقة
GMSPlacesClient findAutocompletePredictionsFromQuery
لحدود طلبات البحث متعددة المستويات. يمكنك الاطّلاع على المستندات حول حدود الاستخدام.
عرض عمليات تحديد المصدر في تطبيقك
- إذا كان تطبيقك يستخدم خدمة الإكمال التلقائي آليًا، يجب أن تعرض واجهة المستخدم الإحالة "بواسطة Google"، أو تظهر ضمن خريطة تحمل علامة Google التجارية.
- إذا كان تطبيقك يستخدم عنصر التحكّم في ميزة "الإكمال التلقائي" في واجهة المستخدم، ليس عليك اتّخاذ أي إجراء إضافي (يتم عرض الإحالة المطلوبة تلقائيًا).
- إذا أردت استرداد معلومات إضافية عن المكان وعرضها بعد الحصول على مكان من خلال رقم التعريف، يجب عرض معلومات الإحالة من جهات خارجية أيضًا.
لمزيد من التفاصيل، يمكنك الاطّلاع على مستندات الإحالات.
التحكم في مؤشر نشاط الشبكة
للتحكّم في مؤشر نشاط الشبكة في شريط حالة التطبيقات يجب تنفيذ طرق التفويض الاختيارية المناسبة لفئة الإكمال التلقائي التي تستخدمها وتفعيل مؤشر الشبكة وإيقافه بنفسك.
- بالنسبة إلى
GMSAutocompleteViewController
، عليك تنفيذ طريقتَي التفويضdidRequestAutocompletePredictions:
وdidUpdateAutocompletePredictions:
. - بالنسبة إلى
GMSAutocompleteResultsViewController
، عليك تنفيذ طريقتَي التفويضdidRequestAutocompletePredictionsForResultsController:
وdidUpdateAutocompletePredictionsForResultsController:
. - بالنسبة إلى
GMSAutocompleteTableDataSource
، عليك تنفيذ طريقتَي التفويضdidRequestAutocompletePredictionsForTableDataSource:
وdidUpdateAutocompletePredictionsForTableDataSource:
.
من خلال تنفيذ هذه الطرق وضبط [UIApplication sharedApplication].networkActivityIndicatorVisible
على YES
وNO
على التوالي، سيكون شريط الحالة مطابقًا بشكل صحيح
لواجهة المستخدم الخاصة بالإكمال التلقائي.
تقييد نتائج الإكمال التلقائي
يمكنك ضبط عنصر التحكّم في الإكمال التلقائي لواجهة المستخدم لحصر النتائج بمنطقة جغرافية معيّنة، و/أو فلترة النتائج حسب نوع واحد أو أكثر من الأماكن، أو إلى بلد أو بلدان محدّدة. لتقييد النتائج، يمكنك إجراء ما يلي:
- لإعطاء الأفضلية لنتائج الانحياز داخل المنطقة المحددة، اضبط
locationBias
علىGMSAutocompleteFilter
(قد يستمر عرض بعض النتائج من خارج المنطقة المحددة). إذا تم ضبطlocationRestriction
أيضًا، سيتم تجاهلlocationBias
. لكي يتم عرض النتائج (حصر) ضمن المنطقة المحدّدة فقط، اضبط
locationRestriction
علىGMSAutocompleteFilter
(سيتم عرض النتائج داخل المنطقة المحدّدة فقط).- ملاحظة: يتم تطبيق هذا القيد على المسارات بالكامل فقط، ويمكن عرض النتائج الاصطناعية التي تقع خارج الحدود المستطيلة استنادًا إلى مسار يتداخل مع تقييد الموقع الجغرافي.
لعرض النتائج التي تتوافق مع نوع مكان معيّن فقط، اضبط
types
علىGMSAutocompleteFilter
(على سبيل المثال، يؤدي تحديد Typeفلتر.ADDRESS إلى عرض الأداة لنتائج مع عنوان دقيق فقط).لعرض النتائج فقط في خمسة بلدان محدّدة، اضبط السمة
countries
على السمةGMSAutocompleteFilter
.
نتائج التحيّز في منطقة معيّنة
لإعطاء الأفضلية لنتائج (الانحياز) ضمن المنطقة المحددة، اضبط locationBias
على GMSAutocompleteFilter
، كما هو موضّح هنا:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);
حصر النتائج على منطقة معيّنة
لعرض النتائج فقط (حظر) ضمن المنطقة المحدّدة، اضبط
locationRestriction
على GMSAutocompleteFilter
، كما هو موضّح هنا:
northEast = CLLocationCoordinate2DMake(39.0, -95.0);
southWest = CLLocationCoordinate2DMake(37.5, -100.0);
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.locationRestriction = GMSPlaceRectangularLocationOption(northEast, southWest);
فلترة النتائج حسب البلد
لفلترة النتائج خلال ما يصل إلى خمسة بلدان محدّدة، اضبط countries
على GMSAutocompleteFilter
، كما هو موضّح أدناه:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.countries = @[ @"au", @"nz" ];
فلترة النتائج حسب نوع المكان أو مجموعة الأنواع
يمكنك حصر النتائج بنوع معيّن أو مجموعة من الأنواع من خلال ضبط السمة types
على GMSAutoCompleteFilter
.
استخدِم هذه السمة لتحديد الفلاتر المُدرَجة في الجداول 1 و2 و3 في أنواع الأماكن. إذا لم يتم تحديد أي شيء، سيتم عرض جميع الأنواع.
لتحديد نوع أو فلتر مجموعة أنواع:
استخدِم السمة
types
لتحديد ما يصل إلى خمس قيم type من الجدول 1 والجدول 2 الذي يظهر في أنواع الأماكن. يتم تحديد قيم النوع من خلال الثوابت فيGMSPlaceType
.استخدِم السمة
types
لتحديد مجموعة أنواع من الجدول 3 المعروض في أنواع الأماكن. يتم تحديد قيم جمع الأنواع من خلال الثوابت فيGMSPlaceType
.يُسمح فقط بنوع واحد من الجدول 3 في الطلب. إذا حددت قيمة من الجدول 3، لا يمكنك تحديد قيمة من الجدول 1 أو الجدول 2. وإذا حدث ذلك، حدث خطأ.
على سبيل المثال، لعرض النتائج التي تتوافق مع نوع مكان معيّن فقط، اضبط
types
على GMSAutocompleteFilter
. يوضّح المثال التالي إعداد
الفلتر لعرض النتائج ذات العنوان الدقيق فقط:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
تحسين عمليات الإكمال التلقائي للأماكن
يصف هذا القسم أفضل الممارسات لمساعدتك في الاستفادة إلى أقصى حد من خدمة "الإكمال التلقائي" للأماكن.
في ما يلي بعض الإرشادات العامة:
- إنّ أسرع طريقة لتطوير واجهة المستخدم صالحة هي استخدام أداة الإكمال التلقائي في "خرائط Google" أو حزمة تطوير برامج (SDK) للأماكن في نظام التشغيل Android تطبيق مصغّر تلقائي أو عنصر تحكّم آخر في حزمة تطوير البرامج (SDK) لعرض الأماكن لأجهزة iOS. التحكّم بالإكمال التلقائي لواجهة المستخدم
- اكتسِب فهمًا أساسيًا لحقول البيانات الخاصة بميزة "الإكمال التلقائي" من الأماكن من البداية.
- إنّ حقول انحياز الموقع الجغرافي وقيود الموقع الجغرافي اختيارية، ولكن يمكن أن يكون لها تأثير كبير في أداء الإكمال التلقائي.
- استخدِم التعامل مع الأخطاء للتأكّد من انخفاض مستوى أداء تطبيقك بشكلٍ سليم إذا كانت واجهة برمجة التطبيقات تعرض خطأً.
- احرص على أن يتعامل تطبيقك مع عدم توفّر أي خيار وأن يوفّر للمستخدمين طريقة للمتابعة.
أفضل ممارسات تحسين التكلفة
تحسين التكلفة الأساسية
لتحسين تكلفة استخدام خدمة "الإكمال التلقائي" للأماكن، استخدِم أقنعة الحقل في "تفاصيل المكان" والتطبيقات المصغّرة الخاصة بميزة "الإكمال التلقائي" لعرض حقول بيانات الأماكن التي تحتاج إليها فقط.
تحسين التكلفة المتقدّم
يمكنك التنفيذ الآلي للإكمال التلقائي للأماكن من أجل الوصول إلى التسعير حسب الطلب وطلب نتائج واجهة برمجة التطبيقات للترميز الجغرافي بشأن المكان المحدّد بدلاً من تفاصيل المكان. إنّ سعر كل طلب، مع واجهة برمجة التطبيقات الجغرافية، هو أكثر فعالية من حيث التكلفة من السعر لكل جلسة (مستند إلى الجلسة) إذا تم استيفاء الشرطين التاليين:
- إذا كنت بحاجة فقط إلى خط العرض/خط الطول أو عنوان المكان المحدّد للمستخدم، تقدّم واجهة برمجة التطبيقات للترميز الجغرافي هذه المعلومات بأقل من طلب بشأن تفاصيل المكان.
- إذا اختار المستخدمون عبارة بحث مقترَحة تلقائيًا ضمن متوسط أربعة عبارات بحث مقترَحة أو أقل، قد يكون سعر كل طلب أكثر فعالية من حيث التكلفة لكل جلسة.
هل يتطلب تطبيقك أي معلومات غير العنوان وخط العرض/خط الطول للتوقّع المحدّد؟
نعم، بحاجة إلى مزيد من التفاصيل
استخدام ميزة "الإكمال التلقائي" المستندة إلى الجلسات مع تفاصيل المكان.
بما أنّ طلبك يتطلّب تفاصيل المكان، مثل اسم المكان أو حالة النشاط التجاري أو ساعات العمل، يجب أن يستخدم تنفيذ ميزة "الإكمال التلقائي" للمكان رمزًا مميّزًا للجلسة (تلقائيًا أو مضمّنًا في أدوات Android أو Android أو iOS) بتكلفة إجمالية تبلغ 0.017 دولار أمريكي (أو ما يعادلها بالعملة المحلية) لكل جلسة بالإضافة إلى رموز تخزين البيانات للأماكن
تنفيذ الأدوات
يتم دمج إدارة الجلسات تلقائيًا في أدوات JavaScript أو Android أو iOS. ويتضمّن ذلك كلاً من طلبات الإكمال التلقائي للأماكن وطلب تفاصيل المكان على عبارة البحث المقترَحة التي تم اختيارها. تأكّد من تحديد المعلَمة fields
للتأكّد من أنك تطلب فقط حقول بيانات المكان التي تحتاج إليها.
التنفيذ الآلي
استخدِم الرمز المميّز للجلسة مع طلبات الإكمال التلقائي للأماكن. عند طلب تفاصيل المكان عن عبارة البحث المقترحة المحدّدة، أدرِج المعلّمات التالية:
- رقم تعريف المكان من الردّ التلقائي المتعلّق بالمكان
- الرمز المميز للجلسة المستخدم في طلب الإكمال التلقائي للأماكن
- المعلَمة
fields
التي تحدّد حقول بيانات المكان التي تحتاج إليها
لا، يحتاج فقط إلى العنوان والموقع
يمكن أن تكون واجهة برمجة التطبيقات للترميز الجغرافي خيارًا أكثر فعالية من حيث التكلفة مقارنةً بتفاصيل المكان المتعلقة بتطبيقك، وذلك استنادًا إلى أداء استخدامك لميزة "الإكمال التلقائي" للمكان. تختلف كفاءة الإكمال التلقائي لكل تطبيق بناءً على ما يدخله المستخدمون ومكان استخدام التطبيق وما إذا تم تنفيذ أفضل ممارسات تحسين الأداء.
للإجابة عن السؤال التالي، يجب تحليل عدد الأحرف التي يكتبها المستخدم في المتوسط قبل اختيار عبارة بحث مقترحة من خلال ميزة "الإكمال التلقائي" في تطبيقك.
هل يختار المستخدمون عبارات بحث مقترحة من خلال ميزة "الإكمال التلقائي للأماكن" في أربعة طلبات أو أقل في المتوسط؟
نعم
تنفيذ ميزة "الإكمال التلقائي" للأماكن من دون استخدام الرموز المميزة للجلسة واستدعاء واجهة برمجة التطبيقات للترميز الجغرافي في توقّع المكان المحدّد
تقدّم واجهة برمجة التطبيقات للترميز الجغرافي عناوين وإحداثيات خطوط العرض/خطوط الطول مقابل 0.005 دولار أمريكي لكل طلب. تبلغ تكلفة أربعة طلبات إكمال تلقائي - لكل طلب 0.01132 دولار أمريكي (أو ما يعادله بالعملة المحلية)، لذا سيكون إجمالي تكلفة أربعة طلبات بالإضافة إلى طلب استدعاء الترميز الجغرافي حول توقعات المكان المختارة هو 0.01632 دولار أمريكي (أو ما يعادله بالعملة المحلية)، وهو أقل من السعر التلقائي الذي يتم تقديمه لكل جلسة بنسبة 0.017 دولار أمريكي (أو ما يعادله بالعملة المحلية) لكل جلسة.1
ننصحك باستخدام أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على التوقّعات التي يبحثون عنها بعدد أقل من الأحرف.
لا
استخدام ميزة "الإكمال التلقائي" المستندة إلى الجلسات مع تفاصيل المكان.
بما أنّ متوسط عدد الطلبات الذي تتوقّع أن تقدّمه قبل أن يحدِّد أحد المستخدمين توقّعًا يتم إكماله تلقائيًا للمكان، فإن تنفيذ هذا الإجراء يجب أن يستخدم رمزًا مميّزًا للجلسة لكل من طلبات "الإكمال التلقائي" للمكان وطلب "تفاصيل المكان" المرتبط بتكلفة إجمالية قدرها 0.017 لكل جلسة.1
تنفيذ الأدوات
يتم دمج إدارة الجلسات تلقائيًا في أدوات JavaScript أو Android أو iOS. ويتضمّن ذلك كلاً من طلبات الإكمال التلقائي للأماكن وطلب تفاصيل المكان على عبارة البحث المقترَحة التي تم اختيارها. تأكّد من تحديد المعلمة fields
لضمان طلب حقول البيانات الأساسية فقط.
التنفيذ الآلي
استخدِم الرمز المميّز للجلسة مع طلبات الإكمال التلقائي للأماكن. عند طلب تفاصيل المكان عن عبارة البحث المقترحة المحدّدة، أدرِج المعلّمات التالية:
- رقم تعريف المكان من الردّ التلقائي المتعلّق بالمكان
- الرمز المميز للجلسة المستخدم في طلب الإكمال التلقائي للأماكن
- معلمة
fields
التي تحدد حقول البيانات الأساسية مثل العنوان والهندسة
ننصحك بتأجيل طلبات الإكمال التلقائي للأماكن
يمكنك استخدام استراتيجيات مثل تأخير طلب الإكمال التلقائي للأماكن إلى أن يكتب المستخدم أول ثلاثة أو أربعة أحرف، ما يتيح تقديم طلبات أقل لك. على سبيل المثال، عند تقديم طلبات الإكمال التلقائي للأماكن لكل حرف بعد كتابة المستخدم للحرف الثالث، يعني ذلك أنه إذا كتب المستخدم سبعة أحرف ثم اختار توقعًا تقدم طلبًا واحدًا لواجهة برمجة تطبيقات ترميز المواقع الجغرافية، ستكون التكلفة الإجمالية 0.01632 دولار أمريكي (4 * 0.00283 إكمال تلقائي لكل طلب + 0.005 دولار للترميز الجغرافي).1
إذا كان تأخّر إرسال الطلبات يمكن أن يظهر لك متوسط طلبك المبرمَج أقل من أربعة، يمكنك اتّباع الإرشادات المتعلقة بتنفيذ الإكمال التلقائي للأماكن من خلال واجهة برمجة التطبيقات الجغرافية. يُرجى العِلم أنّه يمكن اعتبار طلبات التأخير على أنها وقت استجابة من جانب المستخدم الذي قد يتوقّع رؤية توقعات مع كل ضغطة مفتاح جديدة.
ننصحك باستخدام أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على التوقّعات التي يبحثون عنها بعدد أحرف أقل.
-
التكاليف المُدرَجة هنا بالدولار الأمريكي. يُرجى الرجوع إلى صفحة الفوترة في "منصة خرائط Google" للحصول على معلومات كاملة عن الأسعار.
أفضل الممارسات المتعلقة بالأداء
توضّح الإرشادات التالية طرق تحسين أداء الإكمال التلقائي للأماكن:
- يمكنك إضافة قيود على البلدان وانحياز الموقع الجغرافي واللغة المفضّلة (في عمليات التنفيذ الآلية) إلى تنفيذ ميزة "الإكمال التلقائي" من المكان. ليس من الضروري اختيار اللغة المفضّلة مع التطبيقات المصغّرة، لأنّها تختار إعدادات اللغة المفضّلة من متصفّح المستخدم أو جهازه الجوّال.
- إذا كانت ميزة "الإكمال التلقائي" للأماكن مصحوبة بخريطة، يمكنك انحياز الموقع الجغرافي حسب إطار عرض الخريطة.
- في الحالات التي لا يختار فيها المستخدم أحد عبارات البحث المقترَحة ضمن ميزة "الإكمال التلقائي"، بشكلٍ عام، لأنّ أيًّا من عبارات البحث المقترَحة لا يمثّل عنوان النتيجة المطلوب، يمكنك إعادة استخدام الإدخال الأصلي للمستخدم لمحاولة الحصول على نتائج أكثر صلة:
- إذا كنت تتوقع أن يُدخِل المستخدم معلومات العنوان فقط، أعِد استخدام إدخال المستخدم الأصلي في استدعاء واجهة برمجة التطبيقات Geocode API.
- إذا كنت تعتقد أنّ المستخدم يُدخِل طلبات بحث عن مكان معيّن بالاسم أو العنوان، استخدِم طلب بحث عن مكان. وإذا كان من المتوقّع أن تكون النتائج في منطقة معيّنة فقط، استخدِم انحياز الموقع الجغرافي.
- المستخدمون الذين يُدخِلون عناوين مبانٍ فرعية في البلدان التي لا تتوفّر فيها خدمة الإكمال التلقائي للأماكن من العناوين الفرعية، مثل التشيك وإستونيا وليتوانيا على سبيل المثال، يشير العنوان التشيكي "Stroupeznického 3191/17, Praha" إلى توقّع جزئي في الإكمال التلقائي للأماكن.
- المستخدمون الذين يُدخلون عناوين تتضمّن بادئات أجزاء الطريق، مثل "23-30 29 St. Queens" في مدينة نيويورك أو "47 -380 Kamehameha Hwy, Kaneohe" على جزيرة "كواي" في "هاواي".
تحديد المشاكل وحلّها
على الرغم من وجود مجموعة متنوعة من الأخطاء، غالبًا ما تحدث معظم الأخطاء التي من المحتمل أن يواجهها تطبيقك بسبب أخطاء في الإعداد (على سبيل المثال، تم استخدام مفتاح واجهة برمجة التطبيقات غير الصحيح أو تم ضبط مفتاح واجهة برمجة التطبيقات بشكل غير صحيح) أو أخطاء في الحصة (تجاوز تطبيقك تطبيقك). اطّلِع على حدود الاستخدام لمزيد من المعلومات عن الحِصص.
يتم عرض الأخطاء التي تحدث أثناء استخدام عناصر التحكّم في الإكمال التلقائي من خلال
الطريقة didFailAutocompleteWithError()
في بروتوكولات التفويض المختلفة. تم ضبط السمة code
لكائن NSError
المقدَّم على إحدى قيم التعداد GMSPlacesErrorCode
.