Home > Software engineering >  How to properly use optional properties of structs in Swift
How to properly use optional properties of structs in Swift

Time:03-29

I have the following struct:

extension Models {
    struct Book: Identifiable {
        let id: UUID
        var title: String
        var pagesCount: Int
        var cover: Optional<Cover>;
        
        struct Cover {
            let image: String
            
            init(image: String) {
                self.image = image
            }
        }
        
        init(id: UUID = UUID(), title: String, pagesCount: Int, cover: Optional<Cover> = nil) {
            self.id = id
            self.title = title
            self.pagesCount = pagesCount
            self.cover = cover
        }
    }
}
extension Models.Book {
    static let sampleData: Models.Book = Models.Book(title: "Orconomics", pagesCount: 100, cover: Models.Book.Cover(image: "actual_image.png"))
}

and I am creating a SwiftUI view that displays each "model" Book.

I have made the Cover parameter optional, as some books won't have covers, the Models.Book.Cover struct has a non-optional property image.

Here's what I have in the body of my SwiftUI file:

HStack {
    if book.cover != nil {
        Text(book.cover?.image ?? "test") // <- can I avoid this?
    }
}

Isn't the book.cover != nil sufficient for Swift? Why do I need the "default value" (test) and the ? after book.cover?

CodePudding user response:

you could try something like this:

HStack {
    if let cover = book.cover {
        Text(cover.image)
    }
}

CodePudding user response:

What I use to do is handle this in my view model so I guess you should have a default value in your init, so I don't need to handle that in the View, since I like the view to be dumb and not deal with much logic.

I think you should use insteaad guard if you want to add an else option IMO guard is a bit more readable, if not if let as mentioned before should be fine.

CodePudding user response:

View? conforms to View. So just use map.

book.cover?.image.map(Text.init)
  • Related