الإكمال التلقائي للأماكن

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
اختيار نظام أساسي: Android iOS JavaScript خدمة الويب

تعرض خدمة الإكمال التلقائي في الأماكن SDK لنظام التشغيل iOS توقعات المكان استجابة لطلبات بحث المستخدم. أثناء كتابة المستخدم، تعرض خدمة الإكمال التلقائي اقتراحات لأماكن مثل الأنشطة التجارية والعناوين ورموز المواقع المفتوحة ونقاط الاهتمام.

يمكنك إضافة الإكمال التلقائي إلى تطبيقك بالطرق التالية:

إضافة عنصر تحكم في الإكمال التلقائي لواجهة المستخدم

عنصر التحكم في واجهة المستخدم للإكمال التلقائي هو مربع حوار بحث يتضمن وظيفة الإكمال التلقائي. عندما يدخل المستخدم عبارات البحث، يقدم عنصر التحكم قائمة بالأماكن المتوقعة للاختيار من بينها. عندما يحدِّد المستخدم أحد الخيارات، يتم عرض مثيل GMSPlace يمكن للتطبيق استخدامه بعد ذلك للحصول على تفاصيل حول المكان الذي تم اختياره.

يمكنك إضافة عنصر تحكم الإكمال التلقائي لواجهة المستخدم إلى تطبيقك بالطرق التالية:

إضافة عنصر تحكم بملء الشاشة

استخدم عنصر التحكم بملء الشاشة عندما تريد سياقًا نمطيًا، حيث يتم استبدال واجهة مستخدم الإكمال التلقائي بواجهة المستخدم مؤقتًا إلى أن يختار المستخدم التحديد. ويتم توفير هذه الوظيفة من خلال فئة GMSAutocompleteViewController. عندما يختار المستخدم مكانًا، يتلقى تطبيقك رد اتصال.

لإضافة عنصر تحكم بملء الشاشة إلى تطبيقك:

  1. يمكنك إنشاء عنصر واجهة مستخدم في تطبيقك الرئيسي لتشغيل عنصر التحكم في الإكمال التلقائي لواجهة المستخدم، مثل معالج اللمس على UIButton.
  2. نفِّذ بروتوكول GMSAutocompleteViewControllerDelegate في وحدة التحكم في الملف الشخصي الرئيسي.
  3. أنشئ مثيلاً من GMSAutocompleteViewController وخصِّص وحدة تحكُّم الملف الشخصي الرئيسية بصفتها موقع المفوَّض.
  4. أنشئ GMSPlaceField لتحديد أنواع بيانات الأماكن المطلوب عرضها.
  5. أضف GMSAutocompleteFilter لتقييد طلب البحث على نوع مكان معيّن.
  6. قدِّم GMSAutocompleteViewController باستخدام [self presentViewController...].
  7. تعامل مع تحديد المستخدم في طريقة التفويض didAutocompleteWithPlace.
  8. يمكنك إغلاق وحدة التحكُّم في طرق تفويض 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

إضافة وحدة تحكم النتائج

استخدم وحدة تحكم النتائج عندما تريد مزيدًا من التحكم في واجهة مستخدم إدخال النص. تعمل وحدة التحكم في النتائج على تبديل مستوى رؤية قائمة النتائج ديناميكيًا بناءً على تركيز واجهة مستخدم الإدخال.

لإضافة وحدة تحكم في النتائج إلى تطبيقك:

  1. أنشئ GMSAutocompleteResultsViewController.
  2. نفِّذ بروتوكول GMSAutocompleteResultsViewControllerDelegate في وحدة تحكُّم الملف الشخصي الرئيسية وحدِّد وحدة تحكُّم الملف الشخصي الرئيسية على أنها موقع التفويض.
  3. يمكنك إنشاء كائن UISearchController، مع تمرير GMSAutocompleteResultsViewController كوسيطة للنتائج.
  4. اضبط الخاصية GMSAutocompleteResultsViewController على أنها السمة searchResultsUpdater للسمة UISearchController.
  5. أضف searchBar لـ UISearchController إلى واجهة مستخدم تطبيقك.
  6. تعامل مع تحديد المستخدم في طريقة التفويض 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 ضمن وحدة تحكُّم العرض:

  1. نفِّذ البروتوكولين GMSAutocompleteTableDataSourceDelegate وUISearchBarDelegate في وحدة التحكم في العرض.
  2. أنشئ مثيلاً في GMSAutocompleteTableDataSource وخصِّص وحدة تحكُّم العرض كخاصية المفوَّض.
  3. يمكنك ضبط GMSAutocompleteTableDataSource كمصدر بيانات وتفويض خصائص مثيل UITableView على وحدة التحكم في العرض.
  4. في معالج إدخال نص البحث، يمكنك استدعاء sourceTextHasChanged في GMSAutocompleteTableDataSource.
  5. تعامل مع اختيار المستخدم باستخدام طريقة تفويض didAutocompleteWithPlace.
  6. يمكنك تجاهل وحدة التحكُّم في طرق تفويض didAutocompleteWithPlace وdidFailAutocompleteWithError وwasCancelled.

