在Swift 4中解析NiceHash JSON

在Swift 4中解析NiceHash JSON

问题描述:

我正在开发一个应用程序来从NiceHash API获取一个余额。我必须使用的JSON如下所示:在Swift 4中解析NiceHash 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" 
} 

我想总结“balance”的所有值,但我不确定如何访问它。我的代码现在看起来是这样的:

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,我猜这个代码只是垃圾。

+1

这是Swift的命名约定,以大写字母开头来命名您的结构。顺便说一句,你应该使用URLSession异步下载你的json数据 –

+1

你正在使用错误类型的算法属性它应该是一个Int而不是一个字符串。 –

+0

您应该添加名称为“Response”的结构,并且此结构必须包含您的“结果”结构的属性。最后使用jsonDecoder.decode(Response.self,来自jsonData)解析“Response”结构而不是jsonDecoder.decode(来自jsonData的Array .self) – Malder

有很多问题。

首先为了避免混淆名称结构总是大写。然而,你的stats结构包含更多的混淆,而不仅仅是命名。

看看JSON结构。有

  • 词典与字典用于密钥result

    struct Root : Decodable { 
        let 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) 
} 

注意的总和

切勿从远程URL以Data(contentsOf同步加载数据。您将阻止当前线程,并且如果发生错误,应用程序将可靠地崩溃。使用异步API,如URLSession/URLSessionDataTask,并添加适当的错误处理。

+0

为什么不使用Codable? –

+2

看来,对象将永远不会** en **编码。 – vadian

+0

无论如何Codable也可以在这里工作 –