- Developers
- Sygic Maps SDK
- iOS
- Search
Search
- Move to section
Autocomplete
The Sygic iOS SDK includes a Search API which provides functionality to search and obtain more information about places in the real world.
Note that offline search is supported when a data connection is unavailable, if the data required to perform the search has been previously downloaded. Geocoding APIs resolve a free-formatted text query to an SYGeoCoordinates, while reverse geocoding APIs resolve from an SYGeoCoordinates to geographic data.
Important note: despite the fact that many SYSearch instances can coexist at the same time, please note that each instance leaves some internal resources until the whole Sygic SDK is terminated.
Note: The offline/online search is no longer handled by the onlineMapsEnabled switch.
Example:
class DemoSearch {
let search = SYSearch()
var session: SYSearchSession?
var results = [SYSearchAutocompleteResult]()
func autocomplete() {
let session = prepareValidSession() // reuse existing session, if it's valid
let request = SYSearchRequest(query: "airport", location: SYGeoCoordinate(latitude: 48.142596, longitude: 17.125206))
session.autocomplete(request) { (results: [SYSearchAutocompleteResult]?, status: SYSearchStatus) in
guard status == .success, let results = results else { /* handle error */ return }
// results are ready
self.results = results
results.forEach { (result) in
self.printAutocompleteResult(result)
}
}
}
func geocodeLocation(autocompleteResultIndex index: Int) {
// for geocodeLocation, it must be the same session, which returned that exact autocomplete result
guard let session = session, session.isValid else { /* handle error */ return }
guard let autocompleteResult = (index >= 0 && index < results.count ? results[index] : nil) else { return }
guard let locationId = autocompleteResult.locationId else { return }
let request = SYGeocodeLocationRequest(locationId: locationId)
session.finish(byRequestingGeocodeLocation: request) { (result: SYSearchGeocodingResult?, status: SYSearchStatus) in
guard status == .success, let result = result else { /* handle error */ return }
// detailed result is ready
self.printDetailedResult(result)
}
}
func geocode() {
let session = prepareValidSession() // reuse existing session, if it's valid
let request = SYSearchRequest(query: "airport", location: SYGeoCoordinate(latitude: 48.142596, longitude: 17.125206))
session.finish(byRequestingGeocode: request) { (results: [SYSearchGeocodingResult]?, status: SYSearchStatus) in
guard status == .success, let results = results else { /* handle error */ return }
// detailed results are ready
results.forEach { (result) in
self.printDetailedResult(result)
}
}
}
func prepareValidSession() -> SYSearchSession {
if let session = session, session.isValid {
return session
} else {
let session = search.startSession(.offline)
self.session = session
return session
}
}
func printAutocompleteResult(_ result: SYSearchAutocompleteResult) {
let title = result.title?.value ?? ""
print("Autocomplete: \(title), \(result.type.rawValue)")
}
func printDetailedResult(_ result: SYSearchGeocodingResult) {
let title = result.title?.value ?? ""
let lat = result.location?.latitude ?? 0
let lon = result.location?.longitude ?? 0
print("GeocodingResult: \(title), \(result.type.rawValue); \(lat),\(lon)")
if let mapResult = result as? SYSearchMapResult {
// mapResult provides more specific info
} else if let favoriteResult = result as? SYSearchFavoriteResult {
// favoriteResult provides more specific info
} // else if let ... SYSearch...Result
}
}
Places
You can also search places around a specific coordinate in a radius or in a Bounding Box.
Here's an example on how to do it.
Note: to request more places for the same request, use SYSearchMorePlacesSession
extension DemoSearch {
func placesRequestLocation() -> SYSearchPlacesRequest {
let location = SYGeoCoordinate(latitude: 48.142596, longitude: 17.125206)
let request = SYSearchPlacesRequest(location: location, radius: 10000, tags: [SYPlaceCategoryPetrolStation, SYPlaceCategoryPharmacy])
request.maxResultsCount = 22
return request
}
func placesRequestBoundingBox() -> SYSearchPlacesRequest {
let box = SYGeoBoundingBox(bottomLeft: SYGeoCoordinate(latitude: 48.139466, longitude: 17.103821),
topRight: SYGeoCoordinate(latitude: 48.149452, longitude: 17.118079))
let request = SYSearchPlacesRequest(boundingBox: box, tags: [SYPlaceCategoryRestaurant])
request.maxResultsCount = 14
return request
}
func places() {
let session = prepareValidSession() // reuse existing session, if it's valid
let request = placesRequestLocation() //or placesRequestBoundingBox()
session.finish(byRequestingPlaces: request) {
(places: [SYPlace]?, morePlacesSession: SYSearchMorePlacesSession?, status: SYSearchStatus) in
guard status == .success, let places = places else { /* handle error */ return }
// place results are ready
places.forEach { (place) in
self.printPlace(place)
}
// morePlacesSession can be saved and then used to get more places for the same request
}
}
func printPlace(_ place: SYPlace) {
print("")
print("Place name: \(place.link.name); cat: \(place.link.category); gps: \(place.link.coordinate)")
place.details.forEach { (arg0) in
let (key, value) = arg0
print("Place detail: \(key): \(value)")
}
}
}
Reverse Geocoding
Applications developed with the Sygic iOS SDK can perform offline and online geocoding, which allows geocode and reverse geocode requests to be performed event without an active data connection.
class SearchViewController: UIViewController {
var reverseSearchResults: [SYReverseSearchResult] = []
// Create an instance of SYReverseSearch
let reverseSearch = SYReverseSearch()
// Example of your method to perform reverse geocoding for specific coordinate
func reverseSearch(at coordinate: SYGeoCoordinate) {
// Perform request for coordinate
self.reverseSearch.reverseSearch(with: coordinate) { [weak self] (reverseSearchResults, error) in
self?.reverseSearchResults = reverseSearchResults
// Example of accessing reverse geocoding results description
if let firstResult = reverseSearchResults?.first {
let resultDescription = firstResult.resultDescription // Contains textual description of the found result
let countryIsoCode = resultDescription.countryIso
let city = resultDescription.city
let street = resultDescription.street
let houseNumber = resultDescription.houseNumber
}
}
}
}
- Previous article: Navigation
- Next article: API Reference