Search code examples
iosjsonswift

Variable was never mutated...or Constant being used before initialized


I'm wanting to get jsonMeals data back and use it outside of this function. However it seems no matter where I place my JSON variable I get an error. Changing it to a let does as well although a different one. Any insight would be greatly appreciated!

Error:

Constant 'json' used before being initialized // Variable 'json' was never mutated; consider changing to 'let' constant

func getApiDetailData(completed: @escaping () -> ()) {
    var json: Any?
    let urlString = "https://www.themealdb.com/api/json/v1/1/lookup.php?i=\(id)"
    let url = URL(string: urlString)
    
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
            do {
                let json = try JSONSerialization.jsonObject(with: data!)
                print("\(json)Testing")
                DispatchQueue.main.async {
                    completed()
                }
            }
            catch {
                print("Error getting detail JSON data:\(error)")
            }
        guard let json = json as? [String : Any],
              let jsonMeals = json["meals"] as? [String: Any] else {
                  print("No meals in json \(error?.localizedDescription)")
                return
            }
        print("testing jsonMeals\(jsonMeals)")
    }.resume()
}

Solution

  • try something like this example code:

    func getApiDetailData(completed: @escaping () -> ()) {
        //   var json: Any?   // <-- remove, never used
        let urlString = "https://www.themealdb.com/api/json/v1/1/lookup.php?i=\(id)"
        let url = URL(string: urlString)
        
        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            do {
                let jsonData = try JSONSerialization.jsonObject(with: data!)
                print("\(jsonData) Testing")
                
                guard let json = jsonData as? [String : Any],
                      let jsonMeals = json["meals"] as? [[String: Any]] else {
                    print("No meals in json \(error?.localizedDescription)")
                    completed()  // <-- here
                    return
                }
                print("testing jsonMeals \(jsonMeals)")
                completed()  // <-- here
            }
            catch {
                print("Error getting detail JSON data:\(error)")
                completed()  // <-- here
            }
        }.resume()
    }
    

    Or, if you want to return the jsonMeals results:

    func getApiDetailData(completed: @escaping ([[String: Any]]?) -> ()) {  // <-- here
      //  var json: Any?   // <-- remove, never used
        let urlString = "https://www.themealdb.com/api/json/v1/1/lookup.php?i=\(id)"
        let url = URL(string: urlString)
        
        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            do {
                let jsonData = try JSONSerialization.jsonObject(with: data!)
                print("\(jsonData) Testing")
                
                guard let json = jsonData as? [String : Any],
                      let jsonMeals = json["meals"] as? [[String: Any]] else {
                    print("No meals in json \(error?.localizedDescription)")
                    completed(nil)  // <-- here
                    return
                }
                print("testing jsonMeals \(jsonMeals)")
                completed(jsonMeals)  // <-- here
            }
            catch {
                print("Error getting detail JSON data:\(error)")
                completed(nil)  // <-- here
            }
        }.resume()
    }