TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

SOLVED: Project 8 - Day 40 - Formatting our mission view – Moonshot SwiftUI Tutorial 8/11 - Fatal error: Failed to decode missions.json from bundle.

Forums > 100 Days of SwiftUI


I am getting this error:

Moonshot/Bundle-Decodable.swift:24: Fatal error: Failed to decode missions.json from bundle.
2022-12-14 16:32:30.116683-0800 Moonshot[32049:1148957] Moonshot/Bundle-Decodable.swift:24: Fatal error: Failed to decode missions.json from bundle.

This is after getting to about 5:00 into : where we first setup the view.

I compared my Mission.swift / Bundle-Decodable.swift / and other files to the github code but didnt see anything obvious.

I am guessing that since it is getting the url and loading the data there is some error in my Mission struct? or Bundle-Decodable file. But am not really sure how to track this down.

Is there a way I can view this error in more detail to see what is causing a decoding error?


import Foundation

struct Mission: Codable, Identifiable {
    struct CrewRole: Codable {
        let name: String
        let roll: String

    let id: Int
    let launchDate: String?
    let crew: [CrewRole]
    let description: String

    var displayName: String {
        "Apollo \(id)"

    var image: String {

import Foundation

extension Bundle {
    func decode<T: Codable>(_ file: String) -> T {

        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate \(file) in bundle.")

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")

        let decoder = JSONDecoder()

        guard let loaded = try? decoder.decode(T.self, from: data) else {
            fatalError("Failed to decode \(file) from bundle.")

        return loaded
import SwiftUI

struct ContentView: View {
    let astronauts: [String: Astronaut] = Bundle.main.decode("astronauts.json")

    let missions: [Mission] = Bundle.main.decode("missions.json")

    let columns = [
        GridItem(.adaptive(minimum: 150))

    var body: some View {
        NavigationView {
            ScrollView {
                LazyVGrid(columns: columns ) {
                    ForEach(missions) { mission in
                        NavigationLink {
                            Text("Detail view")
                        } label: {
                            VStack {
                                    .frame(width: 100, height: 100)

                                VStack {

                                    Text(mission.launchDate ?? "N/A")
                                .frame(maxWidth: .infinity)


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {


let roll: String

Are you sure this shouldn't be role?





Thank you! I knew it would be something like that!


Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

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.