يوضّح مثال الرمز التالي استخدام فئة GMSAutocompleteTableDataSource لزيادة قيمة العرض في جدول UIViewController عند إضافة UISearchBar بشكل منفصل.

Swift

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import GooglePlaces
import UIKit

class PlaceAutocompleteViewController: UIViewController {

  private var tableView: UITableView!
  private var tableDataSource: GMSAutocompleteTableDataSource!

  override func viewDidLoad() {
    super.viewDidLoad()

    let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: self.view.frame.size.width, height: 44.0))
    searchBar.delegate = self
    view.addSubview(searchBar)

    tableDataSource = GMSAutocompleteTableDataSource()
    tableDataSource.delegate = self

    tableView = UITableView(frame: CGRect(x: 0, y: 64, width: self.view.frame.size.width, height: self.view.frame.size.height - 44))
    tableView.delegate = tableDataSource
    tableView.dataSource = tableDataSource

    view.addSubview(tableView)
  }
}

extension PlaceAutocompleteViewController: UISearchBarDelegate {
  func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    // Update the GMSAutocompleteTableDataSource with the search text.
    tableDataSource.sourceTextHasChanged(searchText)
  }
}

extension PlaceAutocompleteViewController: GMSAutocompleteTableDataSourceDelegate {
  func didUpdateAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) {
    // Turn the network activity indicator off.
    UIApplication.shared.isNetworkActivityIndicatorVisible = false
    // Reload table data.
    tableView.reloadData()
  }

  func didRequestAutocompletePredictions(for tableDataSource: GMSAutocompleteTableDataSource) {
    // Turn the network activity indicator on.
    UIApplication.shared.isNetworkActivityIndicatorVisible = true
    // Reload table data.
    tableView.reloadData()
  }

  func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didAutocompleteWith place: GMSPlace) {
    // Do something with the selected place.
    print("Place name: \(place.name)")
    print("Place address: \(place.formattedAddress)")
    print("Place attributions: \(place.attributions)")
  }

  func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didFailAutocompleteWithError error: Error) {
    // Handle the error.
    print("Error: \(error.localizedDescription)")
  }

  func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didSelect prediction: GMSAutocompletePrediction) -> Bool {
    return true
  }
}

      

Objective-C

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "PlaceAutocompleteViewController.h"
@import GooglePlaces;
@import UIKit;

@interface PlaceAutocompleteViewController () <GMSAutocompleteTableDataSourceDelegate, UISearchBarDelegate>

@end

@implementation PlaceAutocompleteViewController {
  UITableView *tableView;
  GMSAutocompleteTableDataSource *tableDataSource;
}

- (void)viewDidLoad {
  [super viewDidLoad];

  UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)];
  searchBar.delegate = self;

  [self.view addSubview:searchBar];

  tableDataSource = [[GMSAutocompleteTableDataSource alloc] init];
  tableDataSource.delegate = self;

  tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 44)];
  tableView.delegate = tableDataSource;
  tableView.dataSource = tableDataSource;

  [self.view addSubview:tableView];
}

#pragma mark - GMSAutocompleteTableDataSourceDelegate

- (void)didUpdateAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource {
  // Turn the network activity indicator off.
  UIApplication.sharedApplication.networkActivityIndicatorVisible = NO;

  // Reload table data.
  [tableView reloadData];
}

- (void)didRequestAutocompletePredictionsForTableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource {
  // Turn the network activity indicator on.
  UIApplication.sharedApplication.networkActivityIndicatorVisible = YES;

  // Reload table data.
  [tableView reloadData];
}

