تعرض خدمة الإكمال التلقائي في حزمة تطوير برامج الأماكن لنظام التشغيل iOS التوقعات استجابةً لطلبات بحث المستخدم. أثناء كتابة المستخدمين، تعرض خدمة الإكمال التلقائي اقتراحات لأماكن مثل الأنشطة التجارية والعناوين ورموز الجمع ونقاط الاهتمام.
يمكنك إضافة ميزة الإكمال التلقائي إلى تطبيقك بالطرق التالية:
- أضف عنصر تحكم الإكمال التلقائي لواجهة المستخدم لتوفير وقت التطوير وضمان تجربة مستخدم متسقة.
- الحصول على توقّعات حول الأماكن آليًا لتوفير تجربة مستخدِم مخصّصة
إضافة عنصر تحكّم إكمال تلقائي لواجهة المستخدم
عنصر التحكم في واجهة المستخدم للإكمال التلقائي هو مربع حوار بحث به وظيفة الإكمال التلقائي المضمنة. عندما يُدخل المستخدم عبارات بحث، يعرض عنصر التحكّم
قائمة بالأماكن المتوقّعة للاختيار من بينها. عندما يختار المستخدم اختيارًا،
يتم عرض مثيل 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
تخصيص ألوان النص والخلفية
يمكنك ضبط ألوان كل النص والخلفيات في عنصر تحكّم واجهة المستخدم ضمن ميزة "الإكمال التلقائي"، وذلك لجعل الأداة أكثر توافقًا مع المظهر المرئي لتطبيقك. هناك طريقتان لضبط ألوان عناصر التحكم في واجهة المستخدم:
- باستخدام بروتوكول واجهة المستخدم (UIالمظهر) الأصلي في نظام التشغيل iOS لتحديد نمط واجهة المستخدم بشكل عام متى أمكن ذلك. وتنطبق هذه الإعدادات على العديد من عناصر التحكم في واجهة المستخدم، وليس كلها.
- من خلال استخدام طرق حزمة تطوير البرامج (SDK) في فئات الأدوات لضبط الخصائص غير المتوافقة مع بروتوكول واجهة المستخدم.
سيستخدم تطبيقك عادةً مجموعة من بروتوكول واجهة المستخدم وطرق حزمة تطوير البرامج (SDK). يوضح الرسم التخطيطي التالي العناصر التي يمكن تصميمها:
يسرد الجدول التالي جميع عناصر واجهة المستخدم، ويشير إلى كيفية تصميم كل عنصر منها (بروتوكول UIUI أو طريقة SDK).
عنصر في واجهة المستخدم | الطريقة | إرشادات متعلّقة بالموضة |
---|---|---|
درجات لون شريط التنقل (الخلفية) | بروتوكول UIالمظهر | يمكنك الاتصال بـ setBarTintColor على الخادم الوكيل UINavigationBar . |
لون شريط التنقل تلوينًا (علامة إقحام نص شريط البحث وزر "إلغاء") | بروتوكول UIالمظهر | يمكنك الاتصال بـ setTintColor على الخادم الوكيل UINavigationBar . |
لون نص شريط البحث | بروتوكول UIالمظهر | ضبط NSForegroundColorAttributeName في searchBarTextAttributes . |
لون شريط البحث | لا ينطبق | شريط البحث شفاف، وسيتم عرضه كنسخة مظللة من شريط التنقل. |
لون نص العنصر النائب لشريط البحث (نص البحث التلقائي) | بروتوكول UIالمظهر | ضبط NSForegroundColorAttributeName في placeholderAttributes . |
النص الأساسي (يُطبَّق أيضًا على نص الرسالة والخطأ) | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextColor ". |
تمييز النص الأساسي | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextHighlightColor ". |
النص الثانوي | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "secondaryTextColor ". |
نص الرسالة والخطأ | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextColor ". |
خلفية خلية الجدول | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tableCellBackgroundColor ". |
لون فاصل الخلايا في الجدول | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tableCellSeparatorColor ". |
زر "إعادة المحاولة" | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tintColor ". |
مؤشر النشاط (مؤشر سريان العمل) | بروتوكول UIالمظهر | يمكنك الاتصال بـ setColor على الخادم الوكيل UIActivityIndicatorView . |
شعار "مُشغَّل بواسطة Google"، صورة سحابة حزينة | لا ينطبق | ويتم اختيار اللون الأبيض أو الرمادي تلقائيًا بناءً على تباين الخلفية. |
رموز العدسة المكبّرة ورموز النص الواضح في حقل النص في "شريط البحث" | لا ينطبق | لتغيير النمط، استبدِل الصور التلقائية بصور من اللون المطلوب. |
استخدام بروتوكول UIالمظهر
يمكنك استخدام بروتوكول واجهة المستخدم
للحصول على الخادم الوكيل للمظهر لعنصر معين في واجهة المستخدم، والذي يمكنك استخدامه بعد ذلك
لتعيين لون عنصر واجهة المستخدم. عند إجراء تعديل، تتأثر جميع مثيلات
عنصر معين في واجهة المستخدم. على سبيل المثال، يغيِّر المثال التالي لون نص فئات UITextField
إلى الأخضر بشكل شامل عندما تكون مضمَّنة في UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
لمزيد من المعلومات حول تحديد قيم الألوان، يمكنك الرجوع إلى مرجع فئة واجهة المستخدم.
تعرض مقتطفات الرمز التالية جميع أوامر الخادم الوكيل التي تحتاج إلى استخدامها لوضع نمط لكل العناصر المتاحة في عنصر التحكم في واجهة المستخدم للإكمال التلقائي بملء الشاشة. أضِف هذا الرمز إلى طريقة 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;
إعداد خصائص نمط تحكُّم واجهة المستخدم
هناك مجموعة فرعية من عناصر التحكم في واجهة المستخدم تضم خصائص لا تتأثر ببروتوكول واجهة المستخدم، وبالتالي يجب ضبطها مباشرةً. يعرض مثال الرمز البرمجي التالي تحديد ألوان المقدمة والخلفية وتطبيقها على مثيل عنصر تحكّم في واجهة المستخدم باسم 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
التي تُستخدم لتحديد كل جلسة على حدة. يجب أن يمرر تطبيقك الرمز المميز نفسه لكل استدعاء طلب إكمال تلقائي، ثم يمرر هذا الرمز المميز، مع رقم تعريف المكان، في الاستدعاء التالي إلىfetchPlacefromPlaceID:
لاسترداد تفاصيل المكان للمكان الذي اختاره المستخدم. - A
GMSAutocompleteFilter
لإجراء ما يلي:- تحيز النتائج أو قصرها على منطقة معينة.
- حصر النتائج على نوع مكان معيّن.
- عنصر حظر/
GMSPlaceLocationBias
يؤدي إلى انحياز النتائج إلى منطقة معيّنة محدّدة بحدود خط الطول وخط العرض.
- طريقة لمعاودة الاتصال لمعالجة التوقّعات المعروضة.
تعرض أمثلة الرمز أدناه مكالمة للرقم 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
في FetcherSampleViewController.h.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var textField: UITextField? var resultText: UITextView? var fetcher: GMSAutocompleteFetcher? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white edgesForExtendedLayout = [] // Set bounds to inner-west Sydney Australia. let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366, longitude: 151.134002) let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725, longitude: 151.200349) // Set up the autocomplete filter. let filter = GMSAutocompleteFilter() filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner) // Create a new session token. let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init() // Create the fetcher. fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter) fetcher?.delegate = self fetcher?.provide(token) textField = UITextField(frame: CGRect(x: 5.0, y: 10.0, width: view.bounds.size.width - 5.0, height: 64.0)) textField?.autoresizingMask = .flexibleWidth textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) let placeholder = NSAttributedString(string: "Type a query...") textField?.attributedPlaceholder = placeholder resultText = UITextView(frame: CGRect(x: 0, y: 65.0, width: view.bounds.size.width, height: view.bounds.size.height - 65.0)) resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0) resultText?.text = "No Results" resultText?.isEditable = false self.view.addSubview(textField!) self.view.addSubview(resultText!) } @objc func textFieldDidChange(textField: UITextField) { fetcher?.sourceTextHasChanged(textField.text!) } } extension ViewController: GMSAutocompleteFetcherDelegate { func didAutocomplete(with predictions: [GMSAutocompletePrediction]) { let resultsStr = NSMutableString() for prediction in predictions { resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText) resultsStr.appendFormat("Place ID: %@\n", prediction.placeID) } resultText?.text = resultsStr as String } func didFailAutocompleteWithError(_ error: Error) { resultText?.text = error.localizedDescription } }
Objective-C
#import "FetcherSampleViewController.h" #import <GooglePlaces/GooglePlaces.h> #import <GoogleMapsBase/GoogleMapsBase.h> @interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate> @end @implementation FetcherSampleViewController { UITextField *_textField; UITextView *_resultText; GMSAutocompleteFetcher* _fetcher; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.edgesForExtendedLayout = UIRectEdgeNone; // Set bounds to inner-west Sydney Australia. CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(-33.843366, 151.134002); CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(-33.875725, 151.200349); GMSAutocompleteFilter *autocompleteFilter = [[GMSAutocompleteFilter alloc] init]; autocompleteFilter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner); // Create the fetcher. _fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:nil filter:filter]; _fetcher.delegate = self; // Set up the UITextField and UITextView. _textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 0, self.view.bounds.size.width - 5.0f, 44.0f)]; _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; _resultText =[[UITextView alloc] initWithFrame:CGRectMake(0, 45.0f, self.view.bounds.size.width, self.view.bounds.size.height - 45.0f)]; _resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f]; _resultText.text = @"No Results"; _resultText.editable = NO; [self.view addSubview:_textField]; [self.view addSubview:_resultText]; } - (void)textFieldDidChange:(UITextField *)textField { NSLog(@"%@", textField.text); [_fetcher sourceTextHasChanged:textField.text]; } #pragma mark - GMSAutocompleteFetcherDelegate - (void)didAutocompleteWithPredictions:(NSArray *)predictions { NSMutableString *resultsStr = [NSMutableString string]; for (GMSAutocompletePrediction *prediction in predictions) { [resultsStr appendFormat:@"%@\n", [prediction.attributedPrimaryText string]]; } _resultText.text = resultsStr; } - (void)didFailAutocompleteWithError:(NSError *)error { _resultText.text = [NSString stringWithFormat:@"%@", error.localizedDescription]; } @end
الرموز المميزة للجلسة
تعمل الرموز المميزة للجلسة على تجميع مرحلتي الاستعلام والتحديد لبحث الإكمال التلقائي للمستخدم في جلسة منفصلة لأغراض الفوترة. تبدأ الجلسة عندما يبدأ المستخدم في كتابة استعلام، وتنتهي عندما يحدد مكانًا. يمكن أن تحتوي كل جلسة على استعلامات متعددة، يتبعها اختيار مكان واحد. بعد انتهاء الجلسة، لن يكون الرمز المميز صالحًا، بل يجب أن ينشئ تطبيقك رمزًا مميزًا جديدًا لكل جلسة. ننصح باستخدام الرموز المميّزة للجلسة لجميع جلسات الإكمال التلقائي الآلية (عند استخدام وحدة التحكّم بملء الشاشة، أو وحدة التحكّم في النتائج، ستتولى واجهة برمجة التطبيقات ذلك تلقائيًا).
تستخدم حزمة تطوير برامج الأماكن لأجهزة 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
، (على سبيل المثال، سيؤدي تحديد TypeFilter.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 ];
تحسين الإكمال التلقائي لأماكن
يوضّح هذا القسم أفضل الممارسات لمساعدتك في تحقيق أقصى استفادة من خدمة "الإكمال التلقائي" للأماكن.
في ما يلي بعض الإرشادات العامة:
- تتمثل أسرع طريقة لتطوير واجهة مستخدم صالحة في استخدام أداة الإكمال التلقائي لواجهة برمجة تطبيقات JavaScript لخرائط Google، أو حزمة SDK للأماكن لأجهزة Android أداة الإكمال التلقائي أو حزمة SDK للأماكن في نظام التشغيل iOS عناصر التحكم في الإكمال التلقائي لواجهة المستخدم
- فهم حقول البيانات الأساسية الخاصة بميزة "الإكمال التلقائي" للمكان من البداية
- إنّ حقلَي "انحياز الموقع الجغرافي" و"حظر الموقع الجغرافي" هما أمران اختياريان، ولكن قد يكون لهما تأثير كبير في أداء الإكمال التلقائي.
- استخدِم معالجة الأخطاء لضمان تراجع مستوى تطبيقك بشكل مناسب في حال عرض واجهة برمجة التطبيقات خطأ.
- يُرجى التأكّد من معالجة التطبيق في حال عدم تحديد الخيار وتوفير طريقة للمستخدمين للمتابعة.
أفضل ممارسات تحسين التكلفة
التحسين الأساسي للتكلفة
ولتحسين تكلفة استخدام خدمة "الإكمال التلقائي" للأماكن، استخدِم أقنعة الحقول في أداتَي "تفاصيل المكان" و"الإكمال التلقائي" لعرض حقول بيانات الأماكن التي تحتاجها فقط.
التحسين المتقدم للتكلفة
جرّب الاستخدام الآلي لميزة "الإكمال التلقائي" للوصول إلى سعر كل طلب وطلب نتائج واجهة برمجة التطبيقات للترميز الجغرافي حول المكان المحدّد بدلاً من "تفاصيل المكان". يكون التسعير حسب الطلب المقترن بواجهة برمجة التطبيقات للترميز الجغرافي أكثر فعالية من حيث التكلفة من التسعير لكل جلسة (المستندة إلى الجلسة) في حال استيفاء الشرطَين التاليَين:
- إذا كنت تحتاج فقط إلى خط العرض/الطول أو عنوان المكان الذي حدده المستخدم، فإن واجهة برمجة التطبيقات للترميز الجغرافي تقدم هذه المعلومات بتكلفة أقل من استدعاء تفاصيل المكان.
- إذا اختار المستخدمون عبارة بحث مقترَحة من خلال ميزة "الإكمال التلقائي" ضمن متوسط أربعة طلبات لعبارات البحث المقترحة من خلال ميزة "الإكمال التلقائي" أو أقل، قد يكون التسعير لكل طلب أكثر فعالية من حيث التكلفة مقارنةً بالتسعير لكل جلسة.
هل يتطلب طلبك أي معلومات أخرى غير العنوان وخط العرض/الطول للتوقعات المحددة؟
نعم، بحاجة إلى مزيد من التفاصيل
استخدام ميزة "الإكمال التلقائي" لـ "الأماكن" المستنِدة إلى الجلسات مع "تفاصيل المكان"
بما أنّ طلبك يتطلب تفاصيل المكان مثل اسم المكان أو حالة النشاط التجاري أو ساعات العمل، يجب أن تستخدم ميزة "الإكمال التلقائي" للمكان رمزًا مميزًا للجلسة (آليًا أو مدمجًا في تطبيقات JavaScript أو 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
إذا كان تأخير الطلبات يمكن أن يجعل متوسط الطلب الآلي أقل من أربعة، يمكنك اتّباع الإرشادات الخاصة بتنفيذ الإكمال التلقائي للأماكن ذات الصلة بواجهة برمجة التطبيقات Geocode API. تجدر الإشارة إلى أنّ الطلبات المتأخرة قد تنظر إلى وقت الاستجابة للمستخدم الذي قد يتوقّع ظهور توقعات مع كل ضغطة مفتاح جديدة.
يمكنك استخدام أفضل ممارسات الأداء لمساعدة المستخدمين في الحصول على التوقعات التي يبحثون عنها باستخدام عدد أقل من الأحرف.
-
التكاليف المدرَجة هنا بالدولار الأمريكي. يُرجى الرجوع إلى صفحة الفوترة في "منصة خرائط Google" للحصول على معلومات كاملة حول الأسعار.
أفضل ممارسات الأداء
توضّح الإرشادات التالية طرق تحسين أداء ميزة "الإكمال التلقائي" للأماكن:
- أضِف القيود المفروضة على البلدان وانحياز الموقع الجغرافي وإعدادات اللغة المفضّلة (بالنسبة إلى عمليات التنفيذ الآلية) إلى إعدادات الإكمال التلقائي لـ "الإكمال التلقائي" للأماكن. ولا يلزم استخدام إعدادات اللغة المفضّلة مع التطبيقات المصغّرة لأنّها تختار الإعدادات المفضّلة للغة من متصفّح المستخدم أو جهازه الجوّال.
- إذا كان الإكمال التلقائي للأماكن مصحوبًا بخريطة، يمكنك تحيز الموقع من خلال إطار عرض الخريطة.
- في الحالات التي لا يختار فيها المستخدم أحد عبارات البحث المقترحة من خلال ميزة "الإكمال التلقائي"، وبصفة عامة،
بما أنّ أيًا من هذه عبارات البحث المقترحة هو عنوان النتيجة المطلوب، يمكنك إعادة استخدام البيانات التي أدخلها المستخدم
الأصلية لمحاولة الحصول على نتائج أكثر صلة باهتماماتك:
- إذا كنت تتوقع من المستخدم إدخال معلومات العنوان فقط، أعِد استخدام المعلومات الأصلية التي أدخلها المستخدم في طلب إلى Geocode API.
- إذا كنت تتوقع أن يُدخل المستخدم طلبات بحث عن مكان معيّن حسب الاسم أو العنوان، يمكنك استخدام طلب البحث عن مكان. إذا كانت النتائج متوقعة في منطقة معيّنة فقط، استخدِم انحياز الموقع الجغرافي.
- المستخدمون الذين يُدخلون عناوين مقرات فرعية في البلدان التي لا تتوفّر فيها ميزة "الإكمال التلقائي" لعناوين المباني الفرعية، مثل التشيك وإستونيا وليتوانيا. على سبيل المثال، يؤدي العنوان التشيكي "Stroupenznického 3191/17, Praha" إلى توقّع جزئي في الإكمال التلقائي لـ "مكان".
- المستخدمون الذين يُدخلون عناوين باستخدام بادئات قطاعات الطريق، مثل " 23-30 29th St, Queens" في مدينة نيويورك أو " 47-380 Kamehameha Hwy, Kaneohe" على جزيرة كاواي في هاواي.
تحديد المشاكل وحلّها
على الرغم من إمكانية حدوث مجموعة متنوعة من الأخطاء، غالبًا ما تنتج معظم الأخطاء التي قد يواجهها تطبيقك عن أخطاء في الضبط (على سبيل المثال، عند استخدام مفتاح واجهة برمجة تطبيقات خاطئ أو ضبط مفتاح واجهة برمجة التطبيقات بشكل غير صحيح) أو أخطاء في الحصة (تجاوز تطبيقك الحصة المحدَّدة). يمكنك الاطّلاع على حدود الاستخدام للحصول على مزيد من المعلومات حول الحِصص.
ويتم عرض الأخطاء التي تحدث عند استخدام عناصر التحكّم في ميزة "الإكمال التلقائي" في طريقة didFailAutocompleteWithError()
الخاصة ببروتوكولات التفويض المختلفة. تم ضبط السمة
code
لكائن NSError
المقدَّم على إحدى قيم
التعداد GMSPlacesErrorCode
.