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

Bookworm challenge 3

Forums > 100 Days of SwiftUI

Hi i added Date but when i add new book - the app crashes. :/

There is something missing in my Book class?

import Foundation
import SwiftData

@Model
class Book {

    var title: String
    var author: String
    var genre: String
    var review: String
    var rating: Int
    var date: Date

    init(title: String, author: String, genre: String, review: String, rating: Int, date: Date) {
        self.title = title
        self.author = author
        self.genre = genre
        self.review = review
        self.rating = rating
        self.date = date
    }

}
//
//  AddBookView.swift
//  Bookworm
//
//  Created by Filip Pokłosiewicz on 30/11/2023.
//

import SwiftUI

struct AddBookView: View {
    @Environment(\.modelContext) var modelContext
    @Environment(\.dismiss) var dismiss

    @State private var title = ""
    @State private var author = ""
    @State private var rating = 3
    @State private var genre = "Fantasy"
    @State private var review = ""
    @State private var date = Date.now

    let genres = ["Fantasy", "Horror", "Kids", "Mystery", "Poetry", "Romance", "Thriller" ]

    var hasValidField: Bool {
        if title.isEmpty || author.isEmpty || genre.isEmpty {
            return false
        } else if title.hasPrefix(" ") || author.hasPrefix(" ") || genre.hasPrefix(" ") {
            return false
        }
        return true
    }

    var body: some View {
        NavigationStack {
            Form {
                Section {
                    TextField("Name of book", text: $title)
                    TextField("Author", text: $author)

                    Picker("Genre", selection: $genre) {
                        ForEach(genres, id: \.self) {
                            Text($0)
                        }
                    }

                }

                Section("Write a review") {
                    TextEditor(text: $review)

                    RatingView(rating: $rating)
                }

                Section{
                    Button("Save") {
                        let newBook = Book(title: title, author: author, genre: genre, review: review, rating: rating, date: date)
                        modelContext.insert(newBook)
                        dismiss()
                    }
                }
                .disabled(hasValidField == false)
            }.navigationTitle("Add book")
        }
    }
}
//
//  DetailView.swift
//  Bookworm
//
//  Created by Filip Pokłosiewicz on 05/12/2023.
//

import SwiftData
import SwiftUI

struct DetailView: View {
    @Environment(\.modelContext) var modelContext
    @Environment(\.dismiss) var dismiss
    @State private var showingDeleteAlert = false
    @State private var date = Date.now

    let book: Book

    var body: some View {

        ScrollView {
            ZStack(alignment: .bottomTrailing) {
                Image(book.genre)
                    .resizable()
                    .scaledToFit()

                Text(book.genre.uppercased())
                    .fontWeight(.black)
                    .padding(8)
                    .foregroundStyle(.white)
                    .background(.black.opacity(0.75))
                    .clipShape(.capsule)
                    .offset(x: -5, y: -5)
            }
            Text(book.author)
                .font(.title)
                .foregroundStyle(.secondary)
            Text(book.review)
                .padding()
            RatingView(rating: .constant(book.rating))

            Text("Added \(Date.now, format: .dateTime.day().month().year())")
                .padding()
        }
        .navigationTitle(book.title)
          .navigationBarTitleDisplayMode(.inline)
          .scrollBounceBehavior(.basedOnSize)
          .alert("Delete book", isPresented: $showingDeleteAlert) {
              Button("Delete", role: .destructive, action: deleteBook)
              Button("Cancel", role: .cancel) { }
          } message: {
               Text("Are you sure")
          }
          .toolbar {
              Button("Delete this book", systemImage: "trash") {
                  showingDeleteAlert = true
              }
          }

    }

    func deleteBook() {
        modelContext.delete(book)
        dismiss()
    }

}

#Preview {
    do {
        let config = ModelConfiguration(isStoredInMemoryOnly: true)
        let container = try ModelContainer(for: Book.self, configurations: config)
        let example = Book(title: "Test Book", author: "Test Author", genre: "Fantasy", review: "This was a great book; I really enjoyed it.", rating: 4, date: Date() )

        return DetailView(book: example)
            .modelContainer(container)
    } catch {
        return Text("Failed to create preview: \(error.localizedDescription)")
    }
}

2      

Was the program running before you added date? If so, then you may need to remove the program icon from the simulator home screen. That way the data will not try to force its way into the existing database on the phone, which does not include your added field.

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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

Reply to this topic…

You need to create an account or log in to reply.

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.