### Minimal Places SDK Setup Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/INDEX.md Provide your API key during application launch for basic SDK setup. ```swift // In AppDelegate.application(_:didFinishLaunchingWithOptions:) GMSPlacesClient.provideAPIKey("YOUR_API_KEY") ``` -------------------------------- ### Complete Search View Controller Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md This example demonstrates a complete implementation of a search view controller using GMSAutocompleteResultsViewController for place autocomplete. It handles view loading, search controller setup, and delegate methods for handling autocomplete results and errors. ```swift import UIKit import GooglePlaces class SearchViewController: UIViewController, GMSAutocompleteResultsViewControllerDelegate { var placesClient: GMSPlacesClient! override func viewDidLoad() { super.viewDidLoad() placesClient = GMSPlacesClient.sharedClient() setupSearchController() } func setupSearchController() { let resultsController = GMSAutocompleteResultsViewController() resultsController.delegate = self resultsController.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldRating let searchController = UISearchController(searchResultsController: resultsController) searchController.searchResultsUpdater = resultsController searchController.searchBar.placeholder = "Search places" navigationItem.searchController = searchController navigationItem.hidesSearchBarWhenScrolling = false } // MARK: - GMSAutocompleteResultsViewControllerDelegate func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didAutocompleteWith place: GMSPlace) { // Dismiss search navigationItem.searchController?.isActive = false // Handle selected place displayPlace(place) } func resultsController(_ resultsController: GMSAutocompleteResultsViewController, didFailAutocompleteWithError error: Error) { print("Error: \(error.localizedDescription)") } private func displayPlace(_ place: GMSPlace) { print("Selected: \(place.name ?? "")") } } ``` -------------------------------- ### Complete AppDelegate Setup Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md This snippet shows the complete setup within an AppDelegate, including optional App Check configuration, API key provision, and usage attribution. ```swift import UIKit import GooglePlaces @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Step 1: Configure App Check (optional but recommended) #if !DEBUG configureAppCheck() #endif // Step 2: Provide API Key (REQUIRED) let apiKey = loadAPIKey() GMSPlacesClient.provideAPIKey(apiKey) // Step 3: Set App Check Token Provider (optional) #if !DEBUG let tokenProvider = MyAppCheckTokenProvider() GMSPlacesClient.setAppCheckTokenProvider(tokenProvider) #endif // Step 4: Add usage attribution (optional) GMSPlacesClient.addInternalUsageAttributionID("my-sample-app") return true } private func loadAPIKey() -> String { // Load from configuration file or environment if let configPath = Bundle.main.path(forResource: "GooglePlacesConfig", ofType: "plist"), let config = NSDictionary(contentsOfFile: configPath), let apiKey = config["PlacesAPIKey"] as? String { return apiKey } fatalError("Missing Places API key") } } ``` -------------------------------- ### Provide API Key in Application Delegate (Full Example) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md A complete example of providing the API key within the application delegate's didFinishLaunchingWithOptions method. Ensure this is called before any GMSPlacesClient usage. ```swift @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // IMPORTANT: Must be called before using GMSPlacesClient GMSPlacesClient.provideAPIKey("YOUR_API_KEY_HERE") return true } } ``` -------------------------------- ### CocoaPods Installation Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Instructions for installing the Google Places SDK using CocoaPods. Specify the desired version in your Podfile. ```ruby # In Podfile pod 'GooglePlaces', '~> 10.14.0' # or for Swift SDK pod 'GooglePlacesSwift', '~> 0.3.0' ``` -------------------------------- ### Swift Package Manager Installation Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Instructions for installing the Google Places SDK using Swift Package Manager in Xcode. This is the recommended method for integrating the SDK. ```swift // In your code import GooglePlaces // For Objective-C SDK import GooglePlacesSwift // For Swift SDK ``` -------------------------------- ### Full Places SDK Setup with Options Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/INDEX.md Configure the Places SDK with optional App Check, required API key, and internal usage attribution. ```swift // 1. App Check (optional) GMSPlacesClient.setAppCheckTokenProvider(tokenProvider) // 2. API Key (required) GMSPlacesClient.provideAPIKey(apiKey) // 3. Usage attribution (optional) GMSPlacesClient.addInternalUsageAttributionID("my-app") // 4. Get shared client let client = GMSPlacesClient.sharedClient() ``` -------------------------------- ### Usage Examples Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSAutocompleteRequest.md Demonstrates how to use GMSAutocompleteRequest for simple autocomplete, with session tokens, and with type filters. ```APIDOC ## Usage Examples ### Simple Autocomplete ```swift let request = GMSAutocompleteRequest() request.query = "restaurants" placesClient.fetchAutocompleteSuggestionsFromRequest(request) { suggestions, error in if let error = error { print("Autocomplete error: \(error.localizedDescription)") return } suggestions?.forEach { suggestion in print("Suggestion: \(suggestion.mainText)") } } ``` ### Autocomplete with Session Token ```swift // Create token at start of user session let sessionToken = GMSAutocompleteSessionToken() let request = GMSAutocompleteRequest() request.query = "pizzerias in" request.sessionToken = sessionToken placesClient.fetchAutocompleteSuggestionsFromRequest(request) { suggestions, error in if let selectedSuggestion = suggestions?.first { // When user selects, fetch full details with same token let fetchRequest = GMSFetchPlaceRequest(placeID: selectedSuggestion.placeID) fetchRequest.sessionToken = sessionToken // Same token // Both requests billed as one session } } ``` ### Autocomplete with Type Filter ```swift let filter = GMSAutocompleteFilter() filter.types = NSSet(array: ["restaurant", "cafe"]) let request = GMSAutocompleteRequest() request.query = "italian" request.filter = filter placesClient.fetchAutocompleteSuggestionsFromRequest(request) { suggestions, error in if let suggestions = suggestions { // Only restaurants and cafes suggestions.forEach { s in print(s.mainText) } } } ``` ``` -------------------------------- ### Provide API Key in Application Delegate Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Provide your API key when the application finishes launching. This is a required setup step before using GMSPlacesClient methods. ```swift import GooglePlaces // Call in application(_:didFinishLaunchingWithOptions:) GMSPlacesClient.provideAPIKey("YOUR_API_KEY") ``` -------------------------------- ### Full Usage Example for GMSAutocompleteViewController Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md Demonstrates how to integrate GMSAutocompleteViewController into a navigation flow, including initialization, configuration of session token and place fields, and handling delegate callbacks for selection, errors, and cancellation. ```swift import UIKit import GooglePlaces class PlaceSearchViewController: UIViewController, GMSAutocompleteViewControllerDelegate { func openAutocomplete() { let autocompleteController = GMSAutocompleteViewController() autocompleteController.delegate = self // Configure let token = GMSAutocompleteSessionToken() autocompleteController.sessionToken = token autocompleteController.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldRating navigationController?.pushViewController(autocompleteController, animated: true) } // MARK: - GMSAutocompleteViewControllerDelegate func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) { navigationController?.popViewController(animated: true) displayPlaceDetails(place) } func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) { print("Error: \(error.localizedDescription)") } func wasCancelled(_ viewController: GMSAutocompleteViewController) { navigationController?.popViewController(animated: true) } private func displayPlaceDetails(_ place: GMSPlace) { // Show place information let name = place.name ?? "Unknown" let address = place.formattedAddress ?? "No address" let rating = place.rating > 0 ? String(format: "%.1f", place.rating) : "No rating" print("\(name)") print("\(address)") print("Rating: \(rating)") } } ``` -------------------------------- ### GMSAutocompleteSessionToken Usage Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/types.md Demonstrates how to create and reuse a GMSAutocompleteSessionToken for a user session, including its use with subsequent place fetch requests. ```swift let sessionToken = GMSAutocompleteSessionToken() // Reuse this token for all autocomplete requests in this user session // When user selects a place, reuse same token for fetchPlace request ``` -------------------------------- ### GMSFetchPhotoRequest Usage Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Illustrates how to fetch a photo for a place using GMSFetchPhotoRequest. Sets maximum size and preferred scale for the image. ```swift let request = GMSFetchPhotoRequest(photo: photoMetadata) request.maxSize = CGSize(width: 400, height: 300) request.preferredScale = UIScreen.main.scale placesClient.fetchPhotoWithRequest(request) { image, error in if let error = error { print("Photo fetch error: \(error.localizedDescription)") return } if let image = image { imageView.image = image } } ``` -------------------------------- ### Session Token Cost Savings Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSAutocompleteRequest.md Illustrates the cost savings achieved by using session tokens for autocomplete and place fetch requests. Shows the difference in billable requests. ```swift // Without token - 2 billable requests autocompleteRequest.sessionToken = nil // $0.01 fetchPlaceRequest.sessionToken = nil // $0.01 // Total: $0.02 // With token - 1 billable session autocompleteRequest.sessionToken = token // $0.01 fetchPlaceRequest.sessionToken = token // Free (grouped) // Total: $0.01 (50% savings!) ``` -------------------------------- ### Error Handling Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Comprehensive guide to error codes (-1 to -12), their trigger conditions, recovery strategies, example error handling, and best practices for debugging. ```APIDOC ## Error Handling ### Description Comprehensive guide to error codes (-1 to -12), their trigger conditions, recovery strategies, example error handling, and best practices for debugging. ### Error Codes Covered - All 12 error codes (-1 to -12) - Trigger conditions - Recovery strategies - Example handling code ``` -------------------------------- ### Implement Exponential Backoff for Rate Limit Errors Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/errors.md This example shows how to implement exponential backoff to retry requests when the rate limit has been exceeded. Adjust `maxAttempts` as needed. ```swift func retryWithBackoff(attempt: Int = 0, maxAttempts: Int = 3) { placesClient.fetchPlace(with: request) { place, error in if let error = error, error.code == kGMSPlacesRateLimitExceeded { if attempt < maxAttempts { let delay = pow(2.0, Double(attempt)) // Exponential backoff DispatchQueue.main.asyncAfter(deadline: .now() + delay) { self.retryWithBackoff(attempt: attempt + 1, maxAttempts: maxAttempts) } } } } } ``` -------------------------------- ### Initialize GMSAutocompleteTableDataSource Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md Initializes the GMSAutocompleteTableDataSource and sets its delegate and table view data source. This is the starting point for using the table data source. ```swift let tableDataSource = GMSAutocompleteTableDataSource() tableDataSource.delegate = self tableView.dataSource = tableDataSource ``` -------------------------------- ### GMSPlacesClient API Reference Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Reference for the main client class, GMSPlacesClient, including its core methods, class methods, and instance methods for all operations. It details parameter tables and provides complete code examples. ```APIDOC ## GMSPlacesClient API Reference ### Description Reference for the main client class, GMSPlacesClient, including its core methods, class methods, and instance methods for all operations. It details parameter tables and provides complete code examples. ### Methods Documented - 7 core client methods - 5 configuration methods ``` -------------------------------- ### GMSPlaceSearchByTextRequest Usage Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Demonstrates how to create and use a GMSPlaceSearchByTextRequest to find places based on a text query. Specify desired place fields, language, and region for the search. ```swift let request = GMSPlaceSearchByTextRequest(textQuery: "pizza restaurants Manhattan") request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldRating | GMSPlaceFieldPhotos request.languageCode = "en" request.regionCode = "us" placesClient.searchByTextWithRequest(request) { response, error in if let error = error { print("Search error: \(error.localizedDescription)") return } if let response = response { response.places.forEach { place in print("Found: \(place.name ?? "")") print(" Rating: \(place.rating)") print(" Address: \(place.formattedAddress ?? "")") } } } ``` -------------------------------- ### Use Radius Effectively Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Choose an appropriate radius for your search based on the use case. This example demonstrates setting a small radius for nearby searches and a larger one for regional searches, advising to use text search for country-wide searches. ```APIDOC ## Use Radius Effectively Choose radius based on use case: ```swift // Nearby search - small radius request.radiusMeters = 500 // 0.5 km // Regional search - larger radius request.radiusMeters = 10000 // 10 km // Country-wide search - use text search instead ``` ``` -------------------------------- ### GMSPlaceSearchNearbyRequest Usage Example Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Demonstrates how to perform a nearby place search using GMSPlaceSearchNearbyRequest. Specifies location, radius, place types, keywords, desired fields, and ranking preference. ```swift let location = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194) let request = GMSPlaceSearchNearbyRequest(location: location) request.radiusMeters = 500 request.placeTypes = @["restaurant", "cafe"] request.keyword = "italian" request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldRating | GMSPlaceFieldOpeningHours request.rankPreference = kGMSPlaceSearchNearbyRankPreferenceDistance placesClient.searchNearbyWithRequest(request) { response, error in if let error = error { print("Search error: \(error.localizedDescription)") return } if let response = response { print("Found \(response.places.count) nearby places") response.places.forEach { place in print("- \(place.name ?? "")") } } } ``` -------------------------------- ### Check Place Opening Status with GMSPlaceIsOpenRequest Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Determine if a place is currently open or closed. This example demonstrates how to create an `GMSPlaceIsOpenRequest`, specify whether to check the current time, and process the opening status response. Handle potential errors during the status check. ```swift let request = GMSPlaceIsOpenRequest(place: place) request.checkOpenNow = true // Check current time placesClient.isOpen(with: request) { response, error in if let error = error { print("Status check error: \(error.localizedDescription)") return } if let response = response { switch response.openingStatus { case .open: print("Place is open") case .closed: print("Place is closed") case .unknown: print("Opening status unknown") @unknown default: break } } } ``` -------------------------------- ### Data Structures Reference Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Documentation for complex data structures such as GMSPlacePhotoMetadata, GMSAddressComponent, GMSOpeningHours, GMSPlaceReview, and GMSAutocompleteSuggestion, including response objects and complex usage examples. ```APIDOC ## Data Structures Reference ### Description Documentation for complex data structures such as GMSPlacePhotoMetadata, GMSAddressComponent, GMSOpeningHours, GMSPlaceReview, and GMSAutocompleteSuggestion, including response objects and complex usage examples. ### Data Structures Documented - GMSPlacePhotoMetadata - GMSAddressComponent - GMSOpeningHours - GMSPlaceReview - GMSAutocompleteSuggestion - Response objects - Complex usage examples ``` -------------------------------- ### Cache Search Results Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Implement a cache to store search results and avoid redundant API calls. This example shows caching results for text searches based on the query string. ```swift var searchCache: [String: [GMSPlace]] = [:] func search(query: String) { if let cached = searchCache[query] { displayResults(cached) return } let request = GMSPlaceSearchByTextRequest(textQuery: query) placesClient.searchByTextWithRequest(request) { response, error in if let places = response?.places { searchCache[query] = places displayResults(places) } } } ``` -------------------------------- ### Cache Search Results Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Implement caching for search results to avoid redundant searches and improve user experience. This example shows a basic implementation using a dictionary to store and retrieve previously fetched places. ```APIDOC ## Cache Search Results Store results to avoid repeated searches: ```swift var searchCache: [String: [GMSPlace]] = [: ] func search(query: String) { if let cached = searchCache[query] { displayResults(cached) return } let request = GMSPlaceSearchByTextRequest(textQuery: query) placesClient.searchByTextWithRequest(request) { response, error in if let places = response?.places { searchCache[query] = places displayResults(places) } } } ``` ``` -------------------------------- ### Get the Shared Client Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/README.md Retrieves the shared instance of GMSPlacesClient, which is the main client for all API operations. ```APIDOC ## Get the Shared Client ### Description Retrieves the shared instance of GMSPlacesClient, which is the main client for all API operations. ### Method Swift ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```swift let placesClient = GMSPlacesClient.sharedClient() ``` ### Response N/A #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Basic Place Fetch with GMSFetchPlaceRequest Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Demonstrates how to create a GMSFetchPlaceRequest, specify fields, and fetch place details using GMSPlacesClient. Handles potential errors and prints place information. ```swift let request = GMSFetchPlaceRequest(placeID: "ChIJN1blFLsB1AgTqefmoW_QC8Q") request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress placesClient.fetchPlaceWithRequest(request) { place, error in if let error = error { print("Error: \(error.localizedDescription)") return } if let place = place { print("Name: \(place.name ?? "")") print("Address: \(place.formattedAddress ?? "")") } } ``` -------------------------------- ### Get Shared GMSPlacesClient Instance Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Access the shared singleton instance of GMSPlacesClient. This method creates the instance if it doesn't exist. ```swift let placesClient = GMSPlacesClient.sharedClient() ``` -------------------------------- ### Initialize the SDK Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/README.md Initialize the Google Places SDK for iOS by providing your API key. This should be done in your AppDelegate's `application(_:didFinishLaunchingWithOptions:)` method. ```swift import GooglePlaces // In AppDelegate.application(_:didFinishLaunchingWithOptions:) GMSPlacesClient.provideAPIKey("YOUR_API_KEY") ``` -------------------------------- ### Initialize the SDK Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/README.md Initializes the Google Places SDK for iOS with your API key. This should be done in your application's delegate. ```APIDOC ## Initialize the SDK ### Description Initializes the Google Places SDK for iOS with your API key. This should be done in your application's delegate. ### Method Swift ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```swift import GooglePlaces // In AppDelegate.application(_:didFinishLaunchingWithOptions:) GMSPlacesClient.provideAPIKey("YOUR_API_KEY") ``` ### Response N/A #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Restrict by Place Type Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlaceSearchRequests.md Filter search results to a specific place type to improve relevance. This example shows how to limit results to only restaurants. ```APIDOC ## Restrict by Place Type Filter results by type to improve relevance: ```swift let request = GMSPlaceSearchNearbyRequest(location: location) request.placeTypes = @["restaurant"] // Only restaurants ``` ``` -------------------------------- ### Use Session Tokens (Best Practice) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Shows how to use session tokens to group related requests, such as autocomplete and place fetch, to be billed as a single session. ```swift let sessionToken = GMSAutocompleteSessionToken() // Use sessionToken for autocomplete, suggestions, and place fetch // All grouped as one billable session ``` -------------------------------- ### GMSAutocompleteRequest Parameters Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Details on GMSAutocompleteRequest parameters, including filter configuration, session token usage, request/response patterns, and cost optimization examples. ```APIDOC ## GMSAutocompleteRequest Parameters ### Description Details on GMSAutocompleteRequest parameters, including filter configuration, session token usage, request/response patterns, and cost optimization examples. ### Features - Autocomplete request parameters - Filter configuration - Session token usage - Request/response patterns - Cost optimization examples - Filter combinations ``` -------------------------------- ### Initialize GMSAutocompleteViewController Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md Instantiate the GMSAutocompleteViewController and set its delegate. This is the first step to present the autocomplete UI. ```swift let autocompleteViewController = GMSAutocompleteViewController() autocompleteViewController.delegate = self ``` -------------------------------- ### Fetch All Place Fields Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Demonstrates how to retrieve all available fields for a place by setting `placeFields` to `GMSPlaceFieldAll`. ```swift let request = GMSFetchPlaceRequest(placeID: placeID) request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldCoordinate | GMSPlaceFieldPhoneNumber | GMSPlaceFieldWebsite | GMSPlaceFieldRating | GMSPlaceFieldUserRatingsTotal | GMSPlaceFieldPriceLevel | GMSPlaceFieldPhotos | GMSPlaceFieldOpeningHours | GMSPlaceFieldBusinessStatus | GMSPlaceFieldAddressComponents placesClient.fetchPlaceWithRequest(request) { place, error in if let place = place { // All requested fields populated print("Name: \(place.name ?? "")") print("Address: \(place.formattedAddress ?? "")") print("Rating: \(place.rating)") print("Photos: \(place.photos?.count ?? 0)") print("Phone: \(place.phoneNumber ?? "")") print("Website: \(place.website?.absoluteString ?? "")") } } ``` -------------------------------- ### Configure Places SDK with Multiple Environments Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Define different API keys and bundle IDs for development, staging, and production environments using an enum. This allows for easy switching between configurations. ```swift enum PlacesConfiguration { case development case staging case production var apiKey: String { switch self { case .development: return "DEV_KEY" case .staging: return "STAGING_KEY" case .production: return "PROD_KEY" } } var bundleID: String { switch self { case .development: return "com.example.app.dev" case .staging: return "com.example.app.staging" case .production: return "com.example.app" } } } // Usage let config = PlacesConfiguration.production GMSPlacesClient.provideAPIKey(config.apiKey) ``` -------------------------------- ### Verify SDK Configuration Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/README.md Perform a simple autocomplete request to verify that the SDK is configured correctly. Check for errors and log the number of suggestions received. ```swift // Try a simple request let request = GMSAutocompleteRequest() request.query = "test" placesClient.fetchAutocompleteSuggestionsFromRequest(request) { suggestions, error in if let error = error { print("Config error: \(error.code) - \(error.localizedDescription)") } else { print("Configuration OK - got \(suggestions?.count ?? 0) suggestions") } } ``` -------------------------------- ### Handle Missing Fields (Best Practice) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Demonstrates how to safely access place fields by checking for nil values, as not all places may have all fields available. ```swift if let phone = place.phoneNumber { print("Phone: \(phone)") } else { print("Phone number not available") } ``` -------------------------------- ### Autocomplete Suggestions and Place Details Fetch Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/INDEX.md Fetch autocomplete suggestions and then place details using the same session token for potential cost savings. ```swift // 1. Create session token let sessionToken = GMSAutocompleteSessionToken() // 2. Fetch suggestions let request = GMSAutocompleteRequest() request.query = userInput request.sessionToken = sessionToken placesClient.fetchAutocompleteSuggestionsFromRequest(request) { ... } // 3. When user selects, fetch details with same token let fetchRequest = GMSFetchPlaceRequest(placeID: suggestion.placeID) fetchRequest.sessionToken = sessionToken // Same token! placesClient.fetchPlaceWithRequest(fetchRequest) { ... } ``` -------------------------------- ### Restricting Autocomplete by Country Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSAutocompleteRequest.md Use the countries property of GMSAutocompleteFilter to limit results to specific ISO 3166-1 country codes. This example restricts results to North American countries. ```swift let filter = GMSAutocompleteFilter() filter.countries = NSSet(array: ["us", "ca", "mx"]) request.filter = filter ``` -------------------------------- ### Provide API Key Configuration Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/errors.md Ensure you call `GMSPlacesClient.provideAPIKey(:)` with a valid API key before making any SDK calls. This is crucial for authentication and authorization. ```swift // Must be called before using GMSPlacesClient GMSPlacesClient.provideAPIKey("YOUR_VALID_API_KEY") ``` -------------------------------- ### openSourceLicenseInfo Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Returns open source software license information for the Google Places SDK. ```APIDOC ## openSourceLicenseInfo ### Description Returns open source software license information for the Google Places SDK. ### Returns String containing license information that must be displayed in your application. ``` -------------------------------- ### GMSPlace Data Object Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Documentation for the GMSPlace data object, detailing its 30+ properties, their types, optional status, usage examples, field availability patterns, and attribution handling. ```APIDOC ## GMSPlace Data Object ### Description Documentation for the GMSPlace data object, detailing its 30+ properties, their types, optional status, usage examples, field availability patterns, and attribution handling. ### Properties Documented - 200+ properties across all types - Types and optional status specified - Default values documented - Field availability patterns explained ``` -------------------------------- ### Check for Optional Place Fields (Nil Check) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlace.md Demonstrates how to check if optional fields like reviews or website are populated for a place. This is crucial as not all fields are guaranteed to be available. ```swift if let reviews = place.reviews { // Place has reviews } if let website = place.website { // Place has website } ``` -------------------------------- ### Request Only Needed Fields (Best Practice) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Illustrates the best practice of requesting only the specific fields required for a place to minimize data transfer and API costs. ```swift // Good - request only what you need request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress // Avoid - requesting all fields is expensive request.placeFields = GMSPlaceFieldAll ``` -------------------------------- ### Check Location Authorization Status Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/errors.md Check the current authorization status for location services before making requests that depend on device location. This example demonstrates how to proceed with a placesClient.searchNearby call only if permission is granted. ```swift let status = CLLocationManager.authorizationStatus() if status == .authorizedWhenInUse || status == .authorizedAlways { // Location permission granted, safe to use placesClient.searchNearby(with: request) { response, error in // Handle response } } else { // Request permission first let locationManager = CLLocationManager() locationManager.requestWhenInUseAuthorization() } ``` -------------------------------- ### Fetch Place with Session Token Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Demonstrates fetching place details using a session token, which is useful for grouping related requests like autocomplete and place fetch to reduce billing. ```swift // During autocomplete, create session token let sessionToken = GMSAutocompleteSessionToken() let autocompleteRequest = GMSAutocompleteRequest() autocompleteRequest.query = "restaurants in Paris" autocompleteRequest.sessionToken = sessionToken placesClient.fetchAutocompleteSuggestionsFromRequest(autocompleteRequest) { suggestions, error in // User selects a suggestion if let selectedSuggestion = suggestions?.first { // Reuse same token for place fetch let fetchRequest = GMSFetchPlaceRequest(placeID: selectedSuggestion.placeID) fetchRequest.placeFields = GMSPlaceFieldName | GMSPlaceFieldRating | GMSPlaceFieldPhotos | GMSPlaceFieldOpeningHours fetchRequest.sessionToken = sessionToken // Same token placesClient.fetchPlaceWithRequest(fetchRequest) { place, error in // Place details loaded - billed as single session } } } ``` -------------------------------- ### Cache Results (Best Practice) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Illustrates caching fetched place details in a dictionary to avoid repeated API requests and improve performance. ```swift var placeCache: [String: GMSPlace] = [: ] func fetchPlace(id: String) { if let cached = placeCache[id] { // Use cached result return } let request = GMSFetchPlaceRequest(placeID: id) placesClient.fetchPlaceWithRequest(request) { place, error in if let place = place { placeCache[id] = place // Cache for future use } } } ``` -------------------------------- ### UI Components Reference Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/MANIFEST.md Reference for UI components like GMSAutocompleteViewController, GMSAutocompleteResultsViewController, and GMSAutocompleteTableDataSource, covering delegate protocols, customization options, and integration patterns. ```APIDOC ## UI Components Reference ### Description Reference for UI components like GMSAutocompleteViewController, GMSAutocompleteResultsViewController, and GMSAutocompleteTableDataSource, covering delegate protocols, customization options, and integration patterns. ### Classes Documented - GMSAutocompleteViewController (full-screen UI) - GMSAutocompleteResultsViewController (embedded) - GMSAutocompleteTableDataSource (custom table) - Delegate protocols - Customization options - Integration patterns ``` -------------------------------- ### Custom Search View Controller with Table Data Source Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md This example shows a custom view controller integrating GMSAutocompleteTableDataSource with a UITableView and UISearchBar. It handles search text changes and displays selected place details. ```swift import UIKit import GooglePlaces class CustomSearchViewController: UIViewController, UISearchBarDelegate, GMSAutocompleteTableDataSourceDelegate { @IBOutlet weak var tableView: UITableView! @IBOutlet weak var searchBar: UISearchBar! var tableDataSource: GMSAutocompleteTableDataSource! override func viewDidLoad() { super.viewDidLoad() searchBar.delegate = self tableDataSource = GMSAutocompleteTableDataSource() tableDataSource.delegate = self tableDataSource.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldPhotos tableView.dataSource = tableDataSource tableView.delegate = self } // MARK: - UISearchBarDelegate func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { tableDataSource.sourceTextHasChanged(searchText) } // MARK: - GMSAutocompleteTableDataSourceDelegate func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didAutocompleteWith place: GMSPlace) { searchBar.text = place.name displayPlace(place) } func tableDataSource(_ tableDataSource: GMSAutocompleteTableDataSource, didFailAutocompleteWithError error: Error) { print("Autocomplete error: \(error.localizedDescription)") } private func displayPlace(_ place: GMSPlace) { print("Name: \(place.name ?? "")") print("Address: \(place.formattedAddress ?? "")") } } ``` -------------------------------- ### Using a Session Token for Autocomplete Requests Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSAutocompleteRequest.md Associate a GMSAutocompleteSessionToken with the request to group autocomplete queries with place fetch requests for unified billing. This token should be created at the start of a user session and reused for subsequent related requests. ```swift let sessionToken = GMSAutocompleteSessionToken() request.sessionToken = sessionToken // Later, when fetching full place details, use same token fetchRequest.sessionToken = sessionToken ``` -------------------------------- ### Present Modal Autocomplete Picker Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md Launch a modal GMSAutocompleteViewController to allow users to search for and select a place. Configure the desired place fields and session token for the request. ```swift @IBAction func openPlacePicker(_ sender: UIButton) { let controller = GMSAutocompleteViewController() controller.delegate = self let token = GMSAutocompleteSessionToken() controller.sessionToken = token controller.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress | GMSPlaceFieldPhotos | GMSPlaceFieldRating let navigationController = UINavigationController(rootViewController: controller) present(navigationController, animated: true) } ``` -------------------------------- ### isOpenWithRequest Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Determines the opening status of a place at the current time or specified date. This is useful for displaying whether a business is currently open. ```APIDOC ## isOpenWithRequest ### Description Determines the opening status of a place at the current time or specified date. This is useful for displaying whether a business is currently open. ### Method Objective-C method signature ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | isOpenRequest | GMSPlaceIsOpenRequest | Yes | — | Request containing place and optional date | | callback | GMSPlaceOpenStatusResponseCallback | Yes | — | Block invoked with status or error | ### Callback Parameters - `response`: `GMSPlaceIsOpenResponse` - Response with opening status - `error`: `NSError` - Error object if operation failed, otherwise nil ### Request Example ```swift let request = GMSPlaceIsOpenRequest(place: place) request.checkOpenNow = true // Check current time placesClient.isOpen(with: request) { response, error in if let error = error { print("Status check error: \(error.localizedDescription)") return } if let response = response { switch response.openingStatus { case .open: print("Place is open") case .closed: print("Place is closed") case .unknown: print("Opening status unknown") @unknown default: break } } } ``` ``` -------------------------------- ### Check Service Availability (Takeout) Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlace.md Illustrates how to check the takeout availability for a place using the `takeout` property of the `GMSPlace` object. It handles three possible states: true, false, and unknown. ```APIDOC ## Check Service Availability (Takeout) This section demonstrates how to determine if takeout service is available for a given place. ### Usage Use the `takeout` property of the `GMSPlace` object, which returns an enum with possible values `.true`, `.false`, or `.unknown`. ```swift if let place = place { switch place.takeout { case .true: print("Takeout available") case .false: print("Takeout not available") case .unknown: print("Takeout availability unknown") } } ``` ``` -------------------------------- ### Verify API Key Configuration Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Check if the API key has been successfully set by retrieving the SDK version. If this fails, the API key may not be configured correctly. ```swift // Check if API key was set successfully let version = GMSPlacesClient.SDKVersion() print("SDK version: \(version)") // If this fails, API key may not be configured ``` -------------------------------- ### GMSFetchPlaceRequest Initialization and Configuration Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md This snippet demonstrates how to initialize GMSFetchPlaceRequest and configure its properties like placeID, placeFields, sessionToken, languageCode, and regionCode. ```APIDOC ## GMSFetchPlaceRequest Request object for fetching detailed information about a place by place ID. ### Properties #### placeID - **Type**: NSString - **Required**: Yes - **Description**: The unique identifier of the place to fetch. Example: `"ChIJN1blFLsB1AgTqefmoW_QC8Q"` #### placeFields - **Type**: GMSPlaceField - **Required**: No - **Default**: None - **Description**: Bitfield specifying which place information fields to retrieve. Only requested fields will be present in the returned `GMSPlace` object. Available fields include `GMSPlaceFieldName`, `GMSPlaceFieldFormattedAddress`, `GMSPlaceFieldRating`, `GMSPlaceFieldOpeningHours`, etc. #### sessionToken - **Type**: GMSAutocompleteSessionToken - **Required**: No - **Default**: nil - **Description**: Session token for associating this request with an autocomplete or previous request for billing purposes. Groups multiple requests into a single billable session. #### languageCode - **Type**: NSString - **Required**: No - **Default**: System locale - **Description**: Language code for results (e.g., "en", "es", "fr"). If not specified, results are returned in the preferred language based on system locale. #### regionCode - **Type**: NSString - **Required**: No - **Default**: nil - **Description**: Region code for biasing results (e.g., "us", "ca", "gb"). Helps localize results to a specific country. ### Usage Examples #### Basic Place Fetch ```swift let request = GMSFetchPlaceRequest(placeID: "ChIJN1blFLsB1AgTqefmoW_QC8Q") request.placeFields = GMSPlaceFieldName | GMSPlaceFieldFormattedAddress placesClient.fetchPlaceWithRequest(request) { place, error in if let error = error { print("Error: \(error.localizedDescription)") return } if let place = place { print("Name: \(place.name ?? "")") print("Address: \(place.formattedAddress ?? "")") } } ``` ``` -------------------------------- ### Performing a Simple Autocomplete Request Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSAutocompleteRequest.md Initiates an autocomplete request with a query and processes the suggestions or errors. Ensure you have a GMSPlacesClient instance available. ```swift let request = GMSAutocompleteRequest() request.query = "restaurants" placesClient.fetchAutocompleteSuggestionsFromRequest(request) { suggestions, error in if let error = error { print("Autocomplete error: \(error.localizedDescription)") return } suggestions?.forEach { suggestion in print("Suggestion: \(suggestion.mainText)") } } ``` -------------------------------- ### Initialize GMSAutocompleteResultsViewController Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/UIComponents.md Instantiate the GMSAutocompleteResultsViewController and set its delegate. This controller is designed to be embedded within other UI hierarchies. ```swift let resultsController = GMSAutocompleteResultsViewController() resultsController.delegate = self ``` -------------------------------- ### Check Opening Status Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlace.md Explains how to determine if a place is currently open, closed, or if its status is unknown. This is achieved by creating a `GMSPlaceIsOpenRequest` and using `placesClient.isOpenWithRequest`. ```APIDOC ## Check Opening Status This section describes how to check the current opening status of a place. ### Usage Instantiate a `GMSPlaceIsOpenRequest` with the `GMSPlace` object. Then, use `placesClient.isOpenWithRequest` to get the `response.openingStatus`, which can be `.open`, `.closed`, or `.unknown`. ```swift if let place = place { let isOpenRequest = GMSPlaceIsOpenRequest(place: place) placesClient.isOpenWithRequest(isOpenRequest) { response, error in if let response = response { switch response.openingStatus { case .open: statusLabel.text = "OPEN" statusLabel.textColor = .green case .closed: statusLabel.text = "CLOSED" statusLabel.textColor = .red case .unknown: statusLabel.text = "Unknown" statusLabel.textColor = .gray @unknown default: break } } } } ``` ``` -------------------------------- ### provideAPIKey Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Provides the API key to the Google Places SDK. Must be called before using any other methods. ```APIDOC ## provideAPIKey ### Description Provides the API key to the Google Places SDK. Must be called before using any other methods. ### Parameters #### Path Parameters - **key** (NSString) - Required - API key from Google Cloud Platform Console ### Returns `YES` if the API key was successfully provided, `NO` otherwise. ### Example ```swift GMSPlacesClient.provideAPIKey("YOUR_API_KEY") ``` ``` -------------------------------- ### Create a Session Token Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/README.md Create a session token to group autocomplete queries and subsequent place detail fetches. This can reduce billing costs. ```swift let sessionToken = GMSAutocompleteSessionToken() // Use in autocomplete request autocompleteRequest.sessionToken = sessionToken // Reuse in fetch request (user selects a suggestion) fetchRequest.sessionToken = sessionToken // Both grouped as single billable event ``` -------------------------------- ### Load API Key from Plist Configuration File Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/configuration.md Load the API key from a GooglePlacesConfig.plist file to avoid hardcoding. This method reads the API key from a dictionary in the plist. ```xml PlacesAPIKey YOUR_API_KEY ``` ```swift if let configPath = Bundle.main.path(forResource: "GooglePlacesConfig", ofType: "plist"), let config = NSDictionary(contentsOfFile: configPath), let apiKey = config["PlacesAPIKey"] as? String { GMSPlacesClient.provideAPIKey(apiKey) } else { fatalError("Missing Places API key configuration") } ``` -------------------------------- ### Fetch Place Details with Session Token Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Demonstrates how to fetch place details using a GMSFetchPlaceRequest, reusing a session token from an autocomplete request to group billing. ```APIDOC ## Fetch Place Details with Session Token This example shows how to fetch detailed information about a place using `GMSFetchPlaceRequest`. It highlights the use of a `GMSAutocompleteSessionToken` to group this place fetch request with a prior autocomplete request, ensuring they are billed as a single session. ### Method `placesClient.fetchPlaceWithRequest(_:callback:)` ### Parameters - **fetchRequest** (`GMSFetchPlaceRequest`): The request object containing the place ID and desired fields. It's crucial to set the `sessionToken` property to the same token used for autocomplete. - **callback**: A closure that is executed upon completion, providing a `GMSPlace` object and an `NSError` if the request fails. ### Request Example ```swift // Assuming 'selectedSuggestion' is obtained from an autocomplete query let fetchRequest = GMSFetchPlaceRequest(placeID: selectedSuggestion.placeID) fetchRequest.placeFields = GMSPlaceFieldName | GMSPlaceFieldRating | GMSPlaceFieldPhotos | GMSPlaceFieldOpeningHours fetchRequest.sessionToken = sessionToken // Reuse the session token placesClient.fetchPlaceWithRequest(fetchRequest) { place, error in // Handle the fetched place details or error } ``` ``` -------------------------------- ### Fetch Place with Language and Region Bias Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSFetchPlaceRequest.md Shows how to fetch place details while specifying a language code and a region code to bias the results. ```swift let request = GMSFetchPlaceRequest(placeID: placeID) request.placeFields = GMSPlaceFieldAll request.languageCode = "es" // Request Spanish results request.regionCode = "mx" // Bias to Mexico placesClient.fetchPlaceWithRequest(request) { place, error in if let place = place { // Results are in Spanish and Mexico-relevant print("\(place.name ?? "")") } } ``` -------------------------------- ### Display Place Photos Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlace.md Fetches and displays photos for a place. Allows specifying a maximum size for the fetched photos. Requires a `placesClient` instance and a `GMSFetchPhotoRequest`. ```swift if let place = place, let photos = place.photos { photos.forEach { photoMetadata in let photoRequest = GMSFetchPhotoRequest(photo: photoMetadata) photoRequest.maxSize = CGSize(width: 400, height: 400) placesClient.fetchPhotoWithRequest(photoRequest) { image, error in if let image = image { imageView.image = image } } } } ``` -------------------------------- ### Fetch and Display Place Photos Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/DataStructures.md Iterates through available photos for a place, prints their dimensions, and fetches the image to display. Requires GMSFetchPhotoRequest and a placesClient. ```swift if let photos = place.photos { for photoMetadata in photos { print("Photo: \(photoMetadata.width)x\(photoMetadata.height)") let request = GMSFetchPhotoRequest(photo: photoMetadata) request.maxSize = CGSize(width: 400, height: 400) placesClient.fetchPhotoWithRequest(request) { image, error in if let image = image { imageView.image = image } } } } ``` -------------------------------- ### SDKVersion Source: https://github.com/googlemaps/ios-places-sdk/blob/main/_autodocs/api-reference/GMSPlacesClient.md Returns the version of the SDK (e.g., "10.14.0"). ```APIDOC ## SDKVersion ### Description Returns the version of the SDK (e.g., "10.14.0"). ### Returns String containing the version number. ```