- (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didAutocompleteWithPlace:(GMSPlace *)place {
  // Do something with the selected place.
  NSLog(@"Place name: %@", place.name);
  NSLog(@"Place address: %@", place.formattedAddress);
  NSLog(@"Place attributions: %@", place.attributions);
}

- (void)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didFailAutocompleteWithError:(NSError *)error {
  // Handle the error
  NSLog(@"Error %@", error.description);
}

- (BOOL)tableDataSource:(GMSAutocompleteTableDataSource *)tableDataSource didSelectPrediction:(GMSAutocompletePrediction *)prediction {
  return YES;
}

#pragma mark - UISearchBarDelegate

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
  // Update the GMSAutocompleteTableDataSource with the search text.
  [tableDataSource sourceTextHasChanged:searchText];
}

@end

      

تخصيص ألوان النص والخلفية

يمكنك تعيين ألوان جميع النصوص والخلفيات في عنصر التحكم في الإكمال التلقائي لواجهة المستخدم، وذلك لجعل الأداة تتطابق مع المظهر المرئي لتطبيقك عن كثب. هناك طريقتان لتعيين ألوان عناصر التحكم في واجهة المستخدم:

  • باستخدام بروتوكول UIUI الأصلي لنظام التشغيل iOS لتحديد عناصر تحكّم في واجهة المستخدم بنمط عام كلما أمكن ذلك. تنطبق هذه الإعدادات على العديد من عناصر التحكم في واجهة المستخدم، وليس كلها.
  • باستخدام طرق SDK في فئات الأدوات لتعيين خصائص غير متوافقة مع بروتوكول UIUI.

عادةً ما سيستخدم تطبيقك مزيجًا من بروتوكول UIUI وطرق 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المظهر

يمكنك استخدام بروتوكول UIUI للحصول على الخادم الوكيل المظهر لعنصر واجهة مستخدم معيّن، والذي يمكنك استخدامه بعد ذلك لتعيين اللون لعنصر واجهة المستخدم. عند إجراء تعديل، تتأثر جميع نسخ عنصر واجهة مستخدم معينة. على سبيل المثال، يغيّر المثال التالي لون النص من 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;

تعيين خصائص نمط التحكم في واجهة المستخدم

تحتوي مجموعة فرعية من عناصر التحكم في واجهة المستخدم على خصائص لا تتأثر ببروتوكول UIUI، ولذلك يجب تعيينها مباشرةً. يوضح مثال الرمز التالي تحديد ألوان المقدمة والخلفية، وتطبيقها على مثيل تحكم في واجهة المستخدم باسم 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:

للحصول على قائمة بأسماء الأماكن و/أو العناوين المتوقّعة، عليك أولاً تحديد قيمة GMSPlaceClient، ثم استدعاء طريقة GMSPlacesClient findAutocompletePredictionsFromQuery: مع المعلّمات التالية:

  • سلسلة autocompleteQuery تحتوي على النص الذي كتبه المستخدم.
  • GMSAutocompleteSessionToken، الذي يُستخدم لتحديد كل جلسة على حدة. يجب أن يمرّر التطبيق الرمز المميز نفسه لكل مكالمة طلب إكمال تلقائي، ثم تمرير هذا الرمز المميز، إلى جانب رقم تعريف المكان، في المكالمة التالية إلى fetchPlacefromPlaceID: لاسترداد تفاصيل المكان للمكان الذي تم تحديده من قِبل المستخدم.
  • من 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، اتّبِع الخطوات التالية:

  1. نفِّذ بروتوكول GMSAutocompleteFetcherDelegate.
  2. أنشئ كائن GMSAutocompleteFetcher.
  3. اتصل بـ sourceTextHasChanged على أداة الجلب أثناء كتابة المستخدم.
  4. التعامل مع التوقعات والأخطاء باستخدام أسلوبَي البروتوكول didAutcompleteWithPredictions وdidFailAutocompleteWithError.

يوضح المثال التالي للشفرة استخدام أداة الجلب لجلب إدخال المستخدم وعرض مطابقات الأماكن في عرض نصي. تم حذف وظيفة اختيار المكان. المشتق FetcherSampleViewController من UIViewController في GSSMOSampleViewController.h.

Swift

import UIKit
import GooglePlaces

class ViewController: UIViewController {

  var textField: UITextField?
  var resultText: UITextView?
  var fetcher: GMSAutocompleteFetcher?

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .white
    edgesForExtendedLayout = []

    // Set bounds to inner-west Sydney Australia.
    let neBoundsCorner = CLLocationCoordinate2D(latitude: -33.843366,
                                                longitude: 151.134002)
    let swBoundsCorner = CLLocationCoordinate2D(latitude: -33.875725,
                                                longitude: 151.200349)

