【问题标题】:Parse NiceHash JSON in Swift 4在 Swift 4 中解析 NiceHash JSON
【发布时间】:2017-11-25 19:01:34
【问题描述】:

我正在开发一个应用程序来从 NiceHash api 中获得平衡。我必须使用的 JSON 如下所示:

{
   "result":{
      "stats":[
         {
            "balance":"0.00000124",
            "rejected_speed":"0",
            "algo":5,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00000163",
            "rejected_speed":"0",
            "algo":7,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00114271",
            "rejected_speed":"0",
            "algo":8,
            "accepted_speed":"0.0002237"
         },
         {
            "balance":"0.00009395",
            "rejected_speed":"0",
            "algo":14,
            "accepted_speed":"0"
         },
         {
            "balance":"0.0000097",
            "rejected_speed":"0",
            "algo":20,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00000004",
            "rejected_speed":"0",
            "algo":21,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00128791",
            "rejected_speed":"0",
            "algo":22,
            "accepted_speed":"0"
         },
         {
            "balance":"0.0000005",
            "rejected_speed":"0",
            "algo":23,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00310707",
            "rejected_speed":"0",
            "algo":24,
            "accepted_speed":"0.0000002"
         },
         {
            "balance":"0.00002411",
            "rejected_speed":"0",
            "algo":26,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00000007",
            "rejected_speed":"0",
            "algo":27,
            "accepted_speed":"0"
         },
         {
            "balance":"0.0000047",
            "rejected_speed":"0",
            "algo":28,
            "accepted_speed":"0"
         },
         {
            "balance":"0.00001291",
            "rejected_speed":"0",
            "algo":29,
            "accepted_speed":"0"
         }
      ],
      "payments":[

      ],
      "addr":"some_bitcoin_adress"
   },
   "method":"stats.provider"
}

我想对“余额”的所有值求和,但我不知道如何访问它。我现在的代码如下所示:

struct stats: Codable {
    let balance: String
    let rejected_speed: String
    let algo: String
    let accepted_speed: String
}
struct result: stats {
    let stats: stats
}

以及获取 JSON 的函数:

func updateBalance() {
    let sampleDataAdress = "nicehash_link_here"
    let url URL(string: sampleDataAdress)!
    let jsonSata = try! Data(contentsOf: url)
    let jsonDecoder = JSONDecoder()
    let data = try? jsonDecoder.decode(Array<stats>.self, from jsonData)
    data?.count
    dump(data?.first)
}

我希望我至少能获得第一个统计数据,但我却得到了零。这是我第一次在 Swift 4 中做 JSON,我猜这段代码就是垃圾。

【问题讨论】:

  • Swift 命名约定以大写字母开头的结构命名。顺便说一句,您应该使用 URLSession 异步下载您的 json 数据
  • 您为算法属性使用了错误的类型,它应该是 Int 而不是 String。
  • 您应该添加结构,其名称例如为“响应”,并且该结构必须包含您的“结果”结构的属性。最后使用 jsonDecoder.decode(Response.self, from jsonData) 而不是 jsonDecoder.decode(Array.self, from jsonData) 解析“响应”结构
  • 不要用try? 忽略抛出的错误,而是在do-catch 块中使用try 并打印抛出的错误。它会准确地告诉你问题是什么。

标签: json swift swift4


【解决方案1】:

有很多问题。

首先要避免混淆名称结构总是大写的。但是,您的 stats 结构包含的不仅仅是命名更多的混乱。 ?

查看 JSON 结构。有

  • 一个 root 字典,其中包含一个关键字字典 result

    struct Root : Decodable {
        let result : Result
    }
    
  • result 字典,其中包含键 stats 的数组

    struct Result: Decodable {
        let stats: [Stats]
    
        var sumOfBalances : Double {
            return stats.flatMap{ Double($0.balance) }.reduce(0.0, +)
        }
    }
    
  • 统计数据数组

    struct Stats: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case balance, rejectedSpeed = "rejected_speed", algo, acceptedSpeed = "accepted_speed"
        }
    
        let balance: String
        let rejectedSpeed: String
        let algo: Int
        let acceptedSpeed: String
    }
    

key 的值也是Int(没有双引号),而不是String

现在解码对象并获取余额总和

do {
    let root = try jsonDecoder.decode(Root.self, from jsonData)
    print(root.result.sumOfBalances)
} catch {
    print(error)
}

注意

永远不要从带有Data(contentsOf 的远程 URL 同步加载数据。如果发生错误,您将阻塞当前线程,并且应用程序将可靠地崩溃。使用像 URLSession / URLSessionDataTask 这样的异步 API 并添加适当的错误处理。

【讨论】:

  • 为什么不能编码?
  • 对象似乎永远不会被en编码。
  • 您还可以将计算属性添加到 Result var sum: Double { return stats.flatMap{Double($0.balance)}.reduce(0,+) }
  • 类似的? .0 不需要
  • @LeoDabus 我知道,但我总是使用正确的文字类型以提高可读性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 2018-08-06
  • 2018-10-21
相关资源
最近更新 更多