تعرض خدمة الإكمال التلقائي في حزمة Places SDK لنظام التشغيل 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:@selector(autocompleteClicked) forControlEvents:UIControlEventTouchUpInside]; [btnLaunchAc setTitle:@"Launch autocomplete" forState:UIControlStateNormal]; btnLaunchAc.frame = CGRectMake(5.0, 150.0, 300.0, 35.0); btnLaunchAc.backgroundColor = [UIColor blueColor]; [self.view addSubview:btnLaunchAc]; } // Handle the user's selection. - (void)viewController:(GMSAutocompleteViewController *)viewController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place ID %@", place.placeID); NSLog(@"Place attributions %@", place.attributions.string); } - (void)viewController:(GMSAutocompleteViewController *)viewController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // User canceled the operation. - (void)wasCancelled:(GMSAutocompleteViewController *)viewController { [self dismissViewControllerAnimated:YES completion:nil]; } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictions:(GMSAutocompleteViewController *)viewController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; } @end
إضافة وحدة تحكّم في النتائج
استخدِم وحدة تحكّم بالنتائج عندما تريد التحكّم بشكل أكبر في واجهة مستخدم إدخال النص. يغيّر عنصر التحكّم في النتائج بشكل ديناميكي مستوى ظهور قائمة النتائج استنادًا إلى تركيز واجهة مستخدم الإدخال.
لإضافة وحدة تحكّم بالنتائج إلى تطبيقك:
- أنشئ
GMSAutocompleteResultsViewController
.- نفِّذ بروتوكول
GMSAutocompleteResultsViewControllerDelegate
في عنصر التحكّم الرئيسي في العرض وحدِّد عنصر التحكّم الرئيسي في العرض على أنّه خاصية المفوّض.
- نفِّذ بروتوكول
- إنشاء كائن
UISearchController
، مع تمريرGMSAutocompleteResultsViewController
كوسيطة وحدة التحكم في النتائج. - اضبط
GMSAutocompleteResultsViewController
كالسمةsearchResultsUpdater
للعنصرUISearchController
. - أضِف
searchBar
لرمزUISearchController
إلى واجهة مستخدم تطبيقك. - يمكنك معالجة اختيار المستخدم في
didAutocompleteWithPlace
طريقة التفويض.
هناك عدة طرق لوضع شريط البحث في UISearchController
في
واجهة مستخدم تطبيقك:
- إضافة شريط بحث إلى شريط التنقّل
- إضافة شريط بحث إلى أعلى طريقة عرض
- إضافة شريط بحث باستخدام نتائج النافذة المنبثقة
إضافة شريط بحث إلى شريط التنقّل
يوضّح مثال الرمز البرمجي التالي كيفية إضافة وحدة تحكّم في النتائج، وإضافة الرمز
searchBar
إلى شريط التنقّل، ومعالجة اختيار المستخدم:
Swift
class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Put the search bar in the navigation bar. searchController?.searchBar.sizeToFit() navigationItem.titleView = searchController?.searchBar // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Prevent the navigation bar from being hidden when searching. searchController?.hidesNavigationBarDuringPresentation = false } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Put the search bar in the navigation bar. [_searchController.searchBar sizeToFit]; self.navigationItem.titleView = _searchController.searchBar; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Prevent the navigation bar from being hidden when searching. _searchController.hidesNavigationBarDuringPresentation = NO; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { _searchController.active = NO; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
إضافة شريط بحث إلى أعلى عرض
يوضّح مثال الرمز البرمجي التالي إضافة searchBar
إلى أعلى عرض.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController let subView = UIView(frame: CGRect(x: 0, y: 65.0, width: 350.0, height: 45.0)) subView.addSubview((searchController?.searchBar)!) view.addSubview(subView) searchController?.searchBar.sizeToFit() searchController?.hidesNavigationBarDuringPresentation = false // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 65.0, 250, 50)]; [subView addSubview:_searchController.searchBar]; [_searchController.searchBar sizeToFit]; [self.view addSubview:subView]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; // Do something with the selected place. NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
بشكلٍ تلقائي،
UISearchController
يخفي شريط التنقّل عند عرض المحتوى (يمكن إيقاف هذه الميزة). في الحالات التي يكون فيها
شريط التنقّل مرئيًا وغير شفاف، لا يضبط UISearchController
موضع الإعلان بشكلٍ صحيح.
يمكنك استخدام الرمز التالي كحل بديل:
Swift
navigationController?.navigationBar.translucent = false searchController?.hidesNavigationBarDuringPresentation = false // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = true self.edgesForExtendedLayout = .top
Objective-C
self.navigationController.navigationBar.translucent = NO; _searchController.hidesNavigationBarDuringPresentation = NO; // This makes the view area include the nav bar even though it is opaque. // Adjust the view placement down. self.extendedLayoutIncludesOpaqueBars = YES; self.edgesForExtendedLayout = UIRectEdgeTop;
إضافة شريط بحث باستخدام نتائج النافذة المنبثقة
يوضح مثال الرمز التالي وضع شريط بحث على الجانب الأيمن من شريط التنقل، وعرض النتائج في نافذة منبثقة.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var resultsViewController: GMSAutocompleteResultsViewController? var searchController: UISearchController? var resultView: UITextView? override func viewDidLoad() { super.viewDidLoad() resultsViewController = GMSAutocompleteResultsViewController() resultsViewController?.delegate = self searchController = UISearchController(searchResultsController: resultsViewController) searchController?.searchResultsUpdater = resultsViewController // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. searchController?.searchBar.frame = (CGRect(x: 0, y: 0, width: 250.0, height: 44.0)) navigationItem.rightBarButtonItem = UIBarButtonItem(customView: (searchController?.searchBar)!) // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. definesPresentationContext = true // Keep the navigation bar visible. searchController?.hidesNavigationBarDuringPresentation = false searchController?.modalPresentationStyle = .popover } } // Handle the user's selection. extension ViewController: GMSAutocompleteResultsViewControllerDelegate { func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { searchController?.isActive = false // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error){ // TODO: handle the error. print("Error: ", error.localizedDescription) } // Turn the network activity indicator on and off again. func didRequestAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = true } func didUpdateAutocompletePredictions(forResultsController resultsController: GMSAutocompleteResultsViewController) { UIApplication.shared.isNetworkActivityIndicatorVisible = false } }
Objective-C
- (void)viewDidLoad { [super viewDidLoad]; _resultsViewController = [[GMSAutocompleteResultsViewController alloc] init]; _resultsViewController.delegate = self; _searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsViewController]; _searchController.searchResultsUpdater = _resultsViewController; // Add the search bar to the right of the nav bar, // use a popover to display the results. // Set an explicit size as we don't want to use the entire nav bar. _searchController.searchBar.frame = CGRectMake(0, 0, 250.0f, 44.0f); self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_searchController.searchBar]; // When UISearchController presents the results view, present it in // this view controller, not one further up the chain. self.definesPresentationContext = YES; // Keep the navigation bar visible. _searchController.hidesNavigationBarDuringPresentation = NO; _searchController.modalPresentationStyle = UIModalPresentationPopover; } // Handle the user's selection. - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didAutocompleteWithPlace:(GMSPlace *)place { [self dismissViewControllerAnimated:YES completion:nil]; NSLog(@"Place name %@", place.name); NSLog(@"Place address %@", place.formattedAddress); NSLog(@"Place attributions %@", place.attributions.string); } - (void)resultsController:(GMSAutocompleteResultsViewController *)resultsController didFailAutocompleteWithError:(NSError *)error { [self dismissViewControllerAnimated:YES completion:nil]; // TODO: handle the error. NSLog(@"Error: %@", [error description]); } // Turn the network activity indicator on and off again. - (void)didRequestAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)didUpdateAutocompletePredictionsForResultsController: (GMSAutocompleteResultsViewController *)resultsController { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; }
استخدام مصدر بيانات جدول
إذا كان تطبيقك يتضمّن واجهة مستخدم مخصّصة لنص البحث، يمكنك استخدام فئة
GMSAutocompleteTableDataSource
لتشغيل عرض الجدول الذي يعرض النتائج على وحدة التحكّم في العرض.
لاستخدام GMSAutocompleteTableDataSource
كمصدر بيانات ومفوّض لسمة UITableView
في أداة التحكّم في العرض:
- نفِّذ بروتوكولَي
GMSAutocompleteTableDataSourceDelegate
وUISearchBarDelegate
في أداة التحكّم في العرض. - أنشئ مثيلًا من
GMSAutocompleteTableDataSource
وحدِّد "عنصر التحكّم في العرض" كخاصية المفوّض. - اضبط
GMSAutocompleteTableDataSource
ك مصدر بيانات وفوِّض سمات مثيلUITableView
في "عنصر التحكّم في العرض". - في معالِج إدخال نص البحث، استخدِم
sourceTextHasChanged
فيGMSAutocompleteTableDataSource
.- يمكنك معالجة اختيار المستخدم في
didAutocompleteWithPlace
طريقة التفويض.
- يمكنك معالجة اختيار المستخدم في
- ويمكنك إغلاق وحدة التحكُّم في أساليب التفويض
didAutocompleteWithPlace
أوdidFailAutocompleteWithError
أوwasCancelled
.
يوضّح مثال الرمز البرمجي التالي استخدام فئة
GMSAutocompleteTableDataSource
لتشغيل عرض الجدول الخاص بعنصر UIViewController
عند
إضافة UISearchBar
بشكل منفصل.
Swift
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import GooglePlaces import UIKit class PlaceAutocompleteViewController: UIViewController { private var tableView: UITableView! private var tableDataSource: GMSAutocompleteTableDataSource! override func viewDidLoad() { super.viewDidLoad() let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: self.view.frame.size.width, height: 44.0)) searchBar.delegate = self view.addSubview(searchBar) tableDataSource = GMSAutocompleteTableDataSource() tableDataSource.delegate = self tableView = UITableView(frame: CGRect(x: 0, y: 64, width: self.view.frame.size.width, height: self.view.frame.size.height - 44)) tableView.delegate = tableDataSource tableView.dataSource = tableDataSource view.addSubview(tableView) } } extension PlaceAutocompleteViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // Update the GMSAutocompleteTableDataSource with the search text. tableDataSource.sourceTextHasChanged(searchText) } } extension PlaceAutocompleteViewController: GMSAutocompleteTableDataSourceDelegate { func didUpdateAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator off. UIApplication.shared.isNetworkActivityIndicatorVisible = false // Reload table data. tableView.reloadData() } func didRequestAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) { // Turn the network activity indicator on. UIApplication.shared.isNetworkActivityIndicatorVisible = true // Reload table data. tableView.reloadData() } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didAutocompleteWith place: GMSPlace) { // Do something with the selected place. print("Place name: \(place.name)") print("Place address: \(place.formattedAddress)") print("Place attributions: \(place.attributions)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didFailAutocompleteWithError error: Error) { // Handle the error. print("Error: \(error.localizedDescription)") } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didSelect prediction: GMSAutocompletePrediction) -> Bool { return true } }
Objective-C
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #import "PlaceAutocompleteViewController.h" @import GooglePlaces; @import UIKit; @interface PlaceAutocompleteViewController () <GMSAutocompleteTableDataSourceDelegate, UISearchBarDelegate> @end @implementation PlaceAutocompleteViewController { UITableView *tableView; GMSAutocompleteTableDataSource *tableDataSource; } - (void)viewDidLoad { [super viewDidLoad]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)]; searchBar.delegate = self; [self.view addSubview:searchBar]; tableDataSource = [[GMSAutocompleteTableDataSource alloc] init]; tableDataSource.delegate = self; tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 44)]; tableView.delegate = tableDataSource; tableView.dataSource = tableDataSource; [self.view addSubview:tableView]; } #pragma mark - GMSAutocompleteTableDataSourceDelegate - (void)didUpdateAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator off. UIApplication.sharedApplication.networkActivityIndicatorVisible = NO; // Reload table data. [tableView reloadData]; } - (void)didRequestAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource { // Turn the network activity indicator on. UIApplication.sharedApplication.networkActivityIndicatorVisible = YES; // Reload table data. [tableView reloadData]; } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didAutocompleteWithPlace:(GMSPlace *)place { // Do something with the selected place. NSLog(@"Place name: %@", place.name); NSLog(@"Place address: %@", place.formattedAddress); NSLog(@"Place attributions: %@", place.attributions); } - (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didFailAutocompleteWithError:(NSError *)error { // Handle the error NSLog(@"Error %@", error.description); } - (BOOL)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didSelectPrediction:(GMSAutocompletePrediction *)prediction { return YES; } #pragma mark - UISearchBarDelegate - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { // Update the GMSAutocompleteTableDataSource with the search text. [tableDataSource sourceTextHasChanged:searchText]; } @end
تخصيص ألوان النص والخلفية
يمكنك ضبط ألوان جميع النصوص والخلفيات في عنصر التحكّم في ميزة "الإكمال التلقائي" في واجهة المستخدم، وذلك لجعل الأداة أكثر تناسبًا مع المظهر المرئي للتطبيق. هناك طريقتان لضبط ألوان عناصر التحكّم في واجهة المستخدم:
- باستخدام بروتوكول واجهة المستخدم المدمج في نظام التشغيل iOS لعناصر التحكم في واجهة المستخدم ذات النمط العام متى أمكن ذلك. تنطبق هذه الإعدادات على العديد، وليس كلها، عناصر التحكم في واجهة المستخدم.
- من خلال استخدام طرق حزمة تطوير البرامج (SDK) في فئات التطبيقات المصغّرة لضبط الخصائص التي لا تتوافق مع بروتوكول واجهة المستخدم في واجهة المستخدم.
سيستخدم تطبيقك عادةً مزيجًا من بروتوكول UIAppearance وطرق حزمة SDK. يوضّح الرسم البياني التالي العناصر التي يمكن تنسيقها:
يسرد الجدول التالي جميع عناصر واجهة المستخدم، ويشير إلى كيفية تنسيق كل عنصر (بروتوكول UIAppearance أو طريقة حزمة SDK).
عنصر في واجهة المستخدم | الطريقة | إرشادات متعلّقة بالموضة |
---|---|---|
درجة لون شريط التنقّل (الخلفية) | بروتوكول UIAppearance | الاتصال بالرقم setBarTintColor على الخادم الوكيل UINavigationBar |
درجة اللون الخفيف لشريط التنقل (علامة إقحام نص شريط البحث وزر الإلغاء) | بروتوكول UIAppearance | الاتصال بالرقم setTintColor على الخادم الوكيل UINavigationBar |
لون نص شريط البحث | بروتوكول UIAppearance | اضبط NSForegroundColorAttributeName في searchBarTextAttributes . |
درجة لون شريط البحث | لا ينطبق | إنّ شريط البحث شفاف وسيعرض كنسخة مظللة من "شريط التنقل". |
لون نص العنصر النائب في شريط البحث (نص البحث التلقائي) | بروتوكول UIAppearance | ضبط NSForegroundColorAttributeName في placeholderAttributes |
النص الأساسي (ينطبق أيضًا على نص الخطأ والرسالة) | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextColor ". |
تمييز النص الأساسي | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextHighlightColor ". |
النص الثانوي | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "secondaryTextColor ". |
الخطأ ونص الرسالة | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "primaryTextColor ". |
خلفية خلية الجدول | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tableCellBackgroundColor ". |
لون فاصل خلايا الجدول | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tableCellSeparatorColor ". |
زر "إعادة المحاولة" | طريقة حزمة تطوير البرامج (SDK) | تواصل هاتفيًا مع "tintColor ". |
مؤشر النشاط (مؤشر التقدم) | بروتوكول UIAppearance | الاتصال بالرقم setColor على الخادم الوكيل UIActivityIndicatorView |
شعار "مدعوم من Google"، صورة سحابة حزينة | لا ينطبق | يتم اختيار النسخة البيضاء أو الرمادية تلقائيًا استنادًا إلى التباين مع الخلفية. |
رمزان لعدسة مكبرة ومحو النص في حقل نص شريط البحث | لا ينطبق | لإضافة نمط، استبدِل الصور التلقائية بصور باللون المطلوب. |
استخدام بروتوكول UIاطّلِع على
يمكنك استخدام بروتوكول واجهة المستخدم للحصول على خادم وكيل المظهر لعنصر معيّن في واجهة المستخدم، والذي يمكنك استخدامه بعد ذلك لضبط لون عنصر واجهة المستخدم. عند إجراء تعديل، تتأثر جميع
مثيلات عنصر واجهة المستخدم المعين. على سبيل المثال، يؤدي المثال التالي إلى
تغيير لون نص فئات UITextField
بشكلٍ عام إلى الأخضر عندما تكون مضمّنة
في UISearchBar
:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];
لمزيد من المعلومات عن تحديد قيم الألوان، يمكنك الرجوع إلى مرجع فئة UIColor.
تعرض المقتطفات التالية من الرموز البرمجية جميع أوامر الخادم الوكيل التي تحتاج إلى استخدامها لتحديد تنسيق كل العناصر في عنصر التحكّم في واجهة المستخدم للإكمال التلقائي بملء الشاشة. أضف هذه التعليمة البرمجية إلى
الطريقة didFinishLaunchingWithOptions
في Appdelegate.m:
// Define some colors. UIColor *darkGray = [UIColor darkGrayColor]; UIColor *lightGray = [UIColor lightGrayColor]; // Navigation bar background. [[UINavigationBar appearance] setBarTintColor:darkGray]; [[UINavigationBar appearance] setTintColor:lightGray]; // Color of typed text in the search bar. NSDictionary *searchBarTextAttributes = @{ NSForegroundColorAttributeName: lightGray, NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]] }; [UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] .defaultTextAttributes = searchBarTextAttributes; // Color of the placeholder text in the search bar prior to text entry. NSDictionary *placeholderAttributes = @{ NSForegroundColorAttributeName: lightGray, NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]] }; // Color of the default search text. // NOTE: In a production scenario, "Search" would be a localized string. NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Search" attributes:placeholderAttributes]; [UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] .attributedPlaceholder = attributedPlaceholder; // Color of the in-progress spinner. [[UIActivityIndicatorView appearance] setColor:lightGray]; // To style the two image icons in the search bar (the magnifying glass // icon and the 'clear text' icon), replace them with different images. [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x_high"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateHighlighted]; [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal]; [[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_search"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; // Color of selected table cells. UIView *selectedBackgroundView = [[UIView alloc] init]; selectedBackgroundView.backgroundColor = [UIColor lightGrayColor]; [UITableViewCell appearanceWhenContainedIn:[GMSAutocompleteViewController class], nil] .selectedBackgroundView = selectedBackgroundView;
ضبط خصائص نمط عناصر التحكّم في واجهة المستخدم
تحتوي مجموعة فرعية من عناصر التحكّم في واجهة المستخدم على سمات لا تتأثر ببروتوكول
UIAppearance، لذا يجب ضبطها مباشرةً. يوضّح مثال الرمز التالي تعريف ألوان المقدمة والخلفية، وتطبيقها على عنصر تحكّم في واجهة المستخدم باسم acController
. أضِف هذا الرمز إلى طريقة onLaunchClicked
في ViewController.m:
UIColor *darkGray = [UIColor darkGrayColor]; UIColor *lightGray = [UIColor lightGrayColor]; acController.secondaryTextColor = [UIColor colorWithWhite:1.0f alpha:0.5f]; acController.primaryTextColor = lightGray; acController.primaryTextHighlightColor = [UIColor grayColor]; acController.tableCellBackgroundColor = darkGray; acController.tableCellSeparatorColor = lightGray; acController.tintColor = lightGray;
الحصول على توقعات الأماكن آليًا
يمكنك إنشاء واجهة مستخدم بحث مخصّصة كبديل لواجهة المستخدم التي يوفّرها تطبيق "الإكمال التلقائي" المصغّر. ولإجراء ذلك، يجب أن يحصل تطبيقك على توقعات الأماكن برمجيًا. يمكن لتطبيقك الحصول على قائمة بأسماء الأماكن و/أو العناوين المتوقّعة بإحدى الطريقتَين التاليتَين:
سيتم الاتصال بالرقم GMSPlacesClient findAutocompletePredictionsFromQuery:
للحصول على قائمة بأسماء الأماكن و/أو العناوين المتوقّعة، عليك أولاً إنشاء مثيل لـ
GMSPlacesClient، ثم استدعاء الأسلوب GMSPlacesClient
findAutocompletePredictionsFromQuery:
مع المَعلمات التالية:
- سلسلة
autocompleteQuery
تحتوي على النص الذي كتبه المستخدم. GMSAutocompleteSessionToken
، الذي يُستخدَم لتحديد كل جلسة فردية يجب أن يُرسِل تطبيقك الرمز المميّز نفسه مع كل طلب لإكمال تلقائي، ثم يُرسِل هذا الرمز المميّز مع معرّف مكان في الطلب اللاحق المُرسَل إلى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
، لن يتم عرض أي قيمة distance.
يوضّح مثال الرمز البرمجي التالي كيفية تمييز الأجزاء
من النتيجة التي تتطابق مع النص في طلب بحث المستخدم باستخدام enumerateAttribute
:
Swift
let regularFont = UIFont.systemFont(ofSize: UIFont.labelFontSize) let boldFont = UIFont.boldSystemFont(ofSize: UIFont.labelFontSize) let bolded = prediction.attributedFullText.mutableCopy() as! NSMutableAttributedString bolded.enumerateAttribute(kGMSAutocompleteMatchAttribute, in: NSMakeRange(0, bolded.length), options: []) { (value, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in let font = (value == nil) ? regularFont : boldFont bolded.addAttribute(NSFontAttributeName, value: font, range: range) } label.attributedText = bolded
Objective-C
UIFont *regularFont = [UIFont systemFontOfSize:[UIFont labelFontSize]]; UIFont *boldFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; NSMutableAttributedString *bolded = [prediction.attributedFullText mutableCopy]; [bolded enumerateAttribute:kGMSAutocompleteMatchAttribute inRange:NSMakeRange(0, bolded.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { UIFont *font = (value == nil) ? regularFont : boldFont; [bolded addAttribute:NSFontAttributeName value:font range:range]; }]; label.attributedText = bolded;
استخدام أداة الجلب
إذا كنت تريد إنشاء عنصر تحكّم في الإكمال التلقائي من البداية، يمكنك استخدام GMSAutocompleteFetcher
الذي يلتف حول طريقة autocompleteQuery
في GMSPlacesClient
. يحدّد برنامج الجلب
معدّل تكرار الطلبات، ولا يعرض سوى نتائج البحث
التي تم إدخالها مؤخرًا. لا يوفّر أي عناصر لواجهة المستخدم.
لتنفيذ
GMSAutocompleteFetcher
،
اتّبِع الخطوات التالية:
- نفِّذ بروتوكول
GMSAutocompleteFetcherDelegate
. - أنشئ كائن
GMSAutocompleteFetcher
. - استخدِم
sourceTextHasChanged
في أداة الجلب بينما يكتب المستخدم. - يمكنك معالجة التوقّعات والأخطاء باستخدام طريقتَي البروتوكول
didAutcompleteWithPredictions
وdidFailAutocompleteWithError
.
يوضّح مثال الرمز البرمجي التالي استخدام أداة الجلب لتلقّي إدخال المستخدم و
عرض مطابقات الأماكن في عرض نصي. تمت إزالة وظائف اختيار مكان. FetcherSampleViewController
مشتق من UIViewController
في
FetcherSampleViewController.h.
Swift
import UIKit import GooglePlaces class ViewController: UIViewController { var textField: UITextField? var resultText: UITextView? var fetcher: GMSAutocompleteFetcher? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white edgesForExtendedLayout = [] // Set bounds to inner-west Sydney Australia. let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366, longitude: 151.134002) let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725, longitude: 151.200349) // Set up the autocomplete filter. let filter = GMSAutocompleteFilter() filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner) // Create a new session token. let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init() // Create the fetcher. fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter) fetcher?.delegate = self fetcher?.provide(token) textField = UITextField(frame: CGRect(x: 5.0, y: 10.0, width: view.bounds.size.width - 5.0, height: 64.0)) textField?.autoresizingMask = .flexibleWidth textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) let placeholder = NSAttributedString(string: "Type a query...") textField?.attributedPlaceholder = placeholder resultText = UITextView(frame: CGRect(x: 0, y: 65.0, width: view.bounds.size.width, height: view.bounds.size.height - 65.0)) resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0) resultText?.text = "No Results" resultText?.isEditable = false self.view.addSubview(textField!) self.view.addSubview(resultText!) } @objc func textFieldDidChange(textField: UITextField) { fetcher?.sourceTextHasChanged(textField.text!) } } extension ViewController: GMSAutocompleteFetcherDelegate { func didAutocomplete(with predictions: [GMSAutocompletePrediction]) { let resultsStr = NSMutableString() for prediction in predictions { resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText) resultsStr.appendFormat("Place ID: %@\n", prediction.placeID) } resultText?.text = resultsStr as String } func didFailAutocompleteWithError(_ error: Error) { resultText?.text = error.localizedDescription } }
Objective-C
#import "FetcherSampleViewController.h" #import <GooglePlaces/GooglePlaces.h> @interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate> @end @implementation FetcherSampleViewController { UITextField *_textField; UITextView *_resultText; GMSAutocompleteFetcher* _fetcher; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.edgesForExtendedLayout = UIRectEdgeNone; // Set bounds to inner-west Sydney Australia. CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(-33.843366, 151.134002); CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(-33.875725, 151.200349); GMSAutocompleteFilter *autocompleteFilter = [[GMSAutocompleteFilter alloc] init]; autocompleteFilter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner); // Create the fetcher. _fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:nil filter:filter]; _fetcher.delegate = self; // Set up the UITextField and UITextView. _textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f, 0, self.view.bounds.size.width - 5.0f, 44.0f)]; _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth; [_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; _resultText =[[UITextView alloc] initWithFrame:CGRectMake(0, 45.0f, self.view.bounds.size.width, self.view.bounds.size.height - 45.0f)]; _resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f]; _resultText.text = @"No Results"; _resultText.editable = NO; [self.view addSubview:_textField]; [self.view addSubview:_resultText]; } - (void)textFieldDidChange:(UITextField *)textField { NSLog(@"%@", textField.text); [_fetcher sourceTextHasChanged:textField.text]; } #pragma mark - GMSAutocompleteFetcherDelegate - (void)didAutocompleteWithPredictions:(NSArray *)predictions { NSMutableString *resultsStr = [NSMutableString string]; for (GMSAutocompletePrediction *prediction in predictions) { [resultsStr appendFormat:@"%@\n", [prediction.attributedPrimaryText string]]; } _resultText.text = resultsStr; } - (void)didFailAutocompleteWithError:(NSError *)error { _resultText.text = [NSString stringWithFormat:@"%@", error.localizedDescription]; } @end
الرموز المميّزة للجلسات
تعمل الرموز المميزة للجلسة على تجميع مرحلتي طلب البحث والاختيار ضمن بحث المستخدم للإكمال التلقائي في جلسة منفصلة لأغراض الفوترة. تبدأ الجلسة عندما يبدأ المستخدم كتابة طلب بحث، وتنتهي عندما يختار مكانًا. يمكن أن تحتوي كل جلسة على طلبات بحث متعددة، متبوعة باختيار مكان واحد. بعد انتهاء إحدى الجلسات، لن يعود الرمز المميّز صالحًا، ويجب أن ينشئ تطبيقك رمزًا مميّزًا جديدًا لكل جلسة. ننصحك باستخدام الرموز المميّزة للجلسات لجميع جلسات مكتملة التلقائية البرمجية (عندما تستخدم وحدة التحكّم في وضع ملء الشاشة أو وحدة التحكّم في النتائج، تتولى واجهة برمجة التطبيقات هذه المهمة تلقائيًا).
تستخدِم حزمة تطوير برامج "الأماكن" لنظام التشغيل 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 ضمن Place
Types. إذا لم يتم تحديد أي شيء، سيتم عرض جميع الأنواع.
لتحديد فلتر نوع أو مجموعة أنواع:
استخدِم السمة
types
لتحديد ما يصل إلى خمس قيم type من الجدول 1 والجدول 2 المعروضة في أنواع الأماكن. يتم تحديد قيم النوع من خلال الثوابت فيGMSPlaceType
.استخدِم السمة
types
لتحديد مجموعة أنواع من الجدول 3 المعروض في أنواع الأماكن. يتم تحديد قيم مجموعة الأنواع من خلال الثوابت فيGMSPlaceType
.يُسمح بنوع واحد فقط من الجدول 3 في الطلب. إذا حددت قيمة من الجدول 3، فلا يمكنك تحديد قيمة من الجدول 1 أو الجدول 2. وإذا حدث ذلك، سيحدث خطأ.
على سبيل المثال، لعرض النتائج التي تتوافق فقط مع نوع مكان معيّن، اضبط
types
على GMSAutocompleteFilter
. يوضّح المثال التالي ضبط الفيلتر
لعرض النتائج التي تتضمّن عنوانًا دقيقًا فقط:
GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];
تحسين ميزة "الإكمال التلقائي للأماكن"
يصف هذا القسم أفضل الممارسات لمساعدتك في الاستفادة إلى أقصى حدّ من خدمة "الإكمال التلقائي" للأماكن.
في ما يلي بعض الإرشادات العامة:
- إنّ أسرع طريقة لتطوير واجهة مستخدم فعّالة هي استخدام أداة الإكمال التلقائي في واجهة برمجة التطبيقات JavaScript للخرائط، أو أداة الإكمال التلقائي في حزمة تطوير البرامج (SDK) للأماكن لنظام التشغيل Android، أو عنصر التحكّم في واجهة المستخدم للإكمال التلقائي في حزمة تطوير البرامج (SDK) للأماكن لنظام التشغيل iOS.
- احرص على فهم حقول البيانات الأساسية لميزة "إكمال الأماكن تلقائيًا" منذ البداية.
- إنّ حقول انحياز الموقع الجغرافي وفرض القيود على المواقع الجغرافية اختيارية، ولكن يمكن أن يكون لها تأثير كبير في أداء ميزة الإكمال التلقائي.
- يجب معالجة الأخطاء للتأكّد من تراجع أداء تطبيقك بشكل سلس في حال عرضت واجهة برمجة التطبيقات خطأً.
- تأكَّد من أنّ تطبيقك يتعامل مع الحالات التي لا يتوفّر فيها خيار معيّن، وأنّه يقدّم للمستخدمين طريقة لمواصلة الإجراء.
أفضل الممارسات لتحسين التكلفة
تحسين التكلفة الأساسية
لتحسين تكلفة استخدام خدمة "الإكمال التلقائي" للأماكن، يمكنك استخدام أقنعة الحقول في "تفاصيل المكان" و"أداة الإكمال التلقائي للأماكن" لعرض حقول بيانات الأماكن التي تحتاج إليها فقط.
التحسين المتقدم للتكلفة
يمكنك التنفيذ الآلي لميزة "الإكمال التلقائي" للأماكن من أجل الوصول إلى السعر لكل طلب وطلب نتائج واجهة برمجة التطبيقات Geocoding حول المكان المحدد بدلاً من تفاصيل المكان. إنّ السعر لكل طلب مع Geocoding API يُعدّ أكثر فعالية من حيث التكلفة مقارنةً بالسعر لكل جلسة (استنادًا إلى الجلسة) في حال استيفاء الشرطَين التاليَين:
- إذا كنت بحاجة فقط إلى خط العرض/خط الطول أو عنوان المكان الذي اختاره المستخدم، تقدّم واجهة برمجة التطبيقات Geocoding API هذه المعلومات بتكلفة أقل من طلب الحصول على تفاصيل المكان.
- إذا اختار المستخدمون توقّعًا للإكمال التلقائي في المتوسط خلال أربعة طلبات توقّعات للإكمال التلقائي أو أقل، قد يكون السعر لكل طلب أكثر فعالية من حيث التكلفة مقارنةً بالسعر لكل جلسة.
هل يتطلب طلبك أي معلومات بخلاف العنوان وخط العرض/خط الطول للتوقّع المحدد؟
نعم، يجب تقديم المزيد من التفاصيل
استخدام ميزة "الإكمال التلقائي للأماكن" المستندة إلى الجلسة مع "تفاصيل الأماكن"
بما أنّ تطبيقك يتطلّب تفاصيل عن المكان، مثل اسم المكان أو حالة النشاط التجاري أو ساعات العمل، يجب أن يستخدم تطبيقك ميزة "الإكمال التلقائي للأماكن" مع رمز أمان الجلسة (برمجيًا أو مضمّنًا في التطبيقات المصغّرة JavaScript أو Android أو iOS) بتكلفة إجمالية تبلغ 0.017 دولار أمريكي لكل جلسة بالإضافة إلى رموز التخزين التعريفية لبيانات الأماكن السارية استنادًا إلى حقول بيانات الأماكن التي تطلبها.1
تنفيذ الأداة
يتم دمج "إدارة الجلسات" تلقائيًا في التطبيقات المصغّرة JavaScript أو Android أو iOS. ويتضمن هذا كلاً من طلبات الإكمال التلقائي للأماكن وطلب "تفاصيل المكان" في التنبؤ المحدد. احرص على تحديد المَعلمة fields
لضمان طلب
حقول بيانات الأماكن التي تحتاج إليها فقط.
التنفيذ الآلي
استخدِم رمز أمان الجلسة مع طلبات ميزة "الإكمال التلقائي للأماكن". عند طلب تفاصيل المكان عن التوقّع المحدّد، يجب تضمين المَعلمات التالية:
- معرّف المكان من ردّ ميزة "الإكمال التلقائي للأماكن"
- الرمز المميّز للجلسة المستخدَم في طلب الإكمال التلقائي للأماكن
- المَعلمة
fields
التي تحدِّد حقول بيانات الأماكن التي تحتاج إليها
لا، يجب إدخال العنوان والموقع الجغرافي فقط.
قد تكون Geocoding API خيارًا أكثر فعالية من حيث التكلفة من Place Details لتطبيقك، وذلك استنادًا إلى أداء استخدامك لخدمة "الإكمال التلقائي للأماكن". تختلف كفاءة ميزة "الإكمال التلقائي" في كل تطبيق حسب ما يُدخله المستخدمون ومكان استخدام التطبيق وما إذا تم تنفيذ أفضل الممارسات لتحسين الأداء.
للإجابة عن السؤال التالي، حلِّل عدد الأحرف التي يكتبها المستخدم في المتوسط قبل اختيار اقتراح من ميزة "الإكمال التلقائي للأماكن" في تطبيقك.
هل يختار المستخدمون توقّعات ميزة "الإكمال التلقائي" للأماكن في أربعة طلبات أو أقل في المتوسط؟
نعم
تنفيذ ميزة "الإكمال التلقائي" للأماكن تلقائيًا بدون الرموز المميّزة للجلسة واستدعاء واجهة برمجة التطبيقات Geocoding API على اقتراحات الأماكن المحدَّدة
توفّر واجهة برمجة التطبيقات Geocoding API عناوين وإحداثيات خطوط العرض/الطول مقابل 0.005 دولار أمريكي لكل طلب. تبلغ تكلفة إرسال أربعة طلبات Place Autocomplete - Per Request 0.01132 دولار أمريكي، وبالتالي فإنّ التكلفة الإجمالية لأربعة طلبات بالإضافة إلى طلب واحد من Geocoding API بشأن التوقّع المحدّد للمكان ستكون 0.01632 دولار أمريكي، وهو أقل من سعر الإكمال التلقائي لكل جلسة الذي يبلغ 0.017 دولار أمريكي لكل جلسة.1
ننصحك باتّباع أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على الاقتراحات التي يبحثون عنها باستخدام عدد أقل من الأحرف.
لا
استخدام ميزة "الإكمال التلقائي للأماكن" المستندة إلى الجلسة مع "تفاصيل الأماكن"
بما أنّ متوسّط عدد الطلبات التي تتوقّع إجراؤها قبل أن يختار المستخدِم أحد التوقّعات في ميزة "إكمال الأماكن تلقائيًا" يتجاوز تكلفة السعر لكل جلسة، يجب أن يستخدِم تطبيقك لميزة "إكمال الأماكن تلقائيًا" رمزًا مميزًا للجلسة لكلّ من طلبات "إكمال الأماكن تلقائيًا" وطلبات "تفاصيل الأماكن" المرتبطة بها بتكلفة إجمالية تبلغ 0.017 دولار أمريكي لكل جلسة.1
تنفيذ التطبيقات المصغّرة
يتم تلقائيًا دمج إدارة الجلسات في التطبيقات المصغّرة JavaScript أو Android أو iOS. ويشمل ذلك طلبات "الإكمال التلقائي للأماكن" وطلبات "تفاصيل المكان" المتعلّقة بالاقتراح المحدّد. احرص على تحديد المَعلمة fields
لضمان طلب حقول البيانات الأساسية فقط.
التنفيذ الآلي
استخدِم رمز أمان الجلسة مع طلبات ميزة "الإكمال التلقائي للأماكن". عند طلب تفاصيل المكان المتعلّقة بالتوقّع المحدّد، يجب تضمين المَعلمات التالية:
- رقم تعريف المكان من ردّ الإكمال التلقائي للأماكن
- الرمز المميّز للجلسة المستخدَم في طلب الإكمال التلقائي للأماكن
- المَعلمة
fields
التي تحدِّد حقول البيانات الأساسية، مثل العنوان والشكل الهندسي
ننصح بتأخير طلبات "الإكمال التلقائي للأماكن"
يمكنك استخدام استراتيجيات مثل تأخير طلب "الإكمال التلقائي للأماكن" إلى أن يكتب المستخدم أوّل ثلاث أو أربع أحرف حتى يقدّم تطبيقك عددًا أقل من الطلبات. على سبيل المثال، عند إرسال طلبات "الإكمال التلقائي للأماكن" لكل حرف بعد أن يكتب المستخدم الحرف الثالث، يعني ذلك أنّه إذا كتب المستخدم سبعة أحرف ثم اختار اقتراحًا تُرسل طلبًا واحدًا من أجله إلى واجهة برمجة التطبيقات Geocoding API، ستكون التكلفة الإجمالية 0.01632 دولار أمريكي (4 * 0.00283 دولار أمريكي للإكمال التلقائي لكل طلب + 0.005 دولار أمريكي للتعيين الجغرافي).1
إذا كان تأخير الطلبات يمكن أن يقلّل متوسط الطلبات المبرمَجة إلى أقل من أربعة، يمكنك اتّباع إرشادات تنفيذ ميزة "الإكمال التلقائي للأماكن" العالية الأداء باستخدام واجهة برمجة التطبيقات Geocoding API. يُرجى العِلم أنّ تأخير الطلبات قد يُنظر إليه على أنّه وقت استجابة من قِبل المستخدم الذي قد يتوقّع رؤية التوقّعات مع كل ضغطة مفتاح جديدة.
ننصحك باتّباع أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على الاقتراحات التي يبحثون عنها باستخدام عدد أقل من الأحرف.
-
التكاليف المدرَجة هنا بالدولار الأمريكي. يُرجى الرجوع إلى صفحة الفوترة في Google Maps Platform للحصول على معلومات الأسعار الكاملة.
أفضل الممارسات المتعلّقة بالأداء
توضّح الإرشادات التالية طرق تحسين أداء ميزة "الإكمال التلقائي للأماكن":
- أضِف القيود المتعلقة بالبلد، الميل إلى الموقع الجغرافي، (في عمليات التنفيذ الآلي) وإعدادات اللغة المفضّلة إلى عملية تنفيذ ميزة "الإكمال التلقائي للأماكن". لا حاجة إلى تفضيل اللغة مع التطبيقات المصغّرة، لأنّها تختار الإعدادات المفضّلة للّغة من متصفّح المستخدم أو جهازه الجوّال.
- إذا كانت ميزة "الإكمال التلقائي للأماكن" مصحوبة بخريطة، يمكنك التركيز على الموقع الجغرافي حسب مساحة العرض في الخريطة.
- في الحالات التي لا يختار فيها المستخدم أحد الاقتراحات التي يوفّرها ميزة "الإكمال التلقائي"، ويعود السبب في ذلك عمومًا
إلى أنّ أيًا من هذه الاقتراحات لا يمثّل عنوان النتيجة المطلوب، يمكنك إعادة استخدام
مدخلات المستخدم الأصلية لمحاولة الحصول على نتائج أكثر صلة:
- إذا كنت تتوقّع أن يُدخل المستخدم معلومات العنوان فقط، أعِد استخدام الإدخال الأصلي في طلب Geocoding API.
- إذا كنت تتوقّع أن يُدخل المستخدم طلبات بحث عن مكان معيّن حسب الاسم أو العنوان، استخدِم طلب البحث عن مكان. إذا كانت النتائج متوقعة فقط في منطقة معيّنة، استخدِم انحياز الموقع الجغرافي.
- المستخدمون الذين يُدخلون عناوين المواقع الفرعية في البلدان التي لا تتوفّر فيها ميزة "الإكمال التلقائي للأماكن" لعناوين المواقع الفرعية، مثل التشيك وإستونيا وليتوانيا على سبيل المثال، يؤدي إدخال عنوان التشيكي "Stroupežnického 3191/17, Praha" إلى عرض عبارة بحث مقترَحة جزئية في ميزة "الإكمال التلقائي" للأماكن.
- المستخدمون الذين يُدخلون عناوين تتضمّن بادئات أجزاء من الطرق، مثل "23-30 29th St, Queens" في مدينة نيويورك أو "47-380 Kamehameha Hwy, Kaneohe" في جزيرة كاواي في هاواي
تحديد المشاكل وحلّها
على الرغم من أنّه يمكن أن تحدث مجموعة كبيرة من الأخطاء، إلا أنّ معظم الأخطاء التي يُحتمَل أن يواجهها تطبيقك ناتجة عادةً عن أخطاء في الإعداد (على سبيل المثال، تم استخدام مفتاح واجهة برمجة التطبيقات غير الصحيح أو تم ضبط مفتاح واجهة برمجة التطبيقات بشكل غير صحيح) أو أخطاء في الحصة (تجاوز تطبيقك حصته). اطّلِع على حدود الاستخدام للحصول على مزيد من المعلومات عن الحصص.
يتم عرض الأخطاء التي تحدث عند استخدام عناصر تحكّم الإكمال التلقائي في طريقة didFailAutocompleteWithError()
الخاصة ببروتوكولات التفويض المختلفة. تم ضبط سمة
code
لعنصر NSError
المقدَّم على إحدى قيم
التعداد GMSPlacesErrorCode
.