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 を使用してデータを 2 回解析していたことに注意してください。そのため、不要な 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 に答える