    // Set up the autocomplete filter.
    let filter = GMSAutocompleteFilter()
    filter.locationRestriction = GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner)

    // Create a new session token.
    let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

    // Create the fetcher.
    fetcher = GMSAutocompleteFetcher(bounds: nil, filter: filter)
    fetcher?.delegate = self
    fetcher?.provide(token)

    textField = UITextField(frame: CGRect(x: 5.0, y: 10.0,
                                          width: view.bounds.size.width - 5.0,
                                          height: 64.0))
    textField?.autoresizingMask = .flexibleWidth
    textField?.addTarget(self, action: #selector(textFieldDidChange(textField:)),
                         for: .editingChanged)
    let placeholder = NSAttributedString(string: "Type a query...")

    textField?.attributedPlaceholder = placeholder

    resultText = UITextView(frame: CGRect(x: 0, y: 65.0,
                                          width: view.bounds.size.width,
                                          height: view.bounds.size.height - 65.0))
    resultText?.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
    resultText?.text = "No Results"
    resultText?.isEditable = false

    self.view.addSubview(textField!)
    self.view.addSubview(resultText!)
  }

  @objc func textFieldDidChange(textField: UITextField) {
    fetcher?.sourceTextHasChanged(textField.text!)
  }

}

extension ViewController: GMSAutocompleteFetcherDelegate {
  func didAutocomplete(with predictions: [GMSAutocompletePrediction]) {
    let resultsStr = NSMutableString()
    for prediction in predictions {
      resultsStr.appendFormat("\n Primary text: %@\n", prediction.attributedPrimaryText)
      resultsStr.appendFormat("Place ID: %@\n", prediction.placeID)
    }

    resultText?.text = resultsStr as String
  }

  func didFailAutocompleteWithError(_ error: Error) {
    resultText?.text = error.localizedDescription
  }
}

Objective-C

#import "FetcherSampleViewController.h"
#import <GooglePlaces/GooglePlaces.h>
#import <GoogleMapsBase/GoogleMapsBase.h>

@interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate>

@end

@implementation FetcherSampleViewController {
  UITextField *_textField;
  UITextView *_resultText;
  GMSAutocompleteFetcher* _fetcher;
}

- (void)viewDidLoad {
  [super viewDidLoad];

  self.view.backgroundColor = [UIColor whiteColor];
  self.edgesForExtendedLayout = UIRectEdgeNone;

  // Set bounds to inner-west Sydney Australia.
  CLLocationCoordinate2D neBoundsCorner = CLLocationCoordinate2DMake(-33.843366, 151.134002);
  CLLocationCoordinate2D swBoundsCorner = CLLocationCoordinate2DMake(-33.875725, 151.200349);

  GMSAutocompleteFilter *autocompleteFilter = [[GMSAutocompleteFilter alloc] init];
  autocompleteFilter.locationRestriction =
        GMSPlaceRectangularLocationOption(neBoundsCorner, swBoundsCorner);

  // Create the fetcher.
  _fetcher = [[GMSAutocompleteFetcher alloc] initWithBounds:nil
                                                     filter:filter];
  _fetcher.delegate = self;

  // Set up the UITextField and UITextView.
  _textField = [[UITextField alloc] initWithFrame:CGRectMake(5.0f,
                                                             0,
                                                             self.view.bounds.size.width - 5.0f,
                                                             44.0f)];
  _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  [_textField addTarget:self
                 action:@selector(textFieldDidChange:)
       forControlEvents:UIControlEventEditingChanged];
  _resultText =[[UITextView alloc] initWithFrame:CGRectMake(0,
                                                            45.0f,
                                                            self.view.bounds.size.width,
                                                            self.view.bounds.size.height - 45.0f)];
  _resultText.backgroundColor = [UIColor colorWithWhite:0.95f alpha:1.0f];
  _resultText.text = @"No Results";
  _resultText.editable = NO;
  [self.view addSubview:_textField];
  [self.view addSubview:_resultText];
}

- (void)textFieldDidChange:(UITextField *)textField {
  NSLog(@"%@", textField.text);
  [_fetcher sourceTextHasChanged:textField.text];
}

#pragma mark - GMSAutocompleteFetcherDelegate
- (void)didAutocompleteWithPredictions:(NSArray *)predictions {
  NSMutableString *resultsStr = [NSMutableString string];
  for (GMSAutocompletePrediction *prediction in predictions) {
      [resultsStr appendFormat:@"%@\n", [prediction.attributedPrimaryText string]];
  }
  _resultText.text = resultsStr;
}

- (void)didFailAutocompleteWithError:(NSError *)error {
  _resultText.text = [NSString stringWithFormat:@"%@", error.localizedDescription];
}

