1
func downloadCurrentWeather(completed: @escaping DownloadComplete){
    Alamofire.request(API_URL).responseJSON { (response) in
        let result = response.result

        let json = JSON(result.value) // <-- (EXPRESSION IMPLICITLY COERCED WARNING)
        self._cityName = json["name"].stringValue
        let tempDate = json["dt"].double
        let convertedDate = Date(timeIntervalSince1970: tempDate!)
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .none
        let currentDate = dateFormatter.string(from: convertedDate)
        self._date = "\(currentDate)"
        self._weatherType = json["weather"][0]["main"].stringValue
        let downloadedTemp = json["main"]["temp"].double
        self._currentTemp = (downloadedTemp! - 273.15).rounded(toPlaces: 0)
        completed()
    }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Possible duplicate of [Swift 3: Expression implicitly coerced from 'UIView?' to Any](https://stackoverflow.com/questions/40386836/swift-3-expression-implicitly-coerced-from-uiview-to-any) – Tamás Sengel Mar 22 '18 at 17:28
  • The `value` is optional, methinks. Replace `let result = ...` line with `guard let result = ... else { ... }` statement, specifying what you want it to do in case `result` was `nil`... – Rob Mar 22 '18 at 17:36
  • Welcome to StackOverflow! Perhaps you can add more details and show what you have done on your own to answer your question (e.g. what you have found on Google, what you didn't understand of it and so on). Have a read of [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) for more information. – Francesco B. Mar 22 '18 at 18:49

1 Answers1

3

It's coercing it because value is a Any? optional value. I'd suggest unwrapping the value to make sure it's not nil:

func downloadCurrentWeather(completed: @escaping DownloadComplete){
    Alamofire.request(API_URL).responseJSON { (response) in
        guard let value = response.result.value else {
            print(response.result.error ?? "Unknown error")
            return
        }

        let json = JSON(value)

        ...
    }
}

As a further refinement, I'd change DownloadComplete to include information about whether it failed or not. For example, I might add an Error? parameter, and then you could do:

func downloadCurrentWeather(completed: @escaping DownloadComplete){
    Alamofire.request(API_URL).responseJSON { (response) in
        guard let value = response.result.value else {
            completed(response.result.error)
            return
        }

        let json = JSON(value)

        ...

        completed(nil)
    }
}

Then the caller could see if the error was nil or not.


The other approach is to switch on response.result, because in the .success case, you can just use the associated value:

func downloadCurrentWeather(completed: @escaping DownloadComplete){
    Alamofire.request(API_URL).responseJSON { response in
        switch response.result {
        case .failure(let error):
            completed(error)
        case .success(let value):
            let json = JSON(value)
            ...
            completed(nil)
        }
    }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044