iosswiftgoogle-places-api

How to combine business name and address to find the point of interest using the Google Places API Text Search?


I am building an application that is using Apple's MapKit framework as well as Google's Places API. The reason is mainly saving costs.

My current situation is, that I have an MKMapItem and want to find the corresponding GMSPlace. I want to use the GMSPlace to get further details about the point of interest, like opening times for example. My idea was to use Google's TextSearch and was building my solution based on the following support site.

Unfortunately, I am unable to find the corresponding places this way, as my query returns empty sets when getting fed with the places name as well as its address.

My code for the API looks as follows and works with generic queries. Feeding it with questions like "pizza" returns viable results in the correct region. However, when I provide the following query and locationbias, I get an empty result set. The same happens when I actually provide the exact address details.

class PlacesViewModel: ObservableObject {
    @Published var placeResults: [GMSPlace] = []
    @Published var placeResult: GMSPlace? = nil
    @Published var errorMessage: String? = nil
    
    func searchPlaces(query: String, location: CLLocationCoordinate2D) {
        // Define the properties we want to retrieve
        let myProperties = [GMSPlaceProperty.name, GMSPlaceProperty.placeID, GMSPlaceProperty.openingHours, GMSPlaceProperty.website].map { $0.rawValue }
        
        // Create the GMSPlaceSearchByTextRequest object
        let request = GMSPlaceSearchByTextRequest(textQuery: query, placeProperties: myProperties)
        request.maxResultCount = 5
        request.rankPreference = .distance
        
        request.locationBias = GMSPlaceCircularLocationOption(location, 500.0)
        
        // Callback to handle the response
        let callback: GMSPlaceSearchByTextResultCallback = { [weak self] results, error in
            guard let self = self else { return }
            
            if let error = error {
                DispatchQueue.main.async {
                    self.errorMessage = error.localizedDescription
                }
                return
            }
            
            guard let results = results else {
                return
            }
            
            DispatchQueue.main.async {
                self.placeResults = results
                print(self.placeResults)
                //self.placeResult = results[0]
            }
        }
        
        // Perform the search
        GMSPlacesClient.shared().searchByText(with: request, callback: callback)
    }
}

Does anybody have an idea on how to construct the query?, or which function/API I can use instead?


Solution

  • I tried around a bit and realised that there is no solution using Google's Text Search. Instead, using the same kind of query, one can use Google's AutocompleteSuggestions function. This one does return the placeID for a specific shop and address. I built it the same way as I did the TextSearch in my original question. Happy to answer further questions if somebody encounters the same issue.

    class PlacesViewModel: ObservableObject {
        @Published var errorMessage: String? = nil
        var placeSuggestions: [GMSAutocompleteSuggestion] = []
    
        func fetchSuggestions(query: String, location: CLLocationCoordinate2D) {
            let token = GMSAutocompleteSessionToken()
    
            let filter = GMSAutocompleteFilter()
            filter.locationBias = GMSPlaceCircularLocationOption(location, 200.0)
            
            let request = GMSAutocompleteRequest(query: query)
            request.filter = filter
            request.sessionToken = token
        
            let callback: GMSAutocompleteSuggestionsCallback = { [weak self] results, error in
                guard let self = self else { return }
            
                if let error = error {
                    DispatchQueue.main.async {
                        self.errorMessage = error.localizedDescription
                    }
                    return
                }
            
                if let results = results {
                    DispatchQueue.main.async {
                        self.placeSuggestions = results
                        print(results)
                    }
                } else {
                    return
                }
            }
    
            GMSPlacesClient.shared().fetchAutocompleteSuggestions(from: request, callback: callback)
        }
    }