@end

الرموز المميزة للجلسة

تعمل الرموز المميزة للجلسة على تجميع طلبات البحث ومراحل الاختيار من بحث الإكمال التلقائي للمستخدم في جلسة منفصلة لأغراض الفوترة. تبدأ الجلسة عندما يبدأ المستخدم في كتابة طلب بحث، وتنتهي عند اختيار مكان ما. يمكن أن تحتوي كل جلسة على طلبات بحث متعددة، يتبعها تحديد مكان واحد. بعد انتهاء الجلسة، لن يكون الرمز المميز صالحًا بعد الآن، بل يجب أن ينشئ تطبيقك رمزًا مميزًا جديدًا لكل جلسة. نوصي باستخدام الرموز المميزة للجلسة لجميع جلسات الإكمال التلقائي الآلي (عند استخدام وحدة التحكم في وضع ملء الشاشة، أو وحدة التحكم في النتائج، ستهتم واجهة برمجة التطبيقات بذلك تلقائيًا).

تستخدم حزمة تطوير البرامج (SDK) للأماكن في نظام التشغيل iOS GMSAutocompleteSessionToken لتحديد كل جلسة. يجب أن يمرّر تطبيقك رمزًا مميزًا جديدًا للجلسة عند بدء كل جلسة جديدة، ثم يمرر ذلك الرمز المميز نفسه، مع رقم تعريف المكان، في الاستدعاء التالي إلى fetchPlacefromPlaceID: لاسترداد تفاصيل المكان للمكان الذي حدده المستخدم.

مزيد من المعلومات عن الرموز المميزة للجلسة.

استخدم الرمز التالي لإنشاء رمز مميز جديد للجلسة:

let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

حدود الاستخدام

عرض الإحالات في تطبيقك

  • إذا كان تطبيقك يستخدم خدمة الإكمال التلقائي آليًا، يجب أن تعرض واجهة المستخدم التصنيف "تدعمه شركة Google" أو تظهر ضمن خريطة تحمل علامة Google التجارية.
  • إذا كان تطبيقك يستخدم عنصر التحكم في الإكمال التلقائي لواجهة المستخدم، ليس عليك اتخاذ أي إجراء إضافي (يتم عرض الإحالة المطلوبة تلقائيًا).
  • في حال استرداد معلومات مكان إضافية وعرضها بعد الحصول على مكان باستخدام رقم التعريف، عليك أيضًا عرض سمات الأطراف الثالثة.

لمزيد من التفاصيل، اطّلع على الوثائق حول النسب.

التحكم في مؤشر نشاط الشبكة

للتحكم في مؤشر نشاط الشبكة في شريط حالة التطبيقات، يجب تنفيذ طرق التفويض الاختيارية المناسبة لفئة الإكمال التلقائي التي تستخدمها وتشغيل مؤشر الشبكة وإيقاف تشغيله بنفسك.

  • بالنسبة إلى GMSAutocompleteViewController، يجب تطبيق طريقتي التفويض didRequestAutocompletePredictions: وdidUpdateAutocompletePredictions:.
  • بالنسبة إلى GMSAutocompleteResultsViewController، يجب تطبيق طريقتي التفويض didRequestAutocompletePredictionsForResultsController: وdidUpdateAutocompletePredictionsForResultsController:.
  • بالنسبة إلى GMSAutocompleteTableDataSource، يجب تطبيق طريقتي التفويض didRequestAutocompletePredictionsForTableDataSource: وdidUpdateAutocompletePredictionsForTableDataSource:.

من خلال تنفيذ هاتين الطريقتين وإعداد [UIApplication sharedApplication].networkActivityIndicatorVisible على YES وNO على التوالي، سيطابق شريط الحالة واجهة مستخدم الإكمال التلقائي بشكلٍ صحيح.

تقييد نتائج الإكمال التلقائي

