从 JSON 数据中对 UItableview 中的排序和部分进行排序

Posted

技术标签:

【中文标题】从 JSON 数据中对 UItableview 中的排序和部分进行排序【英文标题】:Sorting & section in UItableview from JSON data 【发布时间】:2019-05-01 11:15:26 【问题描述】:

我已经定义了包数据的数据模型,但是需要在此基础上定义UITableviewsections

subscriptiontype = '每年'、'每月'、'每周'

出现错误 - 无法将类型“[Package]”的值分配给类型“[[String : String]]?”。如何将其分配给 tableview 部分。

代码:

var packag = [Package]()
enum TableSection: Int 
    case subscriptionType = 0, yearly, monthly, weekly, total

var data = [TableSection: [[String: String]]]()

func sortData() 
    data[.yearly] = packag.filter( $0.subscriptionType == "yearly" )
    data[.monthly] = packag.filter( $0.subscriptionType == "monthly" )
    data[.weekly] = packag.filter( $0.subscriptionType == "weekly" )


更新代码 - viewdidload():

override func viewDidLoad() 
    super.viewDidLoad()
    tableview.dataSource = self
    tableview.delegate = self


    //fetchData()
    if let path = Bundle.main.path(forResource: "packageList", ofType: "json") 
        do 
            let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)

            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .custom decoder -> Date in
                let container = try decoder.singleValueContainer()
                let dateStr = try container.decode(String.self)
                return Date(timeIntervalSince1970: TimeInterval(dateStr)!)
            
            let jSON = try? decoder.decode(Root.self, from: data)

            if let packages = jSON?.packages 
                self.sortData(packages: packages)
                print(packages)

            
         catch 
            // handle error
            print(Error.self)
        
    


根模型:

struct Root : Codable 

    let packages : [Package]

包模型:

struct Package : Codable 

    let availableUntil : Date
    let benefits : [String]?
    let desc : String
    let didUseBefore : Bool
    let name : String
    let price : Double
    let subscriptionType : String
    let tariff : Tariff

Triff 模型:

struct Tariff : Codable 

    let data : String
    let sms : String
    let talk : String

更新的 PackageJson 数据:

 "packages": [

  "name": "Platinum Maksi 6 GB",
  "desc": "Zengin içerikli Platinum Maksi Paketi ile Turkcell Uygulamalarının keyfini sürün!",
  "subscriptionType": "monthly",
  "didUseBefore": true,
  "benefits": [
    "TV+",
    "Fizy",
    "BiP",
    "lifebox",
    "Platinum",
    "Dergilik"
  ],
  "price": 109.90,
  "tariff": 
    "data": "6144",
    "talk": "2000",
    "sms": "100"
  ,
  "availableUntil": "1558131150"
,

  "name": "Platinum Maksi 8 GB",
  "desc": "Zengin içerikli Platinum Maksi Paketi ile Turkcell Uygulamalarının keyfini sürün!",
  "subscriptionType": "monthly",
  "didUseBefore": false,
  "benefits": [
    "TV+",
    "Fizy",
    "BiP",
    "lifebox",
    "Platinum",
    "Dergilik"
  ],
  "price": 129.90,
  "tariff": 
    "data": "8192",
    "talk": "2000",
    "sms": "100"
  ,
  "availableUntil": "1555060350"
,

  "name": "Platinum Maksi 12 GB",
  "desc": "Zengin içerikli Platinum Maksi Paketi ile Turkcell Uygulamalarının keyfini sürün!",
  "subscriptionType": "yearly",
  "didUseBefore": false,
  "benefits": [
    "TV+",
    "Fizy",
    "BiP",
    "lifebox",
    "Platinum",
    "Dergilik"
  ],
  "price": 109.90,
  "tariff": 
    "data": "12288",
    "talk": "2000",
    "sms": "100"
  ,
  "availableUntil": "1555060350"
,

【问题讨论】:

【参考方案1】:

问题是您试图将 Package 对象分配给期望字典数组的值。

您的data 变量是一个字典,其中有一个TableSection 作为键,一个字典数组作为您通过编写[[String: String]] 定义的值。然后在您的 sortData 函数中,您尝试为各种数据键分配一个值,但是当它需要一个字典数组时,您正在为其分配一个 Package 项。

如果您将数据定义更改为

var data = [TableSection: Package]()

【讨论】:

谢谢。真的很感激。【参考方案2】:

型号

    import Foundation

    struct JSON: Codable 
        let packages: [Package]
    

    struct Package: Codable 
        let name, desc, subscriptionType: String
        let didUseBefore: Bool
        let benefits: [String]
        let price: Double
        let tariff: Tariff
        let availableUntil: String
    

    struct Tariff: Codable 
        let data, talk, sms: String
    

枚举

enum TableSection: Int 
    case subscriptionType = 0, yearly, monthly, weekly, total

数据

var data = [TableSection: [Package]]()

解析

    if let path = Bundle.main.path(forResource: "document", ofType: "json") 
        do 
            let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
            let jSON = try? JSONDecoder().decode(JSON.self, from: data)

            if let packages = jSON?.packages 
                self.sortData(packages: packages)
            
         catch 
            // handle error
        
    

排序

private func sortData(packages : [Package]) 
    data[.yearly] = packages.filter( $0.subscriptionType == "yearly" )
    data[.monthly] = packages.filter( $0.subscriptionType == "monthly" )
    data[.weekly] = packages.filter( $0.subscriptionType == "weekly" )

    print("Data is \(data)")

我使用 LOCAL JSON,你可以使用服务器数据。

【讨论】:

感谢您让我应用更改并让您知道。顺便说一句,我也使用本地文件临时基础。 当然。我在这里,以防你得到任何帮助。谢谢。 我已经实现了代码但没有显示。所有模型都是完美的(Root、Package、Traiff)。我已经设置了断点,但是一个解析函数是 fetchData 和 Sort Data 给我这个 [Packages.PackagesViewController.TableSection.weekly: [] Packages.PackagesViewController.TableSection.yearly: [], Packages.PackagesViewController.TableSection.monthly: []] 我认为我做错了什么,即使简单的 fetchData 没有调用。 override func viewDidLoad() super.viewDidLoad() tableview.dataSource = self tableview.delegate = self fetchData() self.sortData(packages: packag) fetchData 是本地的还是基于服务器 api 的?

以上是关于从 JSON 数据中对 UItableview 中的排序和部分进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何从json获取数据中对两个或多个值求和

从 JSON 解析数据直接到 UITableView

从 JSON 数据填充 UITableView

使用 JSON 数据填充 UITableView

从具有 id 的 UItableview 单元格中获取数据

在 UITableView 中对核心数据多对关系进行排序