In the Merging Codable structs video Paul
adds this code to the MissionView view:
struct CrewMember {
let role: String
let astronaut: Astronaut
}
let crew: [CrewMember]
and this custom initializer:
init(mission: Mission, astronauts: [String: Astronaut]) {
self.mission = mission
self.crew = mission.crew.map { member in
if let astronaut = astronauts[member.name] {
return CrewMember(role: member.role, astronaut: astronaut)
} else {
fatalError("Missing \(member.name)")
}
}
}
I'm confused why we need to do all that when adding this to MissionView:
let astronaut: [String: Astronaut]
and passing astronauts from ContentView
NavigationLink {
MissionView(mission: mission, astronaut: astronauts)
}
gives us access to the same information in MissionView:
ForEach(mission.crew, id: \.self) { crewMember in
VStack {
Text(crewMember.name)
Text(crewMember.role)
Image(astronaut[crewMember.name, default: Astronaut(id: "Error", name: "Error", description: "Error")].id)
}
}
my full version of MissionView:
struct MissionView: View {
let mission: Mission
let astronaut: [String: Astronaut]
var body: some View {
GeometryReader { geometry in
ScrollView {
VStack {
Image(mission.image)
.resizable()
.scaledToFit()
.frame(maxWidth: geometry.size.width * 0.6)
.padding(.top)
VStack(alignment: .leading) {
Text("Mission Highlights")
.font(.title.bold())
.padding(.bottom, 5)
Text(mission.description)
}
.padding(.horizontal)
}
.padding(.bottom)
ScrollView(.horizontal) {
HStack {
ForEach(mission.crew, id: \.self) { crewMember in
VStack {
Text(crewMember.name)
Text(crewMember.role)
Image(astronaut[crewMember.name, default: Astronaut(id: "Error", name: "Error", description: "Error")].id)
}
}
}
}
}
.navigationTitle(mission.displayName)
.navigationBarTitleDisplayMode(.inline)
.background(.darkBackground)
}
}
}