I have created a Book struct with author and title defined. I then declare a var as an array of Book. I then declare several instances of Book. None of which generates any errors.
However, when I try to .append my Book instances to my array of Book it fails.
The problem is here:
myBooks.append(mb1)
Here is my code:
import SwiftUI
struct ContentView: View {
var myBooks: [Book] = []
let mb1 = Book(title: "Lies", author: "Franken, Al")
let mb2 = Book(title: "Road to Hell, The", author: "Groening, Matt")
let mb3 = Book(title: "Our Dumb Century", author: "the ONION")
myBooks.append(mb1)
var body: some View {
VStack(alignment: .leading) {
BookRow(book: mb1)
BookRow(book: mb2)
BookRow(book: mb3)
}
.padding()
}
}
#Preview {
ContentView()
}
Here is my struct:
struct Book {
let title: String
let author: String
init(title: String = "Hercules", author: String = "Author") {
self.title = title
self.author = author
}
}
The remainder of my code (but I don’t think it is relevant):
import SwiftUI
extension Book {
struct Image: View {
let title: String
var body: some View {
let symbol =
SwiftUI.Image(title: title)
?? .init(systemName: "book")
symbol
.resizable()
.scaledToFit()
.frame(width: 80, height: 80)
.font(Font.title.weight(.light))
.foregroundColor(.secondary.opacity(0.5))
}
}
}
extension Image {
init?(title: String) {
guard let character = title.first,
case let symbolName = "\(character.lowercased()).square",
UIImage(systemName: symbolName) != nil
else {
return nil
}
self.init(systemName: symbolName)
}
}
struct BookRow: View {
let book: Book
var body: some View {
HStack {
Book.Image(title: book.title)
VStack(alignment: .leading) {
Text("\(book.title)")
Text("\(book.author)")
.foregroundColor(.secondary)
}
.font(.title2)
}
}
}
>Solution :
The main problem here is that you have added executing code in places where there should be only declarations.
struct ContentView: View {
var myBooks: [Book] = []
let mb1 = Book(title: "Lies", author: "Franken, Al")
let mb2 = Book(title: "Road to Hell, The", author: "Groening, Matt")
let mb3 = Book(title: "Our Dumb Century", author: "the ONION")
myBooks.append(mb1)
You can’t call append here since, you need to be inside a method to do that. (I guess also mb1, mb2 and mb3 are misplaced).
Two options, either add an init and build up your array there
init() {
myBooks.append(Book(title: "Lies", author: "Franken, Al"))
myBooks.append(Book(title: "Road to Hell, The", author: "Groening, Matt"))
myBooks.append(Book(title: "Our Dumb Century", author: "the ONION"))
}
Or you could include it in the declaration of the array
var myBooks: [Book] = [
Book(title: "Lies", author: "Franken, Al"),
Book(title: "Road to Hell, The", author: "Groening, Matt"),
Book(title: "Our Dumb Century", author: "the ONION")
]
And since we now only have an array the view code in body changes to
List(myBooks, id: \.title) { book in
BookRow(book: book)
}
