LAST CHANCE: Save 50% on all my Swift books and bundles! >>

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      

Hacking with Swift is sponsored by Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

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.