[ad_1]
I’m utilizing WeatherKit and am attempting to transform a metropolis title to a CLLocation so I can move it to the weatherService however I’m not positive how to do that. I do know there’s a geocodeAddressString however I wasn’t in a position to get it to work and I do not suppose it might return a CLLocation. Together with that I’m additionally having hassle with getting location information from a number of places. I’m confused on what kind of array I’d make which means would I make an array of Climate objects of an array of simply metropolis names after which convert them to coordinates once I must get the climate information. My code that I’ve thus far is beneath. Any assist with these could be nice.
WeatherKitTestApp
”’
import SwiftUI
import WeatherKit
@essential
struct WeatherKitTestApp: App {
let weatherService = WeatherService.shared
@StateObject personal var locationManager = LocationManager()
var physique: some Scene {
WindowGroup {
ContentView(weatherService: weatherService, locationManager: locationManager)
}
}
}
”’
ContentView
”’
import SwiftUI
import WeatherKit
struct ContentView: View {
let weatherService: WeatherService
@ObservedObject var locationManager: LocationManager
@State personal var climate: Climate?
@State var searchLocation: String = ""
var physique: some View {
NavigationView {
if locationManager.weatherLocations.isEmpty {
Textual content("Add a location")
} else {
TabView {
ForEach(locationManager.weatherLocations, id: .self) { location in
VStack {
HStack {
TextField("Climate Location", textual content: $searchLocation)
.padding(.horizontal)
.body(width: 200)
.background {
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Colour(UIColor.lightGray))
}
Button(motion: {
locationManager.weatherLocations.append(searchLocation)
searchLocation = ""
print(locationManager.weatherLocations)
}) {
Picture(systemName: "plus")
}
}
.padding(.horizontal)
if let climate {
VStack {
Textual content("(location)")
Textual content("(climate.currentWeather.date.formatted())")
Textual content(climate.currentWeather.temperature.formatted())
}
}
}
.activity(id: locationManager.currentLocation) {
do {
if let location = locationManager.currentLocation {
self.climate = strive await weatherService.climate(for: location)
}
} catch {
print(error)
}
}
}
}
.tabViewStyle(.web page)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(weatherService: WeatherService(), locationManager: LocationManager())
}
}
”’
LocationManager
”’
import Basis
import CoreLocation
class LocationManager: NSObject, ObservableObject {
@Revealed var currentLocation: CLLocation? {
didSet {
if let currentLocation {
resolveLocationName(with: currentLocation) { locationName in
self.weatherLocations.append(locationName!)
}
}
}
}
@Revealed var metropolis: String = ""
personal let locationManager = CLLocationManager()
@Revealed var weatherLocations: [String] = []
override init() {
tremendous.init()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.delegate = self
}
public func resolveLocationName(with location: CLLocation, completion: @escaping ((String?) -> Void)) {
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
guard let place = placemarks?.first, error == nil else {
completion(nil)
return
}
var title = ""
if let locality = place.locality {
title += locality
}
if let adminRegion = place.administrativeArea {
title += ", (adminRegion)"
}
completion(title)
}
}
func getCoordinate(addressString: String, completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(addressString) { (placemarks, error) in
if error == nil {
if let placemark = placemarks?[0] {
let location = placemark.location!
completionHandler(location.coordinate, nil)
return
}
}
completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
}
}
// One other try at attempting to transform metropolis title to CLLocation
/*
personal func getLocation() {
CLGeocoder().geocodeAddressString(metropolis, completionHandler: {(placemarks, error) in
if error != nil {
print("Error: ", error!)
}
if let placemark = placemarks?.first {
let location = placemark.location!.coordinate
return
}
})
}
*/
func appendLocation(location: String) {
weatherLocations.append(location)
}
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ supervisor: CLLocationManager, didUpdateLocations places: [CLLocation]) {
guard let location = places.final, currentLocation == nil else { return }
DispatchQueue.essential.async {
self.currentLocation = location
}
supervisor.stopUpdatingLocation()
}
}
”’
[ad_2]
