انتخاب مکان فعلی و نمایش جزئیات روی نقشه
این آموزش، ساخت یک برنامه iOS را نشان میدهد که مکان فعلی دستگاه را بازیابی میکند، مکانهای احتمالی را شناسایی میکند، از کاربر میخواهد بهترین مورد منطبق را انتخاب کند و یک نشانگر نقشه برای مکان انتخاب شده نمایش میدهد.
این برنامه برای کسانی که دانش اولیه یا متوسطی از Swift یا Objective-C و دانش عمومی از Xcode دارند، مناسب است. برای راهنمای پیشرفته ایجاد نقشهها، راهنمای توسعهدهندگان را مطالعه کنید.
شما با استفاده از این آموزش نقشه زیر را ایجاد خواهید کرد. نشانگر نقشه در سانفرانسیسکو، کالیفرنیا قرار دارد، اما به هر جایی که دستگاه یا شبیهساز قرار دارد، منتقل میشود.

این آموزش از Places SDK برای iOS ، Maps SDK برای iOS و فریمورک Apple Core Location استفاده میکند.
کد را دریافت کنید
مخزن نمونههای iOS نقشههای گوگل را از گیتهاب کپی یا دانلود کنید.روش دیگر، برای دانلود کد منبع روی دکمه زیر کلیک کنید:
کنترلر نمای نقشه
سویفت
import UIKit import GoogleMaps import GooglePlaces class MapViewController: UIViewController { var locationManager: CLLocationManager! var currentLocation: CLLocation? var mapView: GMSMapView! var placesClient: GMSPlacesClient! var preciseLocationZoomLevel: Float = 15.0 var approximateLocationZoomLevel: Float = 10.0 // An array to hold the list of likely places. var likelyPlaces: [GMSPlace] = [] // The currently selected place. var selectedPlace: GMSPlace? // Update the map once the user has made their selection. @IBAction func unwindToMain(segue: UIStoryboardSegue) { // Clear the map. mapView.clear() // Add a marker to the map. if let place = selectedPlace { let marker = GMSMarker(position: place.coordinate) marker.title = selectedPlace?.name marker.snippet = selectedPlace?.formattedAddress marker.map = mapView } listLikelyPlaces() } override func viewDidLoad() { super.viewDidLoad() // Initialize the location manager. locationManager = CLLocationManager() locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestWhenInUseAuthorization() locationManager.distanceFilter = 50 locationManager.startUpdatingLocation() locationManager.delegate = self placesClient = GMSPlacesClient.shared() // A default location to use when location permission is not granted. let defaultLocation = CLLocation(latitude: -33.869405, longitude: 151.199) // Create a map. let zoomLevel = locationManager.accuracyAuthorization == .fullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude, longitude: defaultLocation.coordinate.longitude, zoom: zoomLevel) mapView = GMSMapView.map(withFrame: view.bounds, camera: camera) mapView.settings.myLocationButton = true mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.isMyLocationEnabled = true // Add the map to the view, hide it until we've got a location update. view.addSubview(mapView) mapView.isHidden = true listLikelyPlaces() } // Populate the array with the list of likely places. func listLikelyPlaces() { // Clean up from previous sessions. likelyPlaces.removeAll() let placeFields: GMSPlaceField = [.name, .coordinate] placesClient.findPlaceLikelihoodsFromCurrentLocation(withPlaceFields: placeFields) { (placeLikelihoods, error) in guard error == nil else { // TODO: Handle the error. print("Current Place error: \(error!.localizedDescription)") return } guard let placeLikelihoods = placeLikelihoods else { print("No places found.") return } // Get likely places and add to the list. for likelihood in placeLikelihoods { let place = likelihood.place self.likelyPlaces.append(place) } } } // Prepare the segue. override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "segueToSelect" { if let nextViewController = segue.destination as? PlacesViewController { nextViewController.likelyPlaces = likelyPlaces } } } } // Delegates to handle events for the location manager. extension MapViewController: CLLocationManagerDelegate { // Handle incoming location events. func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location: CLLocation = locations.last! print("Location: \(location)") let zoomLevel = locationManager.accuracyAuthorization == .fullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: zoomLevel) if mapView.isHidden { mapView.isHidden = false mapView.camera = camera } else { mapView.animate(to: camera) } listLikelyPlaces() } // Handle authorization for the location manager. func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { // Check accuracy authorization let accuracy = manager.accuracyAuthorization switch accuracy { case .fullAccuracy: print("Location accuracy is precise.") case .reducedAccuracy: print("Location accuracy is not precise.") @unknown default: fatalError() } // Handle authorization status switch status { case .restricted: print("Location access was restricted.") case .denied: print("User denied access to location.") // Display the map using the default location. mapView.isHidden = false case .notDetermined: print("Location status not determined.") case .authorizedAlways: fallthrough case .authorizedWhenInUse: print("Location status is OK.") @unknown default: fatalError() } } // Handle location manager errors. func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { locationManager.stopUpdatingLocation() print("Error: \(error)") } }
هدف-سی
#import "MapViewController.h" #import "PlacesViewController.h" @import CoreLocation; @import GooglePlaces; @import GoogleMaps; @interface MapViewController () <CLLocationManagerDelegate> @end @implementation MapViewController { CLLocationManager *locationManager; CLLocation * _Nullable currentLocation; GMSMapView *mapView; GMSPlacesClient *placesClient; float preciseLocationZoomLevel; float approximateLocationZoomLevel; // An array to hold the list of likely places. NSMutableArray<GMSPlace *> *likelyPlaces; // The currently selected place. GMSPlace * _Nullable selectedPlace; } - (void)viewDidLoad { [super viewDidLoad]; preciseLocationZoomLevel = 15.0; approximateLocationZoomLevel = 15.0; // Initialize the location manager. locationManager = [[CLLocationManager alloc] init]; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager requestWhenInUseAuthorization]; locationManager.distanceFilter = 50; [locationManager startUpdatingLocation]; locationManager.delegate = self; placesClient = [GMSPlacesClient sharedClient]; // A default location to use when location permission is not granted. CLLocationCoordinate2D defaultLocation = CLLocationCoordinate2DMake(-33.869405, 151.199); // Create a map. float zoomLevel = locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel; GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:defaultLocation.latitude longitude:defaultLocation.longitude zoom:zoomLevel]; mapView = [GMSMapView mapWithFrame:self.view.bounds camera:camera]; mapView.settings.myLocationButton = YES; mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; mapView.myLocationEnabled = YES; // Add the map to the view, hide it until we've got a location update. [self.view addSubview:mapView]; mapView.hidden = YES; [self listLikelyPlaces]; } // Populate the array with the list of likely places. - (void) listLikelyPlaces { // Clean up from previous sessions. likelyPlaces = [NSMutableArray array]; GMSPlaceField placeFields = GMSPlaceFieldName | GMSPlaceFieldCoordinate; [placesClient findPlaceLikelihoodsFromCurrentLocationWithPlaceFields:placeFields callback:^(NSArray<GMSPlaceLikelihood *> * _Nullable likelihoods, NSError * _Nullable error) { if (error != nil) { // TODO: Handle the error. NSLog(@"Current Place error: %@", error.localizedDescription); return; } if (likelihoods == nil) { NSLog(@"No places found."); return; } for (GMSPlaceLikelihood *likelihood in likelihoods) { GMSPlace *place = likelihood.place; [likelyPlaces addObject:place]; } }]; } // Update the map once the user has made their selection. - (void) unwindToMain:(UIStoryboardSegue *)segue { // Clear the map. [mapView clear]; // Add a marker to the map. if (selectedPlace != nil) { GMSMarker *marker = [GMSMarker markerWithPosition:selectedPlace.coordinate]; marker.title = selectedPlace.name; marker.snippet = selectedPlace.formattedAddress; marker.map = mapView; } [self listLikelyPlaces]; } // Prepare the segue. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"segueToSelect"]) { if ([segue.destinationViewController isKindOfClass:[PlacesViewController class]]) { PlacesViewController *placesViewController = (PlacesViewController *)segue.destinationViewController; placesViewController.likelyPlaces = likelyPlaces; } } } // Delegates to handle events for the location manager. #pragma mark - CLLocationManagerDelegate // Handle incoming location events. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { CLLocation *location = locations.lastObject; NSLog(@"Location: %@", location); float zoomLevel = locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel; GMSCameraPosition * camera = [GMSCameraPosition cameraWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude zoom:zoomLevel]; if (mapView.isHidden) { mapView.hidden = NO; mapView.camera = camera; } else { [mapView animateToCameraPosition:camera]; } [self listLikelyPlaces]; } // Handle authorization for the location manager. - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { // Check accuracy authorization CLAccuracyAuthorization accuracy = manager.accuracyAuthorization; switch (accuracy) { case CLAccuracyAuthorizationFullAccuracy: NSLog(@"Location accuracy is precise."); break; case CLAccuracyAuthorizationReducedAccuracy: NSLog(@"Location accuracy is not precise."); break; } // Handle authorization status switch (status) { case kCLAuthorizationStatusRestricted: NSLog(@"Location access was restricted."); break; case kCLAuthorizationStatusDenied: NSLog(@"User denied access to location."); // Display the map using the default location. mapView.hidden = NO; case kCLAuthorizationStatusNotDetermined: NSLog(@"Location status not determined."); case kCLAuthorizationStatusAuthorizedAlways: case kCLAuthorizationStatusAuthorizedWhenInUse: NSLog(@"Location status is OK."); } } // Handle location manager errors. - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { [manager stopUpdatingLocation]; NSLog(@"Error: %@", error.localizedDescription); } @end
PlacesViewController
سویفت
import UIKit import GooglePlaces class PlacesViewController: UIViewController { // ... // Pass the selected place to the new view controller. override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "unwindToMain" { if let nextViewController = segue.destination as? MapViewController { nextViewController.selectedPlace = selectedPlace } } } } // Respond when a user selects a place. extension PlacesViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectedPlace = likelyPlaces[indexPath.row] performSegue(withIdentifier: "unwindToMain", sender: self) } // Adjust cell height to only show the first five items in the table // (scrolling is disabled in IB). func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return self.tableView.frame.size.height/5 } // Make table rows display at proper height if there are less than 5 items. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { if (section == tableView.numberOfSections - 1) { return 1 } return 0 } } // Populate the table with the list of most likely places. extension PlacesViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return likelyPlaces.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) let collectionItem = likelyPlaces[indexPath.row] cell.textLabel?.text = collectionItem.name return cell } }
هدف-سی
#import "PlacesViewController.h" @interface PlacesViewController () <UITableViewDataSource, UITableViewDelegate> // ... -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } #pragma mark - UITableViewDelegate // Respond when a user selects a place. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedPlace = [self.likelyPlaces objectAtIndex:indexPath.row]; [self performSegueWithIdentifier:@"unwindToMain" sender:self]; } // Adjust cell height to only show the first five items in the table // (scrolling is disabled in IB). -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return self.tableView.frame.size.height/5; } // Make table rows display at proper height if there are less than 5 items. -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section == tableView.numberOfSections - 1) { return 1; } return 0; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.likelyPlaces.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { return [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier forIndexPath:indexPath]; } @end
شروع کنید
مدیر بسته سوئیفت
کیت توسعه نرمافزار نقشهها برای iOS را میتوان با استفاده از Swift Package Manager نصب کرد.
- هرگونه SDK نقشه موجود برای وابستگیهای iOS را حذف کنید.
 -  یک پنجره ترمینال باز کنید و به دایرکتوری 
tutorials/current-place-on-mapبروید. -  فضای کاری Xcode خود را ببندید و دستورات زیر را اجرا کنید: 
sudo gem install cocoapods-deintegrate cocoapods-clean pod deintegrate pod cache clean --all rm Podfile rm current-place-on-map.xcworkspace
 - پروژه Xcode خود را باز کنید و فایل podfile را حذف کنید.
 - SDK های مکان ها و نقشه ها را اضافه کنید:
 - به فایل > افزودن وابستگیهای بسته بروید.
 - آدرس https://github.com/googlemaps/ios-places-sdk را به عنوان URL وارد کنید، برای دریافت بسته، Enter را فشار دهید و روی Add Package کلیک کنید.
 - آدرس https://github.com/googlemaps/ios-maps-sdk را به عنوان URL وارد کنید، برای دریافت بسته، Enter را فشار دهید و روی Add Package کلیک کنید.
 - ممکن است لازم باشد حافظه پنهان بسته خود را با استفاده از File > Packages > Reset Package Cache بازنشانی کنید.
 
از کوکوپادز استفاده کنید
- Xcode نسخه ۱۶.۰ یا بالاتر را دانلود و نصب کنید.
 -  اگر CocoaPods را از قبل ندارید، با اجرای دستور زیر از ترمینال، آن را روی macOS نصب کنید: 
sudo gem install cocoapods
 - به دایرکتوری 
tutorials/current-place-on-mapبروید. -  دستور 
pod installرا اجرا کنید. این دستور SDK های Maps و Places که درPodfileمشخص شده اند را به همراه هرگونه وابستگی نصب می کند. -  برای مقایسه نسخه نصب شده pod با هرگونه بهروزرسانی جدید، 
pod outdatedاجرا کنید. اگر نسخه جدیدی شناسایی شد،pod updateاجرا کنید تاPodfileرا بهروزرسانی کرده و آخرین SDK را نصب کنید. برای جزئیات بیشتر، به راهنمای CocoaPods مراجعه کنید. -  برای باز کردن پروژه در Xcode، فایل current-place-on-map.xcworkspace را باز کنید (روی آن دوبار کلیک کنید). برای باز کردن پروژه باید از فایل 
.xcworkspaceاستفاده کنید. 
یک کلید API دریافت کنید و API های لازم را فعال کنید
برای تکمیل این آموزش، به یک کلید API گوگل نیاز دارید که مجاز به استفاده از Maps SDK برای iOS و Places API باشد.
- برای تنظیم حساب پرداخت و فعالسازی پروژه با هر دوی این محصولات، دستورالعملهای « شروع به کار با پلتفرم نقشههای گوگل» را دنبال کنید.
 - برای ایجاد کلید API برای پروژه توسعهای که قبلاً راهاندازی کردهاید ، دستورالعملهای مربوط به دریافت کلید API را دنبال کنید.
 
کلید API را به برنامه خود اضافه کنید
 کلید API خود را به صورت زیر به AppDelegate.swift خود اضافه کنید:
-  توجه داشته باشید که عبارت import زیر به فایل اضافه شده است: 
import GooglePlaces import GoogleMaps
 - خط زیر را در 
application(_:didFinishLaunchingWithOptions:)ویرایش کنید و YOUR_API_KEY را با کلید API خود جایگزین کنید:GMSPlacesClient.provideAPIKey("YOUR_API_KEY") GMSServices.provideAPIKey("YOUR_API_KEY") 
برنامه خود را بسازید و اجرا کنید
- یک دستگاه iOS را به رایانه خود وصل کنید، یا یک شبیهساز را از منوی طرح Xcode انتخاب کنید.
 - اگر از دستگاه استفاده میکنید، مطمئن شوید که سرویسهای موقعیت مکانی فعال هستند. اگر از شبیهساز استفاده میکنید، از منوی ویژگیها ، یک مکان را انتخاب کنید.
 - در Xcode، روی گزینه منوی Product/Run (یا آیکون دکمه پخش) کلیک کنید.
 - Xcode برنامه را میسازد و سپس آن را روی دستگاه یا شبیهساز اجرا میکند.
 - شما باید نقشهای را ببینید که تعدادی نشانگر در اطراف مکان فعلی شما قرار دارد.
 
عیبیابی:
- اگر نقشهای نمیبینید، بررسی کنید که آیا کلید API را دریافت کرده و آن را همانطور که در بالا توضیح داده شد به برنامه اضافه کردهاید یا خیر. کنسول اشکالزدایی Xcode را برای پیامهای خطا در مورد کلید API بررسی کنید.
 -  اگر کلید API را توسط شناسه بسته iOS محدود کردهاید، کلید را ویرایش کنید تا شناسه بسته برای برنامه اضافه شود: 
com.google.examples.current-place-on-map. -  اگر درخواست مجوز برای سرویسهای موقعیت مکانی رد شود، نقشه به درستی نمایش داده نمیشود.
- اگر از دستگاه استفاده میکنید، به تنظیمات/عمومی/حریم خصوصی/خدمات موقعیت مکانی بروید و خدمات موقعیت مکانی را دوباره فعال کنید.
 - اگر از شبیهساز استفاده میکنید، به بخش شبیهساز/تنظیم مجدد محتوا و تنظیمات بروید...
 
 - مطمئن شوید که اتصال Wi-Fi یا GPS شما خوب است.
 - اگر برنامه اجرا میشود اما هیچ نقشهای نمایش داده نمیشود، مطمئن شوید که Info.plist پروژه خود را با مجوزهای مکان مناسب بهروزرسانی کردهاید. برای اطلاعات بیشتر در مورد مدیریت مجوزها، به راهنمای درخواست مجوز مکان در برنامه خود در زیر مراجعه کنید.
 - از ابزارهای اشکالزدایی Xcode برای مشاهدهی گزارشها و اشکالزدایی برنامه استفاده کنید.
 
کد را بفهمید
این بخش از آموزش، مهمترین بخشهای برنامهی «مکان فعلی روی نقشه» را توضیح میدهد تا به شما در درک نحوهی ساخت یک برنامهی مشابه کمک کند.
 برنامهی current-place-on-map دارای دو کنترلر نما است: یکی برای نمایش نقشهای که مکان انتخاب شده توسط کاربر را نشان میدهد و دیگری برای ارائه لیستی از مکانهای احتمالی برای انتخاب به کاربر. توجه داشته باشید که هر کنترلر نما متغیرهای یکسانی برای ردیابی لیست مکانهای احتمالی ( likelyPlaces ) و برای نشان دادن انتخاب کاربر ( selectedPlace ) دارد. پیمایش بین نماها با استفاده از segueها انجام میشود.
درخواست مجوز مکان
 برنامه شما باید از کاربر برای استفاده از سرویسهای موقعیت مکانی رضایت بخواهد. برای انجام این کار، کلید NSLocationAlwaysUsageDescription را در فایل Info.plist برنامه قرار دهید و مقدار هر کلید را به رشتهای تنظیم کنید که نحوه استفاده برنامه از دادههای موقعیت مکانی را شرح دهد.
مدیر مکان را تنظیم کنید
از CLLocationManager برای یافتن مکان فعلی دستگاه و درخواست بهروزرسانیهای منظم هنگام انتقال دستگاه به مکان جدید استفاده کنید. این آموزش کدی را که برای دریافت مکان دستگاه نیاز دارید، ارائه میدهد. برای جزئیات بیشتر، به راهنمای دریافت مکان کاربر در مستندات توسعهدهندگان اپل مراجعه کنید.
- مدیر مکان، مکان فعلی، نمای نقشه، کلاینت مکانها و سطح بزرگنمایی پیشفرض را در سطح کلاس تعریف کنید.
 -  مقداردهی اولیهی location manager و 
GMSPlacesClientدرviewDidLoad() - متغیرهایی را برای نگهداری لیست مکانهای احتمالی و مکان انتخاب شده توسط کاربر تعریف کنید.
 - با استفاده از یک بند الحاقی، نمایندگانی را برای مدیریت رویدادها برای مدیر مکان اضافه کنید.
 
سویفت
var locationManager: CLLocationManager! var currentLocation: CLLocation? var mapView: GMSMapView! var placesClient: GMSPlacesClient! var preciseLocationZoomLevel: Float = 15.0 var approximateLocationZoomLevel: Float = 10.0
هدف-سی
CLLocationManager *locationManager; CLLocation * _Nullable currentLocation; GMSMapView *mapView; GMSPlacesClient *placesClient; float preciseLocationZoomLevel; float approximateLocationZoomLevel;
سویفت
// Initialize the location manager. locationManager = CLLocationManager() locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestWhenInUseAuthorization() locationManager.distanceFilter = 50 locationManager.startUpdatingLocation() locationManager.delegate = self placesClient = GMSPlacesClient.shared()
هدف-سی
// Initialize the location manager. locationManager = [[CLLocationManager alloc] init]; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager requestWhenInUseAuthorization]; locationManager.distanceFilter = 50; [locationManager startUpdatingLocation]; locationManager.delegate = self; placesClient = [GMSPlacesClient sharedClient];
سویفت
// An array to hold the list of likely places. var likelyPlaces: [GMSPlace] = [] // The currently selected place. var selectedPlace: GMSPlace?
هدف-سی
// An array to hold the list of likely places. NSMutableArray<GMSPlace *> *likelyPlaces; // The currently selected place. GMSPlace * _Nullable selectedPlace;
سویفت
// Delegates to handle events for the location manager. extension MapViewController: CLLocationManagerDelegate { // Handle incoming location events. func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location: CLLocation = locations.last! print("Location: \(location)") let zoomLevel = locationManager.accuracyAuthorization == .fullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: zoomLevel) if mapView.isHidden { mapView.isHidden = false mapView.camera = camera } else { mapView.animate(to: camera) } listLikelyPlaces() } // Handle authorization for the location manager. func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { // Check accuracy authorization let accuracy = manager.accuracyAuthorization switch accuracy { case .fullAccuracy: print("Location accuracy is precise.") case .reducedAccuracy: print("Location accuracy is not precise.") @unknown default: fatalError() } // Handle authorization status switch status { case .restricted: print("Location access was restricted.") case .denied: print("User denied access to location.") // Display the map using the default location. mapView.isHidden = false case .notDetermined: print("Location status not determined.") case .authorizedAlways: fallthrough case .authorizedWhenInUse: print("Location status is OK.") @unknown default: fatalError() } } // Handle location manager errors. func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { locationManager.stopUpdatingLocation() print("Error: \(error)") } }
هدف-سی
// Delegates to handle events for the location manager. #pragma mark - CLLocationManagerDelegate // Handle incoming location events. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { CLLocation *location = locations.lastObject; NSLog(@"Location: %@", location); float zoomLevel = locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel; GMSCameraPosition * camera = [GMSCameraPosition cameraWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude zoom:zoomLevel]; if (mapView.isHidden) { mapView.hidden = NO; mapView.camera = camera; } else { [mapView animateToCameraPosition:camera]; } [self listLikelyPlaces]; } // Handle authorization for the location manager. - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { // Check accuracy authorization CLAccuracyAuthorization accuracy = manager.accuracyAuthorization; switch (accuracy) { case CLAccuracyAuthorizationFullAccuracy: NSLog(@"Location accuracy is precise."); break; case CLAccuracyAuthorizationReducedAccuracy: NSLog(@"Location accuracy is not precise."); break; } // Handle authorization status switch (status) { case kCLAuthorizationStatusRestricted: NSLog(@"Location access was restricted."); break; case kCLAuthorizationStatusDenied: NSLog(@"User denied access to location."); // Display the map using the default location. mapView.hidden = NO; case kCLAuthorizationStatusNotDetermined: NSLog(@"Location status not determined."); case kCLAuthorizationStatusAuthorizedAlways: case kCLAuthorizationStatusAuthorizedWhenInUse: NSLog(@"Location status is OK."); } } // Handle location manager errors. - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { [manager stopUpdatingLocation]; NSLog(@"Error: %@", error.localizedDescription); }
اضافه کردن نقشه
 یک نقشه ایجاد کنید و آن را به نمای viewDidLoad() در کنترلر نمای اصلی اضافه کنید. نقشه تا زمانی که بهروزرسانی موقعیت مکانی دریافت نشود، پنهان میماند (بهروزرسانیهای موقعیت مکانی در افزونه CLLocationManagerDelegate مدیریت میشوند). 
سویفت
// A default location to use when location permission is not granted. let defaultLocation = CLLocation(latitude: -33.869405, longitude: 151.199) // Create a map. let zoomLevel = locationManager.accuracyAuthorization == .fullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude, longitude: defaultLocation.coordinate.longitude, zoom: zoomLevel) mapView = GMSMapView.map(withFrame: view.bounds, camera: camera) mapView.settings.myLocationButton = true mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] mapView.isMyLocationEnabled = true // Add the map to the view, hide it until we've got a location update. view.addSubview(mapView) mapView.isHidden = true
هدف-سی
// A default location to use when location permission is not granted. CLLocationCoordinate2D defaultLocation = CLLocationCoordinate2DMake(-33.869405, 151.199); // Create a map. float zoomLevel = locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy ? preciseLocationZoomLevel : approximateLocationZoomLevel; GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:defaultLocation.latitude longitude:defaultLocation.longitude zoom:zoomLevel]; mapView = [GMSMapView mapWithFrame:self.view.bounds camera:camera]; mapView.settings.myLocationButton = YES; mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; mapView.myLocationEnabled = YES; // Add the map to the view, hide it until we've got a location update. [self.view addSubview:mapView]; mapView.hidden = YES;
ترغیب کاربر به انتخاب مکان فعلی خود
 از Places SDK برای iOS استفاده کنید تا بر اساس موقعیت فعلی کاربر، پنج مکان برتر با احتمال حضور را دریافت کنید و لیست را در یک UITableView ارائه دهید. وقتی کاربر مکانی را انتخاب میکند، یک نشانگر به نقشه اضافه کنید.
-  فهرستی از مکانهای احتمالی برای پر کردن یک 
UITableViewدریافت کنید، که از آن طریق کاربر میتواند مکانی را که در آن قرار دارد انتخاب کند. -  یک نمای جدید باز کنید تا مکانهای احتمالی را به کاربر ارائه دهید. وقتی کاربر روی "دریافت مکان" ضربه میزند، ما به یک نمای جدید segue میکنیم و لیستی از مکانهای ممکن برای انتخاب را به کاربر نشان میدهیم. تابع 
preparePlacesViewControllerبا لیست مکانهای احتمالی فعلی بهروزرسانی میکند و هنگام اجرای segue به طور خودکار فراخوانی میشود. -  در 
PlacesViewController، جدول را با استفاده از فهرست مکانهای محتمل، و با استفاده از افزونهی نمایندهیUITableViewDataSource، پر کنید. -  انتخاب کاربر را با استفاده از افزونهی نمایندهی 
UITableViewDelegateمدیریت کنید. 
سویفت
// Populate the array with the list of likely places. func listLikelyPlaces() { // Clean up from previous sessions. likelyPlaces.removeAll() let placeFields: GMSPlaceField = [.name, .coordinate] placesClient.findPlaceLikelihoodsFromCurrentLocation(withPlaceFields: placeFields) { (placeLikelihoods, error) in guard error == nil else { // TODO: Handle the error. print("Current Place error: \(error!.localizedDescription)") return } guard let placeLikelihoods = placeLikelihoods else { print("No places found.") return } // Get likely places and add to the list. for likelihood in placeLikelihoods { let place = likelihood.place self.likelyPlaces.append(place) } } }
هدف-سی
// Populate the array with the list of likely places. - (void) listLikelyPlaces { // Clean up from previous sessions. likelyPlaces = [NSMutableArray array]; GMSPlaceField placeFields = GMSPlaceFieldName | GMSPlaceFieldCoordinate; [placesClient findPlaceLikelihoodsFromCurrentLocationWithPlaceFields:placeFields callback:^(NSArray<GMSPlaceLikelihood *> * _Nullable likelihoods, NSError * _Nullable error) { if (error != nil) { // TODO: Handle the error. NSLog(@"Current Place error: %@", error.localizedDescription); return; } if (likelihoods == nil) { NSLog(@"No places found."); return; } for (GMSPlaceLikelihood *likelihood in likelihoods) { GMSPlace *place = likelihood.place; [likelyPlaces addObject:place]; } }]; }
سویفت
// Prepare the segue. override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "segueToSelect" { if let nextViewController = segue.destination as? PlacesViewController { nextViewController.likelyPlaces = likelyPlaces } } }
هدف-سی
// Prepare the segue. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"segueToSelect"]) { if ([segue.destinationViewController isKindOfClass:[PlacesViewController class]]) { PlacesViewController *placesViewController = (PlacesViewController *)segue.destinationViewController; placesViewController.likelyPlaces = likelyPlaces; } } }
سویفت
// Populate the table with the list of most likely places. extension PlacesViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return likelyPlaces.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) let collectionItem = likelyPlaces[indexPath.row] cell.textLabel?.text = collectionItem.name return cell } }
هدف-سی
#pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.likelyPlaces.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { return [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier forIndexPath:indexPath]; } @end
سویفت
class PlacesViewController: UIViewController { // ... // Pass the selected place to the new view controller. override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "unwindToMain" { if let nextViewController = segue.destination as? MapViewController { nextViewController.selectedPlace = selectedPlace } } } } // Respond when a user selects a place. extension PlacesViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectedPlace = likelyPlaces[indexPath.row] performSegue(withIdentifier: "unwindToMain", sender: self) } // Adjust cell height to only show the first five items in the table // (scrolling is disabled in IB). func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return self.tableView.frame.size.height/5 } // Make table rows display at proper height if there are less than 5 items. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { if (section == tableView.numberOfSections - 1) { return 1 } return 0 } }
هدف-سی
@interface PlacesViewController () <UITableViewDataSource, UITableViewDelegate> // ... -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } #pragma mark - UITableViewDelegate // Respond when a user selects a place. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedPlace = [self.likelyPlaces objectAtIndex:indexPath.row]; [self performSegueWithIdentifier:@"unwindToMain" sender:self]; } // Adjust cell height to only show the first five items in the table // (scrolling is disabled in IB). -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return self.tableView.frame.size.height/5; } // Make table rows display at proper height if there are less than 5 items. -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { if (section == tableView.numberOfSections - 1) { return 1; } return 0; }
اضافه کردن نشانگر به نقشه
 وقتی کاربر انتخابی انجام میدهد، از یک unwind segue برای بازگشت به نمای قبلی استفاده کنید و نشانگر را به نقشه اضافه کنید. unwindToMain IBAction به طور خودکار پس از بازگشت به کنترلر نمای اصلی فراخوانی میشود. 
سویفت
// Update the map once the user has made their selection. @IBAction func unwindToMain(segue: UIStoryboardSegue) { // Clear the map. mapView.clear() // Add a marker to the map. if let place = selectedPlace { let marker = GMSMarker(position: place.coordinate) marker.title = selectedPlace?.name marker.snippet = selectedPlace?.formattedAddress marker.map = mapView } listLikelyPlaces() }
هدف-سی
// Update the map once the user has made their selection. - (void) unwindToMain:(UIStoryboardSegue *)segue { // Clear the map. [mapView clear]; // Add a marker to the map. if (selectedPlace != nil) { GMSMarker *marker = [GMSMarker markerWithPosition:selectedPlace.coordinate]; marker.title = selectedPlace.name; marker.snippet = selectedPlace.formattedAddress; marker.map = mapView; } [self listLikelyPlaces]; }
تبریک! شما یک برنامه iOS ساختهاید که به کاربر اجازه میدهد مکان فعلی خود را انتخاب کند و نتیجه را روی نقشه گوگل نشان میدهد. در حین انجام این کار، یاد گرفتهاید که چگونه از Places SDK برای iOS ، Maps SDK برای iOS و چارچوب Apple Core Location استفاده کنید.