为啥除了纬度和经度之外的所有内容的 JSON 都返回为零?

Posted

技术标签:

【中文标题】为啥除了纬度和经度之外的所有内容的 JSON 都返回为零?【英文标题】:Why is the JSON returning as nil for everything besides latitude and longitude?为什么除了纬度和经度之外的所有内容的 JSON 都返回为零? 【发布时间】:2019-02-25 23:30:15 【问题描述】:
import UIKit

class ViewController: UIViewController 

@IBOutlet weak var tableview: UITableView!
var weatherList: [weatherJSON] = []


func downloadJSON() 
    let jsonUrlString = "https://api.darksky.net/forecast/59c6b6b7efd5c3fc0f617338cfae6c48/40.7127,-74.0059"
    guard let url = URL(string: jsonUrlString) else return
    URLSession.shared.dataTask(with: url)  (data, response, err) in
        guard let data = data else return

        do 
            let JSON = try JSONDecoder().decode(weatherJSON.self, from: data)
            self.weatherList.append(JSON)
            print(self.weatherList)
            DispatchQueue.main.async 
                self.tableview.reloadData()
            
         catch let jsonErr 
            print("Error serializing json", jsonErr)
        

        .resume()


override func viewDidLoad() 
    super.viewDidLoad()
    downloadJSON()





extension ViewController: UITableViewDataSource 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return weatherList.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! countryCell


cell.nameLabel?.text = "\(String(describing: weatherList[indexPath.row].latitude))"


    return cell



extension ViewController: UITableViewDelegate 
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    performSegue(withIdentifier: "segue1", sender: nil)


编辑:我通过使用字符串插值成功调用了 JSON 数据 -

cell.nameLabel?.text = "(String(describing: weatherList[indexPath.row].latitude))"

但现在,在我的通话中,唯一返回 nil 的信息是纬度和经度。为什么从我的 JSON 调用成功返回的唯一内容为零?我是不是叫错了什么?感谢您迄今为止的所有帮助。如果我应该发新帖子,请告诉我。我认为这是同一个主题,因为它与我昨天的原始帖子几乎相同。

*** 本身不会让我在不添加更多文本的情况下发帖,但因为我已经说出了我需要说的一切,这只是补充。

【问题讨论】:

您在哪里尝试使用加载的数据更新您的 weatherList 属性? (我是新手,所以我知道我在问一个非常简单的问题,但我不知道该怎么做。)如何做到这一点? 您没有将请求的 JSON 结果保存在 weatherList[] 中。你需要这样做。我在回答中解释了@Westopher 这无论如何都行不通。 JSON 是单个对象,您将 weatherList 声明为数组。答案取决于weatherJSON 结构的结构。您想要显示哪些信息——有很多信息?顺便说一句,结构名称应该以大写字母开头。 @vadian 我真的只是想从这个 json 解析到我的 tableview 中获取我能得到的任何信息。是的,我的结构在我的模型中是大写的;我会在我的代码中更新它,谢谢。那么你如何让json正确地附加到weatherList中呢?这段代码是什么样的? 【参考方案1】:

为了获得更好/更简洁的代码,也许您想将 API 调用分离到一个函数中(可能是 func makeRequest() 或其他东西),以便仅在您的 viewDidLoad. 中调用该函数

你有

var weatherList: [weatherJSON] = []

这是一个包含您希望表格显示的 weatherJSON 对象的列表,但问题出在您的请求中,您正在重新加载表格中的数据,但您没有将 JSON 响应保存在 weatherList 中。 您应该首先将 JSON 响应保存在变量 weatherList 中,或者将结果附加到该数组中。这样做,您将能够在以下情况下填充您的表格:cell.nameLabel?.text = weatherList[indexPath.row]

另外,您需要添加要显示的天气列表对象的属性。 类似weatherList[indexPath.row].name 或对象拥有的属性的名称。

另外,我建议使用一些库来发出 HTTP 请求,例如 AlamoFire 和 SwiftyJson,以将您的 JSON 响应映射到您的对象。

使用我提到的库,您的整个 API 调用和表函数可以是这样的 函数 getWeather()

    let url: String = "http://example.com/api/weather/"

    AFWrapper.requestGETURL(url, success: 
        (JSONResponse) -> Void in

        for item in JSONResponse
            let weatherList = [WeatherList(fromJson: item.1)]

            for weather in weatherList 
                self. weatherList.append(weather)
            
        

        self.tableView.reloadData()
    )
    
        (error) -> Void in
        print("Error \(error)")
    





在你的表中:

cell.nameLabel.text =  self.weatherList[indexPath.row].name

这可以通过一个 AlamoFireWrapper 类来实现,以像这样发布和获取请求: AlamoFireWrapper.swift

import UIKit
import Alamofire
import SwiftyJSON

class AFWrapper: NSObject 
    class func requestGETURL(_ strURL: String, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void) 
        Alamofire.request(strURL).responseJSON  (responseObject) -> Void in



            if responseObject.result.isSuccess 
                let resJson = JSON(responseObject.result.value!)
                success(resJson)
            
            if responseObject.result.isFailure 
                let error : Error = responseObject.result.error!
                failure(error)
            
        
    

    class func requestPOSTURL(_ strURL : String, params : [String : AnyObject]?, headers : [String : String]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void)

        Alamofire.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON  (responseObject) -> Void in



            if responseObject.result.isSuccess 
                let resJson = JSON(responseObject.result.value!)
                success(resJson)
            
            if responseObject.result.isFailure 
                let error : Error = responseObject.result.error!
                failure(error)
            
        
    

【讨论】:

加博,谢谢你给我看这个。我不知道既然你可以使用可解码的,为什么还要使用 Alamofire?可解码的代码要少得多,而且不是外部的,所以随着时间的推移它会更加稳定,是吗?我并不是要逆势而为,我很欣赏您的回答,但是,如果您可以在不使用 JSON 的情况下获得 JSON,我真的很困惑使用 Alamofire 的优势是什么? 另外,我只是在学习,所以我实际上只是想让我的 JSON 填充到 tableview 中。这就是我想做的一切;第一步是婴儿... 被否决了,你不应该推荐容易被苹果库替换的库,除非它们比苹果库提供了积极的好处。 Alamofire 对于 URLSession 是非常多余的,而 SwiftyJSON 通过 Codable 是多余的。 谢谢@SeanLintern88;我对编码比较陌生,但我认为同样的事情。你能看看上面的问题并帮助我解决这个问题吗?我真的很想只使用 URLSession 和 Codable 成功地将这个坏男孩击倒。谢谢!

以上是关于为啥除了纬度和经度之外的所有内容的 JSON 都返回为零?的主要内容,如果未能解决你的问题,请参考以下文章

MKCoordinateSpanMake:为啥要指定经度和纬度增量?

经度和纬度值都是 0.000000 ,为啥?

为啥 LAG 除了一行之外的所有内容都返回 null?

Xcode 6 为啥 CLLocationManager 没有返回纬度和经度

为啥 xcode 4.2 位置模拟不允许输入纬度和经度的浮点值?

为啥 lyft 和 uber 移动 web api 都需要目的地的纬度/经度