在 Swift 中解析 JSON 24 小时的问题 [关闭]

Posted

技术标签:

【中文标题】在 Swift 中解析 JSON 24 小时的问题 [关闭]【英文标题】:Parse JSON in Swift 24hours of problems [closed] 【发布时间】:2018-07-03 20:20:03 【问题描述】:

我现在完成这个项目的精力和时间都很有限,我已经尽我所能去学习、理解和实施一个解决方案,但没有成功,我真的很想得到一些帮助。有人对实施解决方案有任何想法吗?

我真的很难用 Swift 将 json 文件解析到我的 ios 应用程序中。 我有一个来自 SQL 数据库的 JSON 输出。我认为格式错误并且数据标题有点模棱两可,但我聘请来创建流程的开发人员对输出感到满意。链接如下。

所以在过去的 3 天里,我阅读了所有关于解析 JSON 的 Apple Developer 材料,还观看了许多教程,它们都涵盖了几乎相同的数据,我不知道我阅读了多少并转换为实际全部失败的项目。我真的需要一些指导。我什至不顾一切地尝试从不同的角度理解我的问题,我研究了它是如何用其他语言完成的。 这是最新的迭代:

导入 UIKit 导入基金会

struct ScheduleList: Codable 
let data: [Datum]

enum CodingKeys: String, CodingKey 
    case data = "data"
  


struct Datum: Codable 
let date: String
let message: String
let notice: String

enum CodingKeys: String, CodingKey 
    case date = "date"
    case message = "message"
    case notice = "notice"
  


class VCMainViewController: UIViewController 

@IBOutlet weak var flightTable: UITableView!

@IBOutlet weak var date: UILabel!

@IBOutlet weak var route: UILabel!

@IBOutlet weak var std: UILabel!

@IBOutlet weak var sta: UILabel!

@IBOutlet weak var pax: UILabel!


let flight = [Datum]()

func parse() 
    let jsonUrlString = "http://35.237.114.234/api/index.php?uid=Bx7faf08A9fYJ7bZCNMUX9EzxYN2"

    guard let url = URL(string: jsonUrlString) else  return 

    let task = URLSession.shared.scheduleListTask(with: url)  (scheduleList, response, error) in

        guard let scheduleList = scheduleList, error == nil, response != nil else 
            print("Something Wrong")
            return
        
        print("downlaoded")

        do 
            let decoder = JSONDecoder()
//Error Here: Cannot convert value of type 'ScheduleList' to expected argument type 'Data'
            let downloadedFlights = try decoder.decode([scheduleList], from: scheduleList)
            self.flight = downloadedFlights.date
         catch 
            print("Something wrong after loading")
        

    
//I find I can print data / scheduleList here and it still returns correct data. So something above I guess is the problem.
    task.resume()

    /*
        if scheduleList != nil 
                 print(scheduleList!)
         else 
            print(error)
        
     
    */




override func viewDidLoad() 
    super.viewDidLoad()

    parse()


**由于原始帖子的问题,现在添加了完整的 JSON 文件。

我认为结构是问题所在。 有什么建议我哪里出错了吗?我不能将其转换为 Data,dataTask 数据称为 scheduleList 所以我不知道为什么它不会接受它。

谢谢

【问题讨论】:

那么当你运行这段代码时会发生什么?使用有关任何消息、错误等的详细信息更新您的问题(不要发布 cmets)。 随意看看我的帖子,也许它会有所帮助。 ***.com/questions/50420124/… 也可以查看 json4swift.com 只需在谷歌上搜索“JSON 在线查看器验证器”即可。您会注意到您的 JSON ISN'T 格式正确 - 并且查看器应该会帮助您显示在哪里,以及您可以做些什么来解决它。例如:JSON formatter and validator 抱歉,我删除了抓取的最后一部分,因为它不是相关数据,但都在一个结果页面上。如果您想全面了解,请在链接中查看。 for person in data 应该是 for person in memebers。该错误表明您正在尝试使用尚未定义的变量。 【参考方案1】:

只需将您的最后两个字符从 ], 更改为 ],您将获得有效的 JSON。

它甚至可以工作:)

如果没有,请发回确切的错误消息,以及失败所在的行。

再说一次,有一个方便的 JSON 格式化程序/浏览器/验证器是很好的。我通常使用 Notepad++ 插件。这是一个很好的在线浏览器:

JSON formatter and validator

另见:

Stack Overflow: How to create a Minimal, Complete, and Verifiable example

【讨论】:

请在 url 查看完整的 JSON。我将数据修剪为不相关。将更改最后一行以关闭。另请参阅最后一个代码块,因为当前出现错误。 我检查了文件是否存在并且作为 JSON 有效并且在转换器中转换得很好。但不能让它在 Swift 中工作。【参考方案2】:

在 Swift 4.1 中处理 JSON 的新方法是使用Codable 协议(或其子变体EncodableDecodable)。要将 JSON 字符串转换为实际对象,您应该使用 Decodable

//: Playground - noun: a place where people can play

import UIKit
import Foundation

struct Message: Decodable 
    let date: String
    let message: String
    let notice: String


struct Flight: Decodable 
    let flight: String
    let aircraft: String
    let operating: String
    let type: String
    let route: String
    let std: String
    let sta: String
    let pax: String
    let prm: String
    let check: String


struct Response: Decodable 
    let data: [Message]
    let flights: [Flight]
    let state: String

    private enum CodingKeys: String, CodingKey 
        case data, state
        case flights = "flight" // Parses "flight" from the response to the flights property
    



// Get a String from your JSON and convert it to Data
let jsonString = "..."
let jsonData = jsonString.data(using .utf8)!

// Initialize the decoder
let decoder = JSONDecoder()

// Try to convert your JSON to objects
do 
    let response = try decoder.decode(Response.self, from: jsonData)
    print("Decoded successfully: \(response)")

    // Access values as usual with a struct... well, this IS a Swift struct already
    print("State: \(response.state)")
    // etc...
 catch 
    print("Error decoding: \(error)")

在此处查看 Apple 文档:

1) Encoding and Decoding Custom Types

2) JSONDecoder

【讨论】:

好的,我明白了。但是由于这脱离了上下文,我不明白在哪里实现这个....在操场上运行并产生错误:“错误解码:dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:”给定数据不是有效的 JSON。”,基础错误:可选(错误域 = NSCocoaErrorDomain 代码 = 3840“JSON 文本未以数组或对象开头,并且允许未设置片段的选项。” UserInfo=NSDebugDescription=JSON 文本不以数组或开头允许未设置片段的对象和选项。)))" 使用您的实际 JSON 在实际项目中运行它。 嗨,所以我花了一个多小时来构建它,但无法让它工作。我尝试发布的构建代码被拒绝,因此无法显示。是否有其他实施建议以使这项工作发挥作用? NSCocoaErrorDomain Code=3840 是您迄今为止在此线程中发布的一个特定错误。您的 JSON 必须有一个***容器:***.com/questions/14171111/…

以上是关于在 Swift 中解析 JSON 24 小时的问题 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

解析单个 JSON 元素时遇到问题 (Swift)

在 SWIFT 4 中解析嵌套的 JSON

在 Swift 4 中使用 Decodable 解析 JSON

Swift 3 Alamofire Swifty json 解析问题

使用 Swift 3 解析 JSON

使用 Swift 解析 JSON