I'm having a difficult time trying to figure out how to ForEach loop some array's of array's of json data in SwiftUI. I used https://app.quicktype.io to get my data struct from this URL here.
I'm looking to get classes FeaturedHeaderView and FeaturedPackageView, which have title's of "Hot Right Now" and "What We're Using" which also contain the FeaturedPackageView data. My problem is I'm only looping through the first FeaturedHeaderView and FeaturedPackageView repeatedly, which I assumed there was two for each section. Is my data struct incorrect? I've never attempted complex json data yet, so I'm unsure how to handle it properly and if the ForEach loop is what I'm looking for. The end goal would be to have a List with `"Hot Right Now" and it's items and then then "What We're Using" and it's items.
I was able to get the FeaturedBannersView class just fine using two ForEach loops and thought it would be the same approach for the rest of the data?
The banner view working
ScrollView(.horizontal) {
HStack {
ForEach(self.welcome.views, id: \.viewClass) { views in
ForEach(views.banners ?? [], id:\.url) { banner in
ZStack (alignment: .bottomLeading) {
GeometryReader { geometry in
RequestImage(Url(banner.url), animation: nil)
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width)
.clipped()
.cornerRadius(CGFloat(views.itemCornerRadius ?? 0))
}
HStack {
Text(banner.title ?? "")
.fontWeight(.bold)
.font(.title3)
.foregroundColor(Color.white)
}
.padding(.all, 15)
}
.frame(width: 263, height: 148)
}
}
}
.padding(.leading, 10)
.padding(.trailing, 10)
}
The issue
My data struct
struct Welcome: Codable {
let views: [WelcomeView]
}
struct WelcomeView: Codable {
let viewClass: String?
let banners: [Banner]?
let views: [PurpleView]?
enum CodingKeys: String, CodingKey {
case viewClass = "class"
case views
}
}
struct Banner: Codable {
let url: String?
let title, package, repoName: String?
}
struct PurpleView: Codable {
let viewClass: String?
let views: [FluffyView]
enum CodingKeys: String, CodingKey {
case viewClass = "class"
case views
}
}
struct FluffyView: Codable {
let viewClass: String?
let title: String?
let package, packageName, packageAuthor: String?
let repoName: RepoName?
let packageIcon: String?
enum CodingKeys: String, CodingKey {
case viewClass = "class"
case title, package, packageName, packageAuthor, repoName, packageIcon
}
}
enum RepoName: String, Codable {
case chariz = "Chariz"
case packix = "Packix"
}
List {
ForEach(self.welcome.views, id: \.viewClass) { view in
ForEach(view.views ?? [], id: \.viewClass) { purple in
ForEach(purple.views, id: \.packageName) { fluffy in
if fluffy.viewClass == "FeaturedHeaderView" {
Text(fluffy.title ?? "")
.font(.title3)
.fontWeight(.bold)
} else {
HStack (spacing: 15){
RequestImage(Url(fluffy.packageIcon ?? ""), animation: nil)
.aspectRatio(contentMode: .fit)
.frame(width: 60, height: 60)
.clipped()
.cornerRadius(13.5)
VStack (alignment: .leading){
Text(fluffy.packageName ?? "")
.font(.body)
Text(fluffy.packageAuthor ?? "")
.foregroundColor(Color.secondary)
.font(.callout)
Text(fluffy.repoName?.rawValue ?? "")
.foregroundColor(Color.secondary)
.font(.subheadline)
}
}
}
}
}
}
}
.onAppear() {
request()
}

