Swift - 从模型中的 API 调用返回 JSON 对象作为字典以在视图控制器中使用

Posted

技术标签:

【中文标题】Swift - 从模型中的 API 调用返回 JSON 对象作为字典以在视图控制器中使用【英文标题】:Swift - Returning a JSON object from API call in Model as Dictionary to use in View Controller 【发布时间】:2015-06-21 13:04:57 【问题描述】:

我最近开始尝试使用 Swift,并且对更强类型的编程语言不熟悉。

我正在尝试构建一个对http://openweathermap.org/api 的基本 API 调用,它将在 UIView 中有一个搜索框,它采用城市名称并返回相关的天气数据。

我的问题是弄清楚如何将我从模型中的 API 调用返回的 JSON 响应作为字典返回,然后我可以将其用作 ViewController 中的变量。

我尝试了多种方法,但仍然出现“字典不可转换为 Void”错误。从研究和这篇文章 (Dictionary is not convertible to Void) 看来,返回一个闭包可能会提供答案,但鉴于我只想在我的 ViewController searchButton 函数中传递一个城市名称字符串参数,我很难实现。

下面有详细的代码sn-ps,谢谢帮助!

我在 Model 下面的 API 调用目前用于下拉 JSON 对象

class API 
func weatherSearch(#urlSearch: String) -> Dictionary<String,AnyObject>

    let urlPath = "http://api.openweathermap.org/data/2.5/weather?q=" + urlSearch
    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!, completionHandler: data, response, error -> Void in
        println("Task completed")
        if(error != nil) 
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        
        var err: NSError?
        if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary 
            var dataOut = jsonResult as Dictionary<String,AnyObject>
            return dataOut
         //omitted some additional error handling code
        
    )
    task.resume()
 

我的 ViewController 实例化 API 并从 Searchfield 获取输入

@IBOutlet weak var searchField: UITextField!

@IBAction func searchButton() 
    let api = API()
    var dataOut = api.weatherSearch(urlSearch: searchField.text!)
    println(dataOut)
    self.performSegueWithIdentifier("Search", sender: nil)

【问题讨论】:

你的函数永远不会工作。数据是异步请求的,但您的函数并未为此做好准备。像数据任务一样向函数添加完成块。 @HorseT:你指的是类似的东西吗? if let results: NSArray = jsonResult["results"] as? NSArray dispatch_async(dispatch_get_main_queue(), println(results) ) 【参考方案1】:

使用上面评论暗示的回调技术,尝试这样的事情

func weatherSearch(#urlSearch: String, callback: (Dictionary<String,AnyObject> -> ())) 
    let urlPath = "http://api.openweathermap.org/data/2.5/weather?q=" + urlSearch
    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!, completionHandler: data, response, error -> Void in
        println("Task completed")
        if(error != nil) 
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        
        var err: NSError?
        if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary 
            var dataOut = jsonResult as! Dictionary<String,AnyObject>
            callback(dataOut)
            //omitted some additional error handling code
        
    )
    task.resume()


weatherSearch(urlSearch: "endpoint here")  dictionary in
    println(dictionary)

【讨论】:

以上是关于Swift - 从模型中的 API 调用返回 JSON 对象作为字典以在视图控制器中使用的主要内容,如果未能解决你的问题,请参考以下文章

从 Swift 函数中的异步调用返回数据

从 Swift 函数中的异步调用返回数据

从 Swift 函数中的异步调用返回数据

从 Swift 函数中的异步调用返回数据

从 Swift 函数中的异步调用返回数据

如何从 iOS Swift Codable 中的 API 响应通知或打印模型类上缺少的密钥?