يمكنك تعيين عنصر تحكم الإكمال التلقائي لواجهة المستخدم لتقييد النتائج إلى منطقة جغرافية محددة، و/أو تصفية النتائج لنوع واحد أو أكثر من الأماكن، أو لبلد أو بلدان معينة. لتقييد النتائج، يمكنك إجراء ما يلي:

  • لتفضيل (الانحياز) النتائج داخل المنطقة المحددة، عيّن locationBias على GMSAutocompleteFilter (قد يستمر عرض بعض النتائج من خارج المنطقة المحددة). إذا تم ضبط locationRestriction أيضًا، سيتم تجاهل locationBias.
  • لعرض النتائج فقط (حصرها) داخل المنطقة المحددة، اضبط locationRestriction على GMSAutocompleteFilter (سيتم عرض النتائج داخل المنطقة المحددة فقط).

    • ملاحظة: يتم تطبيق هذا التقييد على المسارات بأكملها فقط، وقد يتم عرض النتائج التركيبية خارج الحدود المستطيلة استنادًا إلى مسار يتداخل مع قيد الموقع.
  • لعرض النتائج التي تتوافق فقط مع نوع مكان معيّن، اضبط type على 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، أو أداة SDK للأماكن في Android أداة الإكمال التلقائي، أو حزمة SDK لـ الأماكن لنظام التشغيل iOS التحكم في الإكمال التلقائي لواجهة مستخدم
  • اكتسِب فهمًا أساسيًا لحقول البيانات الخاصة بميزة "الإكمال التلقائي" الخاصة بالأماكن.
  • حقلا انحياز الموقع وتقييد الموقع اختياريان ولكن يمكن أن يكون لهما تأثير كبير على أداء الإكمال التلقائي.
  • استخدِم معالجة الأخطاء للتأكّد من انخفاض جودة التطبيق بشكلٍ سليم في حال عرض واجهة برمجة التطبيقات لأي خطأ.
  • يُرجى التأكّد من أنّ تطبيقك يتعامل مع التطبيق في حال عدم توفّره، ويوفّر للمستخدمين طريقة للمتابعة.

أفضل ممارسات تحسين التكلفة

تحسين التكلفة الأساسي

لتحسين تكلفة استخدام خدمة الإكمال التلقائي للأماكن، استخدم أقنعة الحقل في أداتي تفاصيل المكان والإكمال التلقائي لعرض حقول بيانات الأماكن التي تحتاجها فقط.

تحسين متقدم للتكلفة

جرِّب التنفيذ الآلي لميزة "الإكمال التلقائي" للمكان من أجل الوصول إلى التسعير حسب الطلب وطلب نتائج واجهة برمجة التطبيقات للترميز الجغرافي حول المكان المحدد بدلاً من تفاصيل المكان. ويكون تسعير "لكل طلب" مقترنًا بواجهة برمجة تطبيقات الترميز الجغرافي أكثر فعالية من حيث التكلفة من التسعير لكل جلسة (مستند إلى الجلسة) في حالة استيفاء الشرطين التاليين:

  • إذا كنت تحتاج فقط إلى خط العرض/خط الطول أو عنوان المكان المحدد للمستخدم، فستوفر واجهة برمجة تطبيقات الترميز الجغرافي هذه المعلومات بأقل من طلب عرض تفاصيل المكان.
  • إذا حدد المستخدمون توقع الإكمال التلقائي في حدود أربعة طلبات توقع في الإكمال التلقائي أو أقل في المتوسط، فقد تكون ميزة التسعير لكل طلب أكثر فعالية من حيث التكلفة من التسعير لكل جلسة.
للحصول على مساعدة في اختيار تنفيذ "الإكمال التلقائي" للمكان الذي يناسب احتياجاتك، اختَر علامة التبويب المقابلة لإجابتك على السؤال التالي.

هل يتطلب تطبيقك أي معلومات بخلاف العنوان وخط العرض/خط الطول للتوقع المحدد؟

نعم، بحاجة إلى المزيد من التفاصيل

استخدام ميزة "الإكمال التلقائي للأماكن" المستندة إلى الجلسة مع تفاصيل المكان
وبما أنّ تطبيقك يتطلّب تفاصيل المكان، مثل اسم المكان أو حالة النشاط التجاري أو ساعات العمل، يجب أن تستخدم عملية "الإكمال التلقائي" للمكان رمزًا مميزًا للجلسة (برمجيًا أو مضمّنًا في أدوات JavaScript أو Android أو iOS) بتكلفة إجمالية تبلغ 0.017 لكل جلسة بالإضافة إلى رموز تخزين تعريفية لبيانات الأماكن استنادًا إلى حقول بيانات الأماكن التي تطلبها1}.

تنفيذ الأداة
يتم دمج إدارة الجلسات تلقائيًا في أدوات JavaScript أو Android أو iOS. ويتضمن ذلك كلاً من طلبات الإكمال التلقائي للأماكن وطلب تفاصيل المكان على التوقع المحدد. احرص على تحديد المَعلمة fields لضمان أنك تطلب فقط حقول بيانات الأماكن التي تحتاجها فقط.

