UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Project 8 - Cant get the 2nd Challenge Question

Forums > 100 Days of SwiftUI

Have rewatched the video, but a little fuzzy how we are implementing this first(where) method. Any help would be awesome!

import SwiftUI

struct AstronautView: View {
    struct AstronautMission {
        let mission: Mission
    }

    let astronaut: Astronaut
    let missions: [AstronautMission]

    init(astronaut: Astronaut, missions: [Mission]) {
        self.astronaut = astronaut

        var matches = [AstronautMission]()

        for name in astronaut.id {
            if let match = missions.first(where: { $0.crew[name] == name }) {
                matches.append(AstronautMission(mission: match))
            } else {
                fatalError("Missing \(name)")
            }
        }

        self.missions = matches
    }

    var body: some View {

        GeometryReader { geo in
            ScrollView(.vertical) {
                VStack {
                    Image(astronaut.id)
                        .resizable()
                        .scaledToFit()
                        .frame(width: geo.size.width)

                    Text(astronaut.description)
                        .padding()
                        .layoutPriority(1) // will decide priority and shrink or grow depending..flexbox
                }
            }
        }
        .navigationBarTitle(Text(astronaut.name), displayMode: .inline)
    }
}

2      

This was a bit confusing for me to figure out at first, but It actually ends up being less complex than the way that we used it in the MissionView for two reasons.

The first reason is that we do not want to cause a FatalError in our program every time that we look at a Mission that our current Astronaut was not a crew member on. In the MissionView, it would have been a problem if an Astronaut was listed as a crew member on the Mission, but then we found that that Astronaut didn't exist at all. But it is perfectly fine for a Mission to exist that our particular Astronaut was not a crew member on.

The second reason is that we do not need to assign the result of calling the first(where:) function to a constant, because we are already working with the exact type of thing that we are trying to add to our matches array in this case. (a Mission) Whereas, in the MissionView we needed to take the return value of type Astronaut and convert it into a CrewMember to add to our matches array. If you do try to create a constant for the return value in this case, the compiler will tell you that the constant you created was never used.

So, this is what it looked like in MissionView...

for crewMember in mission.crew {
            if let match = astronauts.first(where: {$0.id == crewMember.name}) {
                matches.append(CrewMember(role: crewMember.role, astronaut: match))
            } else {
                fatalError("Missing \(crewMember)")
            }
}

But now all we have to do is find out if there is a match, and if there is, add it directly to our array of matches. If there is no match, that is perfectly fine, and we can just do nothing further.

So, this is what I ended up with in AstronautView...

for mission in missions {
            if mission.crew.first(where: {$0.name == astronaut.id}) != nil {
                matches.append(mission)
            }
} 

Basically, it says this:

  1. Go through each Mission instance in the missions array.

  2. Look at the crew property ( [CrewRole] ) of the current Mission that we are looking at from the missions array.

  3. Find the first CrewRole in that array where the CrewRole.name matches the Astronaut.id property of the Astronaut that we are currently trying to create a View for. (if there is one)

  4. If we find a match (!= nil), then that means that this astronaut was a crew member of the current Mission that we are looking at, and we should add this Mission to our matches array.

  5. If we did not find a match, then we don't need to do anything further with this Mission, and can move on to checking the next Mission.

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.