JSON不能转换为void(Openweather map API)

时间:2015-08-21 08:45:33

标签: swift swifty-json completionhandler

我使用Swift调用Openweather map API,我需要将特定值作为字符串返回。

但是当我尝试返回值时出现错误,因为JSON不能转换为字符串。

func callWeatherServ(name:String, completion:(Dictionary<String,AnyObject>) -> Void)
{
    var baseUrl: String = "http://api.openweathermap.org/data/2.5/weather"

    var url: String = "\(baseUrl)?q=\(name)"

    let finalUrl: NSURL = NSURL(string: url)!

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithURL(finalUrl, completionHandler: {data, response, error -> Void in
        if error != nil
        {
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        }

        var err: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSDictionary
        if err != nil
        {
            // If there is an error parsing JSON, print it to the console
            println("JSON Error \(err!.localizedDescription)")
        }

        let json = JSON(jsonResult)
        println("response is \(json) ")

        var  weathername = json["weather"][0]["main"]

        if (weathername != nil)
        {
            return weathername

        }
    })
    task.resume()
}

我得到了,因为我们使用了返回类型为void的闭包,所以我们应该使用完成处理程序。但我不知道我们怎么能这样做。

如果我们将完成处理程序作为参数传递,我们如何调用该函数?

2 个答案:

答案 0 :(得分:1)

如果您想继续使用SwiftyJSON,请按照以下步骤操作:

  • 将完成处理程序的类型从字典更改为SwiftyJSON使用的JSON类型。

  • 然后包装你想要的值&#34;返回&#34;在处理程序中。

  • 然后在我的示例中调用您的方法,并使用尾随闭包

Swift 2

func callWeatherServ(name:String, completion:(object: JSON) -> Void) {
    let baseUrl: String = "http://api.openweathermap.org/data/2.5/weather"
    let url: String = "\(baseUrl)?q=\(name)"
    if let finalUrl = NSURL(string: url) {
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(finalUrl, completionHandler: {data, response, error -> Void in
            if let error = error {
                print(error.localizedDescription)
            } else {
                if let data = data {
                    let json = JSON(data: data)
                    print("response is \(json) ")
                    completion(object: json["weather"][0]["main"])
                } else {
                    print("No data")
                }
            }
        })
        task.resume()
    }
}

调用方法:

callWeatherServ("paris") { (object) in
    // here you get back your JSON object
    print(object)
}

请注意,您使用NSJSONSerialization和SwiftyJSON解析了两次数据,因此我删除了不必要的NSJSONSerialization部分。

原始Swift 1版本

func callWeatherServ(name:String, completion:(object: JSON) -> Void)
{
    var baseUrl: String = "http://api.openweathermap.org/data/2.5/weather"

    var url: String = "\(baseUrl)?q=\(name)"

    let finalUrl: NSURL = NSURL(string: url)!

    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithURL(finalUrl, completionHandler: {data, response, error -> Void in
        if error != nil
        {
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        }

        var err: NSError?
        let json = JSON(data: data, options: NSJSONReadingOptions.allZeros, error: &err)
        println("response is \(json) ")

        var  weathername = json["weather"][0]["main"]

        if (weathername != nil)
        {
            completion(object: weathername)

        }
    })
    task.resume()
}

调用方法:

callWeatherServ("paris", completion: { (object) -> Void in
    println(object)  // "Clear"
})

答案 1 :(得分:0)

从您调用此方法的位置实现完成处理程序,并在该位置使用字符串,只需要不返回该字符串。

您可以通过在调用函数

中实现它来直接从完成句柄中使用它