0

I am trying to get the weather for a city using Openweathermap API using this code:

struct WeatherManager { let weatherURL = "https://api.openweathermap.org/data/2.5/weather?appid=XXXXXXXX&units=imperial"

var delegate: WeatherManagerDelegate?

func fetchWeather(cityName: String) {
    let urlString = "\(weatherURL)&q=\(cityName)"
    performRequest(with: urlString)
}

My issue is that Openweathermap API is not very flexible because when you search a city with no spaces like Paris it works fine but if you need to search a city like San Francisco that has a space it won't work unless its typed as San+Francisco.

Where and what type of code can I create that if a space is entered into the search field that it is changed to + and able to fetchWeather and if no spaces are entered it can still use the fetcheWeather.

Super noob so guidance is helpful, thanks in advance!

I want the code to be flexible to take search field text and if there are spaces insert + when fetching weather

  • 2
    Does this answer your question? [Swift - encode URL](https://stackoverflow.com/questions/24551816/swift-encode-url). Or [How to insert space in URL based off user input](https://stackoverflow.com/questions/71905380/how-to-insert-space-in-url-based-off-user-input) – HangarRash Apr 04 '23 at 23:43
  • Note from `openweathermap`, Please use Geocoder API if you need automatic convert city names and zip-codes to geo coordinates and the other way around. `Please note that built-in geocoder has been deprecated. Although it is still available for use, bug fixing and updates are no longer available for this functionality.` In other words, use `lat,lon` only. – workingdog support Ukraine Apr 05 '23 at 00:50
  • edit your question and remove your `secret` api key – workingdog support Ukraine Apr 05 '23 at 00:57
  • I don't understand where and what code to alter/create to remove spaces entered by the user and on the backend remove them and insert + – Amit Tandel Apr 05 '23 at 02:26
  • https://stackoverflow.com/questions/38872376/get-the-weather-for-cities-with-names-that-contain-spaces-using-openweathermap This person seems to have had the same issue but not sure how to fix – Amit Tandel Apr 05 '23 at 02:27

1 Answers1

0

try this approach, using addingPercentEncoding as mentioned in the comments/links, and as shown in the example code, works for me.

import Foundation
import SwiftUI


struct ContentView: View {
    @State var response: WeatherResponse?
    let cityName = "San Fransisco"
    
    var body: some View {
        Text("temperature is \(response?.main.temp ?? 0.0) F  in \(cityName)")
            .task {
                await fetchWeather(for: cityName)
            }
    }
    
    func fetchWeather(for cityName: String) async {
        let apikey = "YOUR-APIKEY"
        // --- here ---
        if let city = cityName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
           let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(city)&units=imperial&appid=\(apikey)") {
            do {
                let (data, _) = try await URLSession.shared.data(from: url)
                response = try JSONDecoder().decode(WeatherResponse.self, from: data)
            } catch {
                print(error)
            }
        }
    }
}

struct WeatherResponse: Codable {
    let coord: Coord
    //  let weather: [Weather]
    let base: String
    let main: Main
    let visibility: Int
    let dt: Int
    let timezone, id: Int
    let name: String
    let cod: Int
}

struct Coord: Codable {
    let lon, lat: Double
}

struct Main: Codable {
    let temp: Double
}

Using your code:

func fetchWeather(cityName: String) {
    // -- here
    if let city = cityName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
        let urlString = "\(weatherURL)&q=\(city)"  // <-- here
        performRequest(with: urlString)
    }
}