Learn Courses My Dashboard

This error is coming, but the tutorial doesn't get the error

Hey, y’all. I got this error for a weather app I am doing. The error is:

2021-05-29 13:29:26.920628-0400 Weather[17411:751700] Weather/CityViewViewModel.swift:103: Fatal error: Unexpectedly found nil while unwrapping an Optional value

My code:

import SwiftUI
import CoreLocation

final class CityViewViewModel: ObservableObject {
    
    @Published var weather = WeatherResponse.empty()
    
    @Published var city: String = "San Francisco" {
        didSet {
            getLocation()
        }
    }
    
    private lazy var dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .full
        return formatter
    }()
    
    private lazy var dayFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "EEE"
        return formatter
    }()
    
    private lazy var timeFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "hh a"
        return formatter
    }()
    
    init() {
        getLocation()
    }
    
    var date: String {
        return dateFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(weather.current.dt)))
    }
    
    var weatherIcon: String {
        if weather.current.weather.count > 0 {
            return weather.current.weather[0].icon
        }
        return "dayClearSky"
    }
    
    var temperature: String {
        return getTempFor(temp: weather.current.temp)
    }
    
    var conditions: String {
        if weather.current.weather.count > 0 {
            return weather.current.weather[0].main
        }
        return ""
    }
    
    var windSpeed: String {
        return String(format: "%0.1f", weather.current.wind_speed)
    }
    
    var humidity: String {
        return String(format: "%d%%", weather.current.humidity)
    }
    
    var rainChances: String {
        return String(format: "%0.0f%%", weather.current.dew_point)
    }
    
    func getTimeFor(timestamp: Int) -> String {
        return timeFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(timestamp)))
    }
    
    func getTempFor(temp: Double) -> String {
        return String(format: "%0.1f", temp)
    }
    
    func getDayFor(timestamp: Int) -> String {
        return dayFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(timestamp)))
    }
    
    private func getLocation() {
        CLGeocoder().geocodeAddressString(city) { (placemarks, error) in
            if let places = placemarks, let place = places.first {
                self.getWeather(coord: place.location?.coordinate)
            }
        }
    }
    
    private func getWeather(coord: CLLocationCoordinate2D?) {
        if let coord = coord {
            let urlString = API.getURLFor(lat: coord.latitude, lon: coord.longitude)
            getWeatherInternal(city: city, for: urlString)
        } else {
            let urlString = API.getURLFor(lat: 37.5485, lon: -121.9886)
            getWeatherInternal(city: city, for: urlString)
        }
    }
    
    private func getWeatherInternal(city: String, for urlString: String) {
        NetworkManager<WeatherResponse>.fetch(for: URL(string: urlString)!) { (result) in //ERROR
            switch result {
            case .success(let response):
                DispatchQueue.main.async {
                    self.weather = response
                }
                
            case .failure(let err):
                print(err)
            }
        }
    }
    
    func getLottieAnimationFor(icon: String) -> String {
        switch icon {
            case "01d":
                return "dayClearSky"
            case "01n":
                return "nightClearSky"
            case "02d":
                return "dayFewClouds"
            case "02n":
                return "nightFewClouds"
            case "03d":
                return "dayScatteredClouds"
            case "03n":
                return "nightScatteredClouds"
            case "04d":
                return "dayBrokenClouds"
            case "04n":
                return "nightBrokenClouds"
            case "09d":
                return "dayShowerRains"
            case "09n":
                return "nightShowerRains"
            case "10d":
                return "dayRain"
            case "10n":
                return "nightRain"
            case "11d":
                return "dayThunderstorm"
            case "11n":
                return "nightThunderstorm"
            case "13d":
                return "daySnow"
            case "13n":
                return "nightSnow"
            case "50d":
                return "dayMist"
            case "50n":
                return "dayMist"
            default:
                return "dayClearSky"
        }
    }
    
    func getWeatherIconFor(icon: String) -> Image {
        switch icon {
            case "01d":
                return Image(systemName: "sun.max.fill") //"clear_sky_day"
            case "01n":
                return Image(systemName: "moon.fill") //"clear_sky_night"
            case "02d":
                return Image(systemName: "cloud.sun.fill") //"few_clouds_day"
            case "02n":
                return Image(systemName: "cloud.moon.fill") //"few_clouds_night"
            case "03d":
                return Image(systemName: "cloud.fill") //"scattered_clouds"
            case "03n":
                return Image(systemName: "cloud.fill") //"scattered_clouds"
            case "04d":
                return Image(systemName: "cloud.fill") //"broken_clouds"
            case "04n":
                return Image(systemName: "cloud.fill") //"broken_clouds"
            case "09d":
                return Image(systemName: "cloud.drizzle.fill") //"shower_rain"
            case "09n":
                return Image(systemName: "cloud.drizzle.fill") //"shower_rain"
            case "10d":
                return Image(systemName: "cloud.heavyrain.fill")//"rain_day"
            case "10n":
                return Image(systemName: "cloud.heavyrain.fill") //"rain_night"
            case "11d":
                return Image(systemName: "cloud.bolt.fill") //"thunderstorm_day"
            case "11n":
                return Image(systemName: "cloud.bolt.fill") //"thunderstorm_night"
            case "13d":
                return Image(systemName: "cloud.snow.fill") //"snow"
            case "13n":
                return Image(systemName: "cloud.snow.fill") //"snow"
            case "50d":
                return Image(systemName: "cloud.fog.fill") //"mist"
            case "50n":
                return Image(systemName: "cloud.fog.fill") //"mist"
            default:
                return Image(systemName: "sun.max.fill")
        }
    }
}

I know it is because I am force unwrapping an object, but how can I fix the error? My app loses all functionality if I can’t fix this. Thanks!

Which line is it? I see it’s like 103 but the forum doesn’t show line numbers.

@mikaelacaron
I have marked the line with the error, sorry for the inconvenience!

Hi everyone! I’ve tried many other solutions as well, but for some reason, it doesn’t seem to work for me. Does anyone have another solution?

You’re force unwrapping the URL, what url are you passing to this function?

You can use breakpoints to determine that this is the object that’s getting force unwrapped but has nil inside it

@mikaelacaron
Hi, sorry for the late response. The url I am passing is the API call. This is the error code I am getting:

Weather/CityViewViewModel.swift:103: Fatal error: Unexpectedly found nil while unwrapping an Optional value

2021-05-31 11:04:18.388160-0400 Weather[17904:785586] Weather/CityViewViewModel.swift:103: Fatal error: Unexpectedly found nil while unwrapping an Optional value
(lldb) 

My GitHub repository: Github Link

When you are optional or force unwrapping it could returns nil, that is what is causing the error.