Observable Geocoder
Tags: swiftobservable
Published: 2024-02-27 16:09:39

---
title: Observable Geocoder
published: true
date: 2024-02-07 08:53:45 UTC
tags: SwiftObservable
canonical_url: https://wesleydegroot.nl/blog/post/Observable-GeoCoder
---

<p>Firstly we want to <code>import CoreLocation</code> for the location services.</p> <p>We're going to construct a basic class, which subclasses <code>ObservableObject</code>.</p> <pre><code class="language-swift">class Geocoder: ObservableObject { /// ... }</code></pre> <p>We're going to add <code>@Published public var</code> (published public variables),<br> for the items we want to expose, in my case it are the following variables <code>placeMark</code>, <code>location</code>, <code>name</code>, <code>iso</code>, <code>country</code>, <code>postalCode</code>, <code>state</code>, <code>subState</code>, <code>city</code>, <code>subCity</code>, <code>street</code>, <code>subStreet</code>, <code>region</code>, <code>timeZone</code>, <code>inlandWater</code>, <code>ocean</code> and <code>areasOfInterest</code>.</p> <p>Full Code:</p> <pre><code class="language-swift">import CoreLocation class Geocoder: ObservableObject { /// Placemark @Published public var placeMark: CLPlacemark? /// Location @Published public var location: CLLocation? /// The name of the placemark. @Published public var name: String? /// The abbreviated country or region name. @Published public var iso: String? /// The name of the country or region associated with the placemark. @Published public var country: String? /// The postal code associated with the placemark. @Published public var postalCode: String? /// The state or province associated with the placemark. @Published public var state: String? /// Additional administrative area information for the placemark. @Published public var subState: String? /// The city associated with the placemark. @Published public var city: String? /// Additional city-level information for the placemark. @Published public var subCity: String? /// The street address associated with the placemark. @Published public var street: String? /// Additional street-level information for the placemark. @Published public var subStreet: String? /// The geographic region associated with the placemark. @Published public var region: CLRegion? /// The time zone associated with the placemark. @Published public var timeZone: TimeZone? /// The name of the inland water body associated with the placemark. @Published public var inlandWater: String? /// The name of the ocean associated with the placemark. @Published public var ocean: String? /// The relevant areas of interest associated with the placemark. @Published public var areasOfInterest: [String]? /// Geocoder private let geoCoder = CLGeocoder() init () { } /// Update to location func update (to location: CLLocation) { geoCoder.reverseGeocodeLocation( location, completionHandler: { (placemarks, \_) -&gt; Void in // We're only using the first place mark. if let placeMark = placemarks?[0] { self.placeMark = placeMark self.location = placeMark.location self.name = placeMark.name self.iso = placeMark.isoCountryCode self.country = placeMark.country self.postalCode = placeMark.postalCode self.state = placeMark.administrativeArea self.subState = placeMark.subAdministrativeArea self.city = placeMark.locality self.subCity = placeMark.subLocality self.street = placeMark.thoroughfare self.subStreet = placeMark.subThoroughfare self.region = placeMark.region self.timeZone = placeMark.timeZone self.inlandWater = placeMark.inlandWater self.ocean = placeMark.ocean self.areasOfInterest = placeMark.areasOfInterest // Send a notification that our `@Published` values have been changed. self.objectWillChange.send() } } ) } }</code></pre> <h2>Usage</h2> <pre><code class="language-swift">geocoder.update(to: .init( latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude ))</code></pre>