Following the apple tutorial "Scrumdinger" app (https://developer.apple.com/tutorials/app-dev-training/creating-a-navigation-hierarchy) and receiving help from @Cheezzhead in my previous post (SwiftUI: Using ForEach to dynamically generate a List of array data within an array) I'm inches from the finish line. I have just one last hurdle to clear: in my PayRateView creating a list of NavigationLinks for each aircraft which links to their respective RateDetailViews.
Desired endstate:
Currently I've got two variations of the PayRateView code, each with their own insufficiencies.
VARIATION ONE:
struct PayRateView: View {
var fleet: Fleet
var body: some View {
List {
ForEach(fleet, id: \.fleetName) { plane in
NavigationLink(destination: RateDetailView(fleet: fleet)) {
Text(plane.fleetName)
}
}
}
Errors:
- Generic struct 'ForEach' requires that 'Fleet' conform to 'RandomAccessCollection'
- Key path value type '' cannot be converted to contextual type ''
- Unable to infer type of a closure parameter 'plane' in the current context
VARIATION TWO:
struct PayRateView: View {
var fleet: [Fleet]
var fleets: Fleet
var body: some View {
List {
ForEach(fleet, id: \.fleetName) { plane in
NavigationLink(destination: RateDetailView(fleet: fleets)) {
Text(plane.fleetName)
}
}
}
This variation does not have any errors but when I run the app in the simulator, the payrates: only the first aircraft payrates are shown on every iteration of each aircraft's RateDetailView. For example, when selecting the NavigationLink to view payrates for the A350, the PayRateDetail page shows B717 payrates. Only B717 payrates are shown for all the other aircraft payrate pages.
Here is my model data:
struct Fleet: Identifiable {
let id: UUID
var fleetName: String
var rates: [HourlyRates]
init(id: UUID = UUID(), fleetName: String, rates: [HourlyRates]) {
self.id = id
self.fleetName = fleetName
self.rates = rates
}
}
extension Fleet {
static let fleetList: [Fleet] = [
Fleet(fleetName: "B717", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo717[1], captHourlyRate: PayRates().capt717[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo717[2], captHourlyRate: PayRates().capt717[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo717[3], captHourlyRate: PayRates().capt717[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo717[4], captHourlyRate: PayRates().capt717[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo717[5], captHourlyRate: PayRates().capt717[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo717[6], captHourlyRate: PayRates().capt717[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo717[7], captHourlyRate: PayRates().capt717[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo717[8], captHourlyRate: PayRates().capt717[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo717[9], captHourlyRate: PayRates().capt717[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo717[10], captHourlyRate: PayRates().capt717[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo717[11], captHourlyRate: PayRates().capt717[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo717[12], captHourlyRate: PayRates().capt717[12])]),
Fleet(fleetName: "B737-7/8", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo738[1], captHourlyRate: PayRates().capt738[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo738[2], captHourlyRate: PayRates().capt738[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo738[3], captHourlyRate: PayRates().capt738[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo738[4], captHourlyRate: PayRates().capt738[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo738[5], captHourlyRate: PayRates().capt738[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo738[6], captHourlyRate: PayRates().capt738[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo738[7], captHourlyRate: PayRates().capt738[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo738[8], captHourlyRate: PayRates().capt738[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo738[9], captHourlyRate: PayRates().capt738[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo738[10], captHourlyRate: PayRates().capt738[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo738[11], captHourlyRate: PayRates().capt738[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo738[12], captHourlyRate: PayRates().capt738[12])]),
Fleet(fleetName: "B737-9", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo739[1], captHourlyRate: PayRates().capt739[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo739[2], captHourlyRate: PayRates().capt739[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo739[3], captHourlyRate: PayRates().capt739[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo739[4], captHourlyRate: PayRates().capt739[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo739[5], captHourlyRate: PayRates().capt739[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo739[6], captHourlyRate: PayRates().capt739[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo739[7], captHourlyRate: PayRates().capt739[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo739[8], captHourlyRate: PayRates().capt739[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo739[9], captHourlyRate: PayRates().capt739[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo739[10], captHourlyRate: PayRates().capt739[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo739[11], captHourlyRate: PayRates().capt739[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo739[12], captHourlyRate: PayRates().capt739[12])]),
Fleet(fleetName: "B757/767", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo739[1], captHourlyRate: PayRates().capt739[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo739[2], captHourlyRate: PayRates().capt739[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo739[3], captHourlyRate: PayRates().capt739[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo739[4], captHourlyRate: PayRates().capt739[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo739[5], captHourlyRate: PayRates().capt739[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo739[6], captHourlyRate: PayRates().capt739[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo739[7], captHourlyRate: PayRates().capt739[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo739[8], captHourlyRate: PayRates().capt739[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo739[9], captHourlyRate: PayRates().capt739[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo739[10], captHourlyRate: PayRates().capt739[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo739[11], captHourlyRate: PayRates().capt739[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo739[12], captHourlyRate: PayRates().capt739[12])]),
Fleet(fleetName: "B767-4", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo757[1], captHourlyRate: PayRates().capt757[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo757[2], captHourlyRate: PayRates().capt757[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo757[3], captHourlyRate: PayRates().capt757[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo757[4], captHourlyRate: PayRates().capt757[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo757[5], captHourlyRate: PayRates().capt757[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo757[6], captHourlyRate: PayRates().capt757[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo757[7], captHourlyRate: PayRates().capt757[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo757[8], captHourlyRate: PayRates().capt757[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo757[9], captHourlyRate: PayRates().capt757[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo757[10], captHourlyRate: PayRates().capt757[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo757[11], captHourlyRate: PayRates().capt757[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo757[12], captHourlyRate: PayRates().capt757[12])]),
Fleet(fleetName: "A220", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo220[1], captHourlyRate: PayRates().capt220[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo220[2], captHourlyRate: PayRates().capt220[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo220[3], captHourlyRate: PayRates().capt220[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo220[4], captHourlyRate: PayRates().capt220[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo220[5], captHourlyRate: PayRates().capt220[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo220[6], captHourlyRate: PayRates().capt220[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo220[7], captHourlyRate: PayRates().capt220[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo220[8], captHourlyRate: PayRates().capt220[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo220[9], captHourlyRate: PayRates().capt220[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo220[10], captHourlyRate: PayRates().capt220[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo220[11], captHourlyRate: PayRates().capt220[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo220[12], captHourlyRate: PayRates().capt220[12])]),
Fleet(fleetName: "A319/320", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo319[1], captHourlyRate: PayRates().capt319[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo319[2], captHourlyRate: PayRates().capt319[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo319[3], captHourlyRate: PayRates().capt319[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo319[4], captHourlyRate: PayRates().capt319[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo319[5], captHourlyRate: PayRates().capt319[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo319[6], captHourlyRate: PayRates().capt319[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo319[7], captHourlyRate: PayRates().capt319[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo319[8], captHourlyRate: PayRates().capt319[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo319[9], captHourlyRate: PayRates().capt319[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo319[10], captHourlyRate: PayRates().capt319[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo319[11], captHourlyRate: PayRates().capt319[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo319[12], captHourlyRate: PayRates().capt319[12])]),
Fleet(fleetName: "A321", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo321[1], captHourlyRate: PayRates().capt321[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo321[2], captHourlyRate: PayRates().capt321[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo321[3], captHourlyRate: PayRates().capt321[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo321[4], captHourlyRate: PayRates().capt321[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo321[5], captHourlyRate: PayRates().capt321[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo321[6], captHourlyRate: PayRates().capt321[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo321[7], captHourlyRate: PayRates().capt321[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo321[8], captHourlyRate: PayRates().capt321[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo321[9], captHourlyRate: PayRates().capt321[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo321[10], captHourlyRate: PayRates().capt321[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo321[11], captHourlyRate: PayRates().capt321[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo321[12], captHourlyRate: PayRates().capt321[12])]),
Fleet(fleetName: "A330-3", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo333[1], captHourlyRate: PayRates().capt333[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo333[2], captHourlyRate: PayRates().capt333[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo333[3], captHourlyRate: PayRates().capt333[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo333[4], captHourlyRate: PayRates().capt333[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo333[5], captHourlyRate: PayRates().capt333[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo333[6], captHourlyRate: PayRates().capt333[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo333[7], captHourlyRate: PayRates().capt333[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo333[8], captHourlyRate: PayRates().capt333[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo333[9], captHourlyRate: PayRates().capt333[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo333[10], captHourlyRate: PayRates().capt333[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo333[11], captHourlyRate: PayRates().capt333[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo333[12], captHourlyRate: PayRates().capt333[12])]),
Fleet(fleetName: "A330-9", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo339[1], captHourlyRate: PayRates().capt339[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo339[2], captHourlyRate: PayRates().capt339[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo339[3], captHourlyRate: PayRates().capt339[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo339[4], captHourlyRate: PayRates().capt339[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo339[5], captHourlyRate: PayRates().capt339[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo339[6], captHourlyRate: PayRates().capt339[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo339[7], captHourlyRate: PayRates().capt339[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo339[8], captHourlyRate: PayRates().capt339[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo339[9], captHourlyRate: PayRates().capt339[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo339[10], captHourlyRate: PayRates().capt339[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo339[11], captHourlyRate: PayRates().capt339[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo339[12], captHourlyRate: PayRates().capt339[12])]),
Fleet(fleetName: "A350", rates: [
HourlyRates(year: 1, foHourlyRate: PayRates().fo350[1], captHourlyRate: PayRates().capt350[1]),
HourlyRates(year: 2, foHourlyRate: PayRates().fo350[2], captHourlyRate: PayRates().capt350[2]),
HourlyRates(year: 3, foHourlyRate: PayRates().fo350[3], captHourlyRate: PayRates().capt350[3]),
HourlyRates(year: 4, foHourlyRate: PayRates().fo350[4], captHourlyRate: PayRates().capt350[4]),
HourlyRates(year: 5, foHourlyRate: PayRates().fo350[5], captHourlyRate: PayRates().capt350[5]),
HourlyRates(year: 6, foHourlyRate: PayRates().fo350[6], captHourlyRate: PayRates().capt350[6]),
HourlyRates(year: 7, foHourlyRate: PayRates().fo350[7], captHourlyRate: PayRates().capt350[7]),
HourlyRates(year: 8, foHourlyRate: PayRates().fo350[8], captHourlyRate: PayRates().capt350[8]),
HourlyRates(year: 9, foHourlyRate: PayRates().fo350[9], captHourlyRate: PayRates().capt350[9]),
HourlyRates(year: 10, foHourlyRate: PayRates().fo350[10], captHourlyRate: PayRates().capt350[10]),
HourlyRates(year: 11, foHourlyRate: PayRates().fo350[11], captHourlyRate: PayRates().capt350[11]),
HourlyRates(year: 12, foHourlyRate: PayRates().fo350[12], captHourlyRate: PayRates().capt350[12])]),
]
}
struct HourlyRates: Identifiable {
let id: UUID
var year: Int
var foHourlyRate: Double
var captHourlyRate: Double
init(id: UUID = UUID(), year: Int, foHourlyRate: Double, captHourlyRate: Double) {
self.id = id
self.year = year
self.foHourlyRate = foHourlyRate
self.captHourlyRate = captHourlyRate
}
}
Here is my PayRateDetailView:
struct RateDetailView: View {
var fleet: Fleet
var body: some View {
List {
ForEach (fleet.rates) { line in
RateCardView(fleet: fleet)
}
}
.navigationTitle(fleet.fleetName)
}
}
Here is my RateCardView:
struct RateCardView: View {
var fleet: Fleet
var body: some View {
ForEach(fleet.rates) { rate in
HStack {
Text("Year \(rate.year)")
Spacer()
Text("$ \(rate.foHourlyRate, specifier: "%.2f")")
Spacer()
Text("$ \(rate.captHourlyRate, specifier: "%.2f")")
}
}
}
}
VARIATION THREE:
With a slight change, there is also a third variation which produces one error...
Error: Cannot convert value of type '[Fleet]' to expected argument type 'Fleet'
Thank you so much for your help!!



ForEachis for things like arrays (aka random access collection)Fleetisn't it would would with[Fleet]but not a single item. It would probably be less confusing if you decide on a standard plural name and a singular name likefleet : [Fleet]andfleetObj : FleetyouPayRateViewwould uselet fleet : [Fleet]instead ofvar fleet: Fleet