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

اختيار النظام الأساسي: نظام التشغيل Android iOS JavaScript خدمة ويب

يتم إرجاع خدمة الإكمال التلقائي في حزم الأماكن لأجهزة 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:@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

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

يمكنك استخدام وحدة تحكّم بالنتائج إذا أردت التحكّم بشكل أكبر في واجهة مستخدم إدخال النص. تعمل وحدة التحكم في النتائج على إيقاف ظهور قائمة النتائج بشكل ديناميكي. استنادًا إلى التركيز على واجهة المستخدم المُدخَلة.

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

  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).

سيستخدم تطبيقك عادةً مزيجًا من بروتوكول واجهة المستخدم (UIالمظهر). وطرق SDK. يوضّح المخطّط التالي العناصر التي يمكن تصميمها:

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

يسرد الجدول التالي جميع عناصر واجهة المستخدم، ويوضح كيف أن كل يجب اختيار نمط (بروتوكول واجهة برمجة التطبيقات أو طريقة حزمة تطوير البرامج (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يقتصر على

يمكنك استخدام بروتوكول واجهة برمجة التطبيقات API. للحصول على وكيل المظهر لعنصر واجهة مستخدم معين، والذي يمكنك استخدامه بعد ذلك لتعيين لون عنصر واجهة المستخدم. عند إجراء تعديل، فإن جميع مثيلات يتأثر عنصر واجهة مستخدم معين. فعلى سبيل المثال، ينطبق المثال التالي على مستوى العالم تغيير لون نص صفوف UITextField إلى اللون الأخضر عند مضمّنة في UISearchBar:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil]
    setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}];

لمزيد من المعلومات حول تحديد قيم الألوان، راجع UIColor Class Reference.

تعرض مقتطفات الرمز التالية جميع أوامر الخادم الوكيل التي تحتاج إلى استخدامها نمط كل شيء في عنصر تحكم الإكمال التلقائي في واجهة المستخدم بملء الشاشة. إضافة هذا الرمز إلى الطريقة didFinishLaunchingWithOptions في Appdelegate.m:

// Define some colors.
UIColor *darkGray = [UIColor darkGrayColor];
UIColor *lightGray = [UIColor lightGrayColor];

// Navigation bar background.
[[UINavigationBar appearance] setBarTintColor:darkGray];
[[UINavigationBar appearance] setTintColor:lightGray];

// Color of typed text in the search bar.
NSDictionary *searchBarTextAttributes = @{
                                          NSForegroundColorAttributeName: lightGray,
                                          NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]]
                                          };
[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]]
    .defaultTextAttributes = searchBarTextAttributes;

// Color of the placeholder text in the search bar prior to text entry.
NSDictionary *placeholderAttributes = @{
                                        NSForegroundColorAttributeName: lightGray,
                                        NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]]
                                        };

// Color of the default search text.
// NOTE: In a production scenario, "Search" would be a localized string.
NSAttributedString *attributedPlaceholder =
[[NSAttributedString alloc] initWithString:@"Search"
                                attributes:placeholderAttributes];
[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]]
    .attributedPlaceholder = attributedPlaceholder;

// Color of the in-progress spinner.
[[UIActivityIndicatorView appearance] setColor:lightGray];