التنفيذ الآلي
استخدِم رمزًا مميّزًا للجلسة مع طلبات الإكمال التلقائي للأماكن. عند طلب تفاصيل المكان حول التوقع المحدد، أدرج المعلمات التالية:

  1. رقم تعريف المكان من الاستجابة التلقائية للمكان
  2. الرمز المميز للجلسة المستخدم في طلب الإكمال التلقائي للمكان
  3. المعلمة fields التي تحدّد حقول بيانات الأماكن التي تحتاجها

لا، يحتاج إلى العنوان والموقع فقط

يمكن أن تكون واجهة برمجة تطبيقات الترميز الجغرافي خيارًا أكثر فعالية من حيث التكلفة من "تفاصيل المكان" لتطبيقك، بناءً على أداء استخدام الإكمال التلقائي للمكان. تختلف كفاءة الإكمال التلقائي لكل تطبيق اعتمادًا على ما يدخله المستخدمون، ومكان استخدام التطبيق، وما إذا تم تنفيذ أفضل ممارسات تحسين الأداء أم لا.

للإجابة عن السؤال التالي، يجب تحليل عدد الأحرف التي يكتبها المستخدم في المتوسط قبل تحديد توقع الإكمال التلقائي في تطبيقك.

هل يختار المستخدمون توقع الإكمال التلقائي للأماكن من خلال أربعة طلبات أو أقل في المتوسط؟

متوافق

تنفيذ ميزة "الإكمال التلقائي للأماكن" آليًا بدون الحاجة إلى رموز مميَّزة للجلسة واستدعاء واجهة برمجة التطبيقات للترميز الجغرافي في ميزة "توقُّع المكان" التي تم اختيارها.
توفّر واجهة برمجة التطبيقات للترميز الجغرافي عناوين وإحداثيات خطوط طول/دوائر عرض مقابل 0.005 دولار أمريكي لكل طلب. تصل تكلفة تنفيذ أربعة طلبات إكمال تلقائي للمكان - لكل طلب إلى 0.01132 دولار أمريكي (أو ما يعادله بالعملة المحلية)، لذلك فإن التكلفة الإجمالية لأربعة طلبات بالإضافة إلى استدعاء واجهة برمجة التطبيقات للترميز الجغرافي حول توقع المكان المحدد ستكون 0.01632 دولار أمريكي (أو ما يعادله بالعملة المحلية)؛ وهو أقل من سعر الإكمال التلقائي لكل جلسة 0.017 دولار أمريكي (أو ما يعادله بالعملة المحلية) لكل جلسة.1

جرّب استخدام أفضل ممارسات الأداء لمساعدة المستخدمين في الحصول على التوقعات التي يبحثون عنها بعدد أحرف أقل.

لا

استخدام ميزة "الإكمال التلقائي للأماكن" المستندة إلى الجلسة مع تفاصيل المكان
نظرًا لأن متوسط عدد الطلبات التي تتوقع أن تقدمها قبل أن يختار أحد المستخدمين توقع الإكمال التلقائي للأماكن يتجاوز تكلفة التسعير لكل جلسة، ينبغي أن يستخدم تنفيذ ميزة الإكمال التلقائي للأماكن رمزًا مميزًا للجلسة لكلٍّ من طلبات الإكمال التلقائي للمكان وطلبات تفاصيل المكان المقترنة بتكلفة إجمالية تبلغ 0.017 دولار أمريكي لكل جلسة.1

تنفيذ الأداة
يتم دمج إدارة الجلسات تلقائيًا في أدوات JavaScript أو Android أو iOS. ويتضمن ذلك كلاً من طلبات الإكمال التلقائي للأماكن وطلب تفاصيل المكان على التوقع المحدد. تأكد من تحديد المعلمة fields لضمان أنك تطلب حقول البيانات الأساسية فقط.

التنفيذ الآلي
استخدِم رمزًا مميّزًا للجلسة مع طلبات الإكمال التلقائي للأماكن. عند طلب تفاصيل المكان حول التوقع المحدد، أدرج المعلمات التالية:

  1. رقم تعريف المكان من الاستجابة التلقائية للمكان
  2. الرمز المميز للجلسة المستخدم في طلب الإكمال التلقائي للمكان
  3. المعلمة fields التي تحدد حقول البيانات الأساسية مثل العنوان والهندسة

