通过 PHP 将来自 MySQL 的 JSON 解码为 SwiftUI 中的复杂结构

Posted

技术标签:

【中文标题】通过 PHP 将来自 MySQL 的 JSON 解码为 SwiftUI 中的复杂结构【英文标题】:Decoding JSON coming from MySQL via PHP to a complex Struct in SwiftUI 【发布时间】:2021-12-31 13:24:27 【问题描述】:

我通过 phpmysql 数据库获得了这个 JSON 文件:

[
   
      "id":1,
      "partner":
         "id":1,
         "name":"Migros Bank",
         "image":"migrosbank"
      ,
      "name":"Testkonto 1",
      "type":"bank",
      "iban":"CH12 1234 1234 1234 1234 1",
      "datapoints":[
         
            "id":1,
            "depot_id":1,
            "date":"2021-12-28",
            "amount":5811.490234375
         ,
         
            "id":2,
            "depot_id":1,
            "date":"2021-12-29",
            "amount":7736.89013671875
         
      ]
   ,
   
      "id":2,
      "partner":
         "id":1,
         "name":"Migros Bank",
         "image":"migrosbank"
      ,
      "name":"Testkonto 2",
      "type":"bank",
      "iban":"CH12 1234 1234 1234 1234 2",
      "datapoints":[
         
            "id":3,
            "depot_id":2,
            "date":"2021-12-28",
            "amount":500
         ,
         
            "id":4,
            "depot_id":2,
            "date":"2021-12-29",
            "amount":1500
         
      ]
   
]

在 SwiftUI 中,我尝试将其解码为一个名为 Depot 的自定义结构,该结构由自定义结构 Partner 的一个实例和自定义结构 Depotstand 的一组实例组成:

import Foundation
import SwiftUI

struct Partner: Hashable, Codable, Identifiable 
    var id: Int
    var name: String
    var image: String
    
    var imageName: Image 
        Image(image)
    


struct Depotstand: Hashable, Codable, Identifiable 
    var id: Int
    var depot_id: Int
    var date: Date
    var amount: Double


struct Depot: Hashable, Codable, Identifiable 
    var id: Int
    var partner: Partner
    var name: String
    var type: String
    var iban: String
    var datapoints: [Depotstand]

我添加了一个数据模型,从我的网络服务器获取 JSON 数据 - 这部分工作正常 - 然后我尝试将数据解码到自定义结构 Depot,但失败(如果我简化,它可以工作将 JSON/struct 转换为仅简单的 Depot 结构,而不依赖于 Partner 和 Depotstand 实例):

import Foundation

final class ModelDataDepot: ObservableObject 
    @Published var depots = [Depot]()
    
    init()
        let url = URL(string: "https://api.webcoders.ch/index.php")!
        
        URLSession.shared.dataTask(with: url)  (data, response, error) in
            do 
                if let data = data 
                    let decodedData = try JSONDecoder().decode([Depot].self, from: data)
                    DispatchQueue.main.async 
                        self.depots = decodedData
                    
                 else 
                    print("No Data!")
                
             catch 
                print("JSON-Error: \(error)")
            
        .resume()
    

这是我得到的错误,主要包含数据类型错误,但我不知道如何解决这个问题:

JSON-Error: typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "datapoints", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "date", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))

我已经尝试了一些不同的数据转换,甚至使用 Numberformatters 等,但我无法让它工作......我还检查了 this article 关于将 JSON 数据转换为复杂的 swift 结构,但我无法解决我的问题。

感谢您帮助我!

P.s:我是 SwiftUI 和移动开发的绝对初学者...我的编码背景主要是 PHP、PowerShell 等,所以请耐心等待。 :-)

【问题讨论】:

var date: String 更改为Depotstand 正如@workingdog 所指出的,json 解码不支持日期。 SO上有一些关于这个的其他线程。 【参考方案1】:

你可以用var date: Date试试这个:

final class ModelDataDepot: ObservableObject 
    @Published var depots = [Depot]()

let dataDateFormat: DateFormatter = 
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter
()
    
    init()
        let url = URL(string: "https://api.webcoders.ch/index.php")!
        
        URLSession.shared.dataTask(with: url)  (data, response, error) in
            do 
                if let data = data 
                    let decoder = JSONDecoder()
                    decoder.dateDecodingStrategy = .formatted(self.dataDateFormat)  //<-- here
                    let decodedData = try decoder.decode([Depot].self, from: data)
                    DispatchQueue.main.async 
                        print("\n-----> decodedData: \(decodedData) \n")
                        self.depots = decodedData
                    
                 else 
                    print("No Data!")
                
             catch 
                print("JSON-Error: \(error)")
            
        .resume()
    


struct Depotstand: Hashable, Codable, Identifiable 
    var id: Int
    var depot_id: Int
    var date: Date  
    var amount: Double

【讨论】:

谢谢。不知道这种可能性。 @workingdog 非常感谢您的帮助!它现在工作正常。 :-)

以上是关于通过 PHP 将来自 MySQL 的 JSON 解码为 SwiftUI 中的复杂结构的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 编码的 PHP 变量传递给 HighCharts

MySQL 数据从 PHP 到带有 JSON 的 Javascript

使用 php 在 5 秒内将数据保存到 MySQL [关闭]

来自 php mysql 的 Highcharts 钻取 json

JSON解析:来自PHP5(攻击数据库:mySQL)ios5 iphone

来自 php 的 Google Table Chart 创建了 Json