// To style the two image icons in the search bar (the magnifying glass
// icon and the 'clear text' icon), replace them with different images.
[[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x_high"]
                  forSearchBarIcon:UISearchBarIconClear
                            state:UIControlStateHighlighted];
[[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_clear_x"]
                  forSearchBarIcon:UISearchBarIconClear
                            state:UIControlStateNormal];
[[UISearchBar appearance] setImage:[UIImage imageNamed:@"custom_search"]
                    forSearchBarIcon:UISearchBarIconSearch
                            state:UIControlStateNormal];

// Color of selected table cells.
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.backgroundColor = [UIColor lightGrayColor];
[UITableViewCell appearanceWhenContainedIn:[GMSAutocompleteViewController class], nil]
    .selectedBackgroundView = selectedBackgroundView;

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

مجموعة فرعية من عناصر التحكم في واجهة المستخدم لها خصائص لا تتأثر ويجب ضبطها مباشرةً. مثال التعليمة البرمجية التالي عرض تحديد ألوان المقدمة والخلفية، وتطبيقها على واجهة المستخدم مثيل تحكّم باسم acController. أضِف هذا الرمز إلى onLaunchClicked. في ViewController.m:

UIColor *darkGray = [UIColor darkGrayColor];
UIColor *lightGray = [UIColor lightGrayColor];

acController.secondaryTextColor = [UIColor colorWithWhite:1.0f alpha:0.5f];
acController.primaryTextColor = lightGray;
acController.primaryTextHighlightColor = [UIColor grayColor];
acController.tableCellBackgroundColor = darkGray;
acController.tableCellSeparatorColor = lightGray;
acController.tintColor = lightGray;

الحصول على توقعات الأماكن آليًا

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

سيتم الاتصال بالرقم GMSPlacesClient findAutocompletePredictionsFromQuery:

للحصول على قائمة بأسماء و/أو عناوين الأماكن المتوقعة، أولاً instantiate GMSPlacesClient, ثم استدعِ GMSPlacesClient findAutocompletePredictionsFromQuery: بالمعلمات التالية:

  • سلسلة autocompleteQuery تحتوي على النص الذي كتبه المستخدم.
  • A GMSAutocompleteSessionToken, والذي يستخدم لتحديد كل جلسة على حدة. يجب أن وتمرير الرمز المميز نفسه لكل طلب طلب إكمال تلقائي، ثم تمرير هذا الرمز، مع رقم تعريف المكان، في المكالمة اللاحقة إلى fetchPlacefromPlaceID: لاسترداد تفاصيل المكان للمكان الذي حدده المستخدم.
  • GMSAutocompleteFilter لإجراء ما يلي:
    • التحيز أو قصر النتائج على منطقة معينة.
    • حصر النتائج على نوع مكان محدّد.
    • عنصر GMSPlaceLocationBias/Restriction لانحياز النتائج إلى منطقة معيّنة تحدّدها حدود خطوط الطول والعرض
  • طريقة معاودة الاتصال للتعامل مع التوقعات التي تم عرضها.

تعرض أمثلة الرموز أدناه مكالمة هاتفية إلى findAutocompletePredictionsFromQuery:.

Swift

/**
 * Create a new session token. Be sure to use the same token for calling
 * findAutocompletePredictions, as well as the subsequent place details request.
 * This ensures that the user's query and selection are billed as a single session.
 */
let token = GMSAutocompleteSessionToken.init()

// Create a type filter.
let filter = GMSAutocompleteFilter()
filter.types = [.bank] 
filter.locationBias = GMSPlaceRectangularLocationOption( northEastBounds,
                                   southWestBounds);

placesClient?.findAutocompletePredictions(fromQuery: "cheesebu",

                                          filter: filter,
                                          sessionToken: token,
                                          callback: { (results, error) in
    if let error = error {
      print("Autocomplete error: \(error)")
      return
    }
    if let results = results {
      for result in results {
        print("Result \(result.attributedFullText) with placeID \(result.placeID)")
      }
    }
})

Objective-C

/**
 * Create a new session token. Be sure to use the same token for calling
 * findAutocompletePredictionsFromQuery:, as well as the subsequent place details request.
 * This ensures that the user's query and selection are billed as a single session.
 */
GMSAutocompleteSessionToken *token = [[GMSAutocompleteSessionToken alloc] init];

// Create a type filter.
GMSAutocompleteFilter *_filter = [[GMSAutocompleteFilter alloc] init];
_filter.types = @[ kGMSPlaceTypeBank ];

[_placesClient findAutocompletePredictionsFromQuery:@"cheesebu"
filter:_filter sessionToken:token callback:^(NSArray<GMSAutocompletePrediction *> * _Nullable results, NSError * _Nullable error) {
  if (error != nil) {
    NSLog(@"An error occurred %@", [error localizedDescription]);
    return;
  }
  if (results != nil) {
    for (GMSAutocompletePrediction *result in results) {
      NSLog(@"Result %@ with PlaceID %@", result.attributedFullText, result.placeID);
    }
  }
}];

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

كل GMSAutocompletePrediction على المعلومات التالية:

  • attributedFullText – النص الكامل للتنبؤ، في شكل NSAttributedString. على سبيل المثال: "دار الأوبرا المصرية، الإمارات العربية المتحدة"، ويلز وأستراليا. كل نطاق نصي يطابق إدخال المستخدم له kGMSAutocompleteMatchAttribute. يمكنك استخدام هذه السمة تمييز النص المطابق في طلب بحث المستخدم، على سبيل المثال، كما هو موضح أدناه.
  • placeID – رقم تعريف المكان للمكان المتوقّع رقم تعريف المكان هو معرِّفًا نصيًا يعرّف المكان بشكل فريد. لمزيد من المعلومات عن أرقام تعريف الأماكن، اطّلِع على نظرة عامة على رقم تعريف المكان.
  • distanceMeters – المسافة المستقيمة من الخط المحدد origin إلى الوجهة. لا يتم تحديد مسافة إذا لم يتم ضبط السمة origin. سيتم إرجاعه.

يوضح مثال الرمز التالي كيفية تمييز الأجزاء بالخط الغامق للنتيجة التي تتطابق مع النص في طلب بحث المستخدم، باستخدام enumerateAttribute:

Swift

let regularFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
let boldFont = UIFont.boldSystemFont(ofSize: UIFont.labelFontSize)

let bolded = prediction.attributedFullText.mutableCopy() as! NSMutableAttributedString
bolded.enumerateAttribute(kGMSAutocompleteMatchAttribute, in: NSMakeRange(0, bolded.length), options: []) {
  (value, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
    let font = (value == nil) ? regularFont : boldFont
    bolded.addAttribute(NSFontAttributeName, value: font, range: range)
}

label.attributedText = bolded
    

Objective-C

UIFont *regularFont = [UIFont systemFontOfSize:[UIFont labelFontSize]];
UIFont *boldFont = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];

NSMutableAttributedString *bolded = [prediction.attributedFullText mutableCopy];
[bolded enumerateAttribute:kGMSAutocompleteMatchAttribute
                   inRange:NSMakeRange(0, bolded.length)
                   options:0
                usingBlock:^(id value, NSRange range, BOOL *stop) {
                  UIFont *font = (value == nil) ? regularFont : boldFont;
                  [bolded addAttribute:NSFontAttributeName value:font range:range];
                }];

label.attributedText = bolded;
    

استخدام برنامج الجلب

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

لتنفيذ GMSAutocompleteFetcher، اتّخاذ الخطوات التالية:

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

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

Swift

import UIKit
import GooglePlaces

class ViewController: UIViewController {

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

  override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = .white
    edgesForExtendedLayout = []

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

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

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

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

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

    textField?.attributedPlaceholder = placeholder

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

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

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

}

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

    resultText?.text = resultsStr as String
  }

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

Objective-C

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

@interface FetcherSampleViewController () <GMSAutocompleteFetcherDelegate>

@end

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

- (void)viewDidLoad {
  [super viewDidLoad];

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

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

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

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

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

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

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

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

@end

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

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

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

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

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

let token: GMSAutocompleteSessionToken = GMSAutocompleteSessionToken.init()

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

عرض عمليات تحديد المصدر في تطبيقك

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

لمزيد من التفاصيل، راجع الوثائق على الإحالة.

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

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

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

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

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

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

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

    • ملاحظة: لا يسري هذا الحظر إلا على مسارات كاملة، سواء كانت اصطناعية قد يتم عرض النتائج التي تقع خارج الحدود المستطيلة استنادًا إلى مسار يتداخل مع تقييد الموقع الجغرافي.
  • لعرض النتائج التي تتوافق فقط مع نوع مكان معيّن، اضبط types. في GMSAutocompleteFilter، (على سبيل المثال، تحديد TypeFilter.ADDRESS إلى عرض الأداة نتائج ذات عنوان دقيق فقط).

  • لعرض نتائج في غضون خمسة بلدان محددة فقط، قم بتعيين countries على GMSAutocompleteFilter.

نتائج التحيز لمنطقة معينة

إذا أردت تفضيل (انحياز) النتائج ضمن المنطقة المحددة، يجب ضبط locationBias على. GMSAutocompleteFilter، كما هو موضح هنا:

  northEast = CLLocationCoordinate2DMake(39.0, -95.0);
  southWest = CLLocationCoordinate2DMake(37.5, -100.0);
  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.locationBias = GMSPlaceRectangularLocationOption(northEast, southWest);

حصر النتائج بمنطقة معيّنة

إذا أردت عرض (تقييد) النتائج ضمن المنطقة المحددة فقط، اضبط locationRestriction في GMSAutocompleteFilter، كما هو موضّح هنا:

  northEast = CLLocationCoordinate2DMake(39.0, -95.0);
  southWest = CLLocationCoordinate2DMake(37.5, -100.0);
  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.locationRestriction = GMSPlaceRectangularLocationOption(northEast, southWest);

فلترة النتائج حسب البلد

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

  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.countries = @[ @"au", @"nz" ];

فلترة النتائج حسب نوع المكان أو نوع المجموعة

يمكنك تقييد النتائج إلى أن تكون من نوع معين أو مجموعة من الأنواع عن طريق تعيين خاصية types من GMSAutoCompleteFilter استخدِم هذه السمة لتحديد الفلاتر المدرجة في الجداول 1 و2 و3 في أنواع الأماكن: إذا لم يتم تحديد أي شيء، سيتم عرض جميع الأنواع.

لتحديد نوع أو نوع فلتر مجموعة:

  • استخدِم السمة types لتحديد ما يصل إلى خمس قيم type من الجدول 1. والجدول 2 المعروض في أنواع الأماكن. قيم النوع هي محددة بالثوابت في GMSPlaceType.

  • استخدِم السمة types لتحديد مجموعة أنواع من الجدول 3 المعروض. في أنواع الأماكن. يتم تحديد قيم مجموعة النوع من خلال الثوابت في GMSPlaceType.

    يُسمح بنوع واحد فقط من الجدول 3 في الطلب. إذا حددت من الجدول 3، فلا يمكنك تحديد قيمة من الجدول 1 أو الجدول 2. في حال حذف فإنك تفعل ذلك، فسيحدث خطأ.

فعلى سبيل المثال، لعرض النتائج التي تتوافق مع نوع مكان معين فقط، قم بتعيين types على GMSAutocompleteFilter. يوضح المثال التالي إعداد تصفية لعرض النتائج فقط ذات عنوان دقيق:

  GMSAutocompleteFilter *filter = [[GMSAutocompleteFilter alloc] init];
  filter.types = @[ kGMSPlaceTypeAirport, kGMSPlaceTypeAmusementPark ];

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

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

في ما يلي بعض الإرشادات العامة:

  • إن أسرع طريقة لتطوير واجهة مستخدم عاملة هي استخدام أداة الإكمال التلقائي لواجهة JavaScript API للخرائط، حزمة تطوير برامج الأماكن لأداة الإكمال التلقائي لنظام التشغيل Android أو حزمة تطوير برامج الأماكن لعنصر الإكمال التلقائي في واجهة المستخدم لنظام التشغيل iOS
  • التعرّف على ميزة "الإكمال التلقائي" الأساسية للأماكن حقول البيانات من البداية.
  • يعد انحياز الموقع وتقييد الموقع اختياريًا ولكن يمكن تؤثر بشكل كبير في أداء ميزة الإكمال التلقائي
  • يجب التعامل مع الأخطاء للتأكّد من تراجع أداء تطبيقك بشكل سلس. إذا كانت واجهة برمجة التطبيقات تعرض خطأً.
  • يجب التأكُّد من معالجة تطبيقك في حال عدم توفّر مجموعة محدَّدة وتوفير طريقة للمستخدمين. للمتابعة.

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

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

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

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

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

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

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

نعم، يجب توفير المزيد من التفاصيل.

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

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

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

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

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

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

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

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

نعم

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

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

لا

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

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

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

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

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

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

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


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

أفضل الممارسات المتعلقة بالأداء

توضّح الإرشادات التالية طُرق تحسين أداء ميزة "الإكمال التلقائي" للأماكن:

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

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

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

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