فكّر في تأخير طلبات الإكمال التلقائي للأماكن
يمكنك استخدام استراتيجيات مثل تأخير طلب الإكمال التلقائي للمكان حتى يكتب المستخدم الأحرف الثلاثة أو الأربعة الأولى حتى يقل عدد الطلبات التي يقدّمها تطبيقك. على سبيل المثال، يعني تقديم طلبات الإكمال التلقائي للأماكن لكل حرف بعد كتابة المستخدم للحرف الثالث أنه إذا كتب المستخدم سبعة أحرف ثم اختار توقعًا يمكنك من خلاله تقديم طلب واحد لواجهة برمجة تطبيقات الترميز الجغرافي، فستصبح التكلفة الإجمالية 0.01632 دولار أمريكي (4 * 0.00283 الإكمال التلقائي لكل طلب + 0.005 دولار أمريكي للترميز الجغرافي).1

إذا كان يمكن لتأخير الطلبات الحصول على متوسط طلب آلي أقل من أربعة، يمكنك اتّباع إرشادات الإكمال التلقائي الفعّال للمكان باستخدام واجهة برمجة التطبيقات للترميز الجغرافي. لاحظ أن تأخير الطلبات يمكن اعتباره وقت استجابة من قِبل المستخدم الذي قد يتوقع رؤية توقعات مع كل ضغطة مفتاح جديدة.

جرّب استخدام أفضل ممارسات الأداء لمساعدة المستخدمين في الحصول على التوقعات التي يبحثون عنها بعدد أحرف أقل.


  1. التكاليف المدرجة هنا بالدولار الأمريكي. يُرجى الرجوع إلى صفحة الفوترة في "منصة خرائط Google" للحصول على المعلومات الكاملة عن الأسعار.

أفضل ممارسات الأداء

تصف الإرشادات التالية طرق تحسين أداء الإكمال التلقائي للأماكن:

  • أضف القيود المفروضة على البلدان وانحياز الموقع وتفضيل اللغة (لعمليات التنفيذ الآلية) في تنفيذ الإكمال التلقائي للأماكن. ليس من الضروري اختيار اللغة باستخدام الأدوات، لأنها تختار الإعدادات المفضّلة للغة من متصفّح المستخدم أو جهازه الجوّال.
  • إذا كانت ميزة الإكمال التلقائي للأماكن مصحوبة بخريطة، فيمكنك انحياز الموقع حسب إطار عرض الخريطة.
  • في الحالات التي لا يختار فيها المستخدم أحد توقّعات الإكمال التلقائي، بشكل عام لأنّ أيًا من هذه التوقّعات لا تمثل عنوان النتيجة المطلوبة، يمكنك إعادة استخدام الإدخال الأصلي للمستخدم في محاولة للحصول على نتائج أكثر صلة: تشمل السيناريوهات الأخرى التي يكون من الأفضل فيها الرجوع إلى واجهة برمجة تطبيقات الترميز الجغرافي ما يلي:
    • المستخدمون الذين يُدخِلون عناوين مؤسسات فرعية في البلدان التي يكون فيها دعم الإكمال التلقائي للأماكن في العنوان الفرعي غير مكتمل، على سبيل المثال، التشيك وإستونيا وليتوانيا. على سبيل المثال، يؤدي العنوان التشيكي "Stroupezhnického 3191/17, Praha" إلى ظهور توقع جزئي في ميزة "الإكمال التلقائي" للمكان.
    • المستخدمون الذين يُدخِلون عناوين تحتوي على بادئات أجزاء الطريق، مثل "23-30 29th St, Queens" في مدينة نيويورك أو "47-380 Kamehameha Hwy، Kaneohe" في جزيرة كاواي في هاواي.

تحديد المشاكل وحلّها

على الرغم من أنه يمكن حدوث مجموعة متنوعة من الأخطاء، فإن معظم الأخطاء التي من المحتمل أن يواجهها تطبيقك تكون ناتجة عن أخطاء في التهيئة (على سبيل المثال، تم استخدام مفتاح واجهة برمجة تطبيقات غير صحيح أو تمت تهيئة مفتاح واجهة برمجة التطبيقات بشكل غير صحيح)، أو بسبب أخطاء في الحصة (تجاوز تطبيقك الحصة المخصصة له). راجع حدود الاستخدام للحصول على مزيد من المعلومات حول الحصص.

يتم عرض الأخطاء التي تحدث أثناء استخدام عناصر التحكم في الإكمال التلقائي باستخدام طريقة didFailAutocompleteWithError() للبروتوكولات المفوضة المختلفة. تم ضبط الخاصية code لكائن NSError المقدّم على إحدى قيم التعداد GMSPlacesErrorCode.