0

Today I ran into a problem, for some reason the url doesn't want to read the link. I don't know how to fix this problem. Everything that I write here: url = URL (string: "here"), for some reason, is not converted into a link. As I understand it, I get nil everywhere because I don't even go to let task = URLSession.shared.dataTask (with: url!), because url is not converted from string to URL.

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    // po searchBar.text
    // print object
    
    let urlString = "http://api.weatherstack.com/current?access_key=617ce097a4c8352ad4fa7b34e2570aa8&query=\(searchBar.text!)"
    
    let url = URL(string: urlString)
    
    var locationName: String?
    var temperature: Double?
    
    let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
            
            if let location = json["location"] {
                locationName = location["name"] as? String
            }
        
            if let current = json["current"] {
                temperature = current["temperature"] as? Double
            }
        }
        catch let jsonError {
            print(jsonError)
        }
    }
    task.resume()
}
TDMNS
  • 281
  • 1
  • 6
  • 19

1 Answers1

2

You should never force unwrap a URL created from a dynamic String which is coming from user input. You should optional bind the return value of URL(string:) and also percent encode your searchbar input to make sure the URL String is valid.

let urlString = "http://api.weatherstack.com/current?access_key=617ce097a4c8352ad4fa7b34e2570aa8&query=\(searchBar.text!)"
guard let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), 
    let url = URL(string: encodedUrlString) else { 
    // You could display an error message to the user from here
    return
}

Unrelated to your question, but you shouldn't be using JSONSerialization to decode the JSON response. Use Codable instead.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • I tried to do it your way, but my output was like this: Thread 5: Fatal error: Unexpectedly found nil while unwrapping an Optional value Already inside the code, here: let json = try JSONSerialization.jsonObject (with: data !, options: .mutableContainers) as! [String: AnyObject] :( I am still new to Swift and watched one blogger's video tutorial on youtube and came across this problem. Although everything works great for that guy, I don't understand what the problem is. – TDMNS Jul 27 '20 at 11:44
  • In data and response, nil values are obtained as a result, and as I understand the link is not readable. The problem was not in the link? I attach an image with a debugger. https://i.stack.imgur.com/qYluB.png – TDMNS Jul 27 '20 at 12:03
  • That's unrelated to your original question. That error is coming from your JSON parsing. Have a look at [Correctly parsing JSON in Swift 3](https://stackoverflow.com/questions/39423367/correctly-parsing-json-in-swift-3) to learn how to parse JSON. The easiest solution is to simply put your JSON response in [quicktype](https://app.quicktype.io/#l=swift) and it will generate the `Codable` models for you. Also, you need to check if there was an `error` in your URL request, `data` will only have a value if `error` is `nil`. – Dávid Pásztor Jul 27 '20 at 12:04