如何在swift中将json数据解析为动态集合视图节和单元格
这是我发出网络请求后从邮递员那里得到的json响应如何在swift中将json数据解析为动态集合视图节和单元格,json,swift,sorting,dictionary,uicollectionview,Json,Swift,Sorting,Dictionary,Uicollectionview,这是我发出网络请求后从邮递员那里得到的json响应 [ { "employeeName": "Find a Sub ", "startDate": "2020-02-25", "startTime": "09:00:00", "endTime": "16:00:00" }, { "employeeName": "Find a Sub ", "startDate": "20
[
{
"employeeName": "Find a Sub ",
"startDate": "2020-02-25",
"startTime": "09:00:00",
"endTime": "16:00:00"
},
{
"employeeName": "Find a Sub ",
"startDate": "2020-02-25",
"startTime": "09:00:00",
"endTime": "16:00:00"
},
{
"employeeName": "Find a Sub ",
"startDate": "2020-02-25",
"startTime": "09:00:00",
"endTime": "16:00:00"
},
{
"employeeName": "Find a Sub ",
"startDate": "2020-02-24",
"startTime": "09:00:00",
"endTime": "16:00:00"
},
{
"employeeName": "Find a Sub ",
"startDate": "2020-02-24",
"startTime": "09:00:00",
"endTime": "16:00:00"
}]
这是我解析json数据的模型结构
struct jobsData:Decodable
{
let employeeName:String?
let startTime:String?
let endTime:String?
var startDate:String?
init(employeeName:String?=nil,
startTime:String?=nil,
endTime:String?=nil,
startDate:String?=nil){
self.employeeName=employeeName
self.startTime=startTime
self.endTime=endTime
self.startDate=startDate
}}
我使用json解码器来解码urlSession请求之后的数据
现在,我需要以这样一种方式操纵响应:uicollectionview的节数将是startDate,其标题文本将是其文本,例如,在上述情况下,uicollectionview将有两个节。每个部分的项目将是json响应中与该日期对应的对象的数量,就像上面的情况一样,在日期为2020-02-25的部分中有三个项目,在日期为2020-02-24的部分中有两个项目。我遇到的问题是,我不知道每个部分的节数和项数,因为数据是来自api的动态数据。我如何操作json响应以将它们附加到uicollectionview中,如我所述。
这个链接很有用,但我不知道如何对数据进行排序,因为在上面的链接中只有两个键,一个用于排序,另一个用于collectionview数据,但我有多个键
编辑:
这是我的collectionview数据源函数。如何在不同部分显示数据
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)as! AvailableJobsCell
let sTime=self.timeInAmPm(String: UserInformation[indexPath.item].startTime!)
let eTime=self.timeInAmPm(String: UserInformation[indexPath.item].endTime!)
cell.jobAddedTime.text="\(sTime) - \(eTime)"
cell.jobTitle.text=UserInformation[indexPath.item].employeeName!
cell.schoolName.text="\(UserInformation[indexPath.item].organizationName ?? "")\n\(UserInformation[indexPath.item].organizationAddress ?? "")"
cell.jobNo.text=UserInformation[indexPath.item].confirmationNumber!
cell.personOnHiatus.text=UserInformation[indexPath.item].positionDescription!
cell.index=indexPath
cell.delegate=self
return cell
}
UserInformation的类型为[JobsData]首先,使用大写名称声明结构,使用非可选成员,并且不使用
init
方法
struct JobsData : Decodable
{
let employeeName : String
let startTime : String
let endTime : String
var startDate : String
}
要对数据进行分组,请声明一个节结构
struct Section
{
let title : String
let jobsData : [JobsData]
}
并声明数据源数组
var sections = [Section]()
在解码数组之后
let jobsDataArray = try JSONDecoder().decode([JobsData].self, from: data)
使用字典(分组:按:)
,将其映射到节
数组,并对其进行排序
let grouped = Dictionary(grouping: jobsDataArray, by: {$0.startDate})
self.sections = grouped.map{Section(title: $0.key, jobsData: $0.value)}
.sorted{$0.title < $1.title}
要显示节,请实现数据源方法
override func numberOfSections(in collectionView: UICollectionView) -> Int
return sections.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return sections[section].jobsData.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! AvailableJobsCell
let jobData = sections[indexPath.section].jobsData[indexPath.item]
let sTime = self.timeInAmPm(String: jobData.startTime)
let eTime = self.timeInAmPm(String: jobData.endTime)
cell.jobAddedTime.text = "\(sTime) - \(eTime)"
cell.jobTitle.text = jobData.employeeName
cell.schoolName.text = "\(jobData.organizationName ?? "")\n\(jobData.organizationAddress ?? "")"
cell.jobNo.text = jobData.confirmationNumber!
cell.personOnHiatus.text = jobData.positionDescription!
cell.index = indexPath
cell.delegate = self
return cell
}
我使用的是swift 5.2和Xcode 11I,当我试图声明节结构“使用未声明的类型‘JobsData’”时,出现了一个错误。如何解决此问题正如我所说,请按照答案中的建议,以大写字母开头声明结构JobsData
。感谢您的帮助。我已经编辑了我的问题。现在,我如何使用部分中的数据在uicollectionview的不同部分中显示它。我在上面添加了uicollectionview数据源函数,请参见更新。请遵守命名惯例。变量、函数、属性、枚举大小写和参数标签以小写字母开头。结构、类、枚举以大写字母开头。非常感谢。成功了。你能给我推荐一些网站或书籍,介绍我如何改进这些缺点,比如解析json和根据需要更改json,以及如何使数据源函数动态化。
override func numberOfSections(in collectionView: UICollectionView) -> Int
return sections.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return sections[section].jobsData.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! AvailableJobsCell
let jobData = sections[indexPath.section].jobsData[indexPath.item]
let sTime = self.timeInAmPm(String: jobData.startTime)
let eTime = self.timeInAmPm(String: jobData.endTime)
cell.jobAddedTime.text = "\(sTime) - \(eTime)"
cell.jobTitle.text = jobData.employeeName
cell.schoolName.text = "\(jobData.organizationName ?? "")\n\(jobData.organizationAddress ?? "")"
cell.jobNo.text = jobData.confirmationNumber!
cell.personOnHiatus.text = jobData.positionDescription!
cell.index = indexPath
cell.delegate = self
return cell
}