3

我正在使用 Swift 调用 Openweather 地图 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 的闭包,所以我们应该使用完成处理程序。但我不知道我们怎样才能做到这一点。

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

4

2 回答 2

1

如果您想像示例中一样继续使用 SwiftyJSON,请按照以下步骤操作:

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

  • 然后将要“返回”的值包装在处理程序中。

  • 然后像我的示例一样调用您的方法,并带有尾随闭包

斯威夫特 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"
})
于 2015-08-21T10:11:51.047 回答
0

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

您可以通过在调用者函数中实现它来直接从完成句柄中使用它

于 2015-08-21T09:25:03.000 回答