# Models and Views | raywenderlich.com

**URL:** <https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108>\
**Category:** 🎓 Courses & Articles\
**Created:** [November 3, 2020, 4:28pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108 "2020-11-03T16:28:58Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![jessycatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jessycatterwaul/32/110937_2.png) [@jessycatterwaul](https://forums.kodeco.com/u/jessycatterwaul)\
**Post date:** [November 3, 2020, 4:28pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/1 "2020-11-03T16:28:58Z")

</div>

* * *
This is a companion discussion topic for the original entry at [https://www.raywenderlich.com/15234721-your-second-ios-and-swiftui-app/lessons/3](https://www.raywenderlich.com/15234721-your-second-ios-and-swiftui-app/lessons/3)

---

<div class="post-metadata">

**Author:** ![kristjan1997](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/kristjan1997/32/102075_2.png) [@kristjan1997](https://forums.kodeco.com/u/kristjan1997)\
**Post date:** [December 22, 2020, 1:53pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/3 "2020-12-22T13:53:08Z")

</div>

This specific tutorial video seemed to confuse me more than help me. The narrator wasn’t quite clear on why we are making extensions of the Book struct in another file rather than with the existing book file. Also trying to explain why we are putting an optional in front of a SwiftUI Image extension with “we wont always have a valid image for a title to represent that, add a question mark after the keyword init.” I have no idea what the narrator is trying to say here. Then not explaining the .square part for the initialization of symbolName, along with not explaining line 57 right after that (self.init…).

---

<div class="post-metadata">

**Author:** ![jcatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jcatterwaul/32/94210_2.png) [@jcatterwaul](https://forums.kodeco.com/u/jcatterwaul)\
**Post date:** [December 22, 2020, 4:12pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/4 "2020-12-22T16:12:27Z")

</div>

Hi,

> [@kristjan1997](#):
>
> The narrator wasn’t quite clear on why we are making extensions of the Book struct in another file rather than with the existing book file.

I tried to explain this from about 2:58 to 3:33. Please let me know what confused you about that, and I can elaborate.

> [@kristjan1997](#):
>
> Also trying to explain why we are putting an optional in front of a SwiftUI Image extension with “we wont always have a valid image for a title to represent that, add a question mark after the keyword init.” I have no idea what the narrator is trying to say here.

It’s a [failable initializer](https://docs.swift.org/swift-book/LanguageGuide/Initialization.html).  
[https://www.raywenderlich.com/1220-swift-tutorial-initialization-in-depth-part-1-2#toc-anchor-009](https://www.raywenderlich.com/1220-swift-tutorial-initialization-in-depth-part-1-2#toc-anchor-009)

> [@kristjan1997](#):
>
> Then not explaining the .square part for the initialization of symbolName, along with not explaining line 57 right after that (self.init…).

SFSymbols are covered [in this video](https://www.raywenderlich.com/18176818-your-first-ios-and-swiftui-app-polishing-the-app/lessons/9).

---

<div class="post-metadata">

**Author:** ![kristjan1997](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/kristjan1997/32/102075_2.png) [@kristjan1997](https://forums.kodeco.com/u/kristjan1997)\
**Post date:** [December 22, 2020, 4:51pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/5 "2020-12-22T16:51:18Z")

</div>

Thanks for taking the time to reply. The SFSymbols are my fault as I forgot that we learned that earlier. Will be reading more about failable initializers thanks for the resource! I’m still confused on why we call self.init(systemName: symbolName) on line 57 in our init? method. Is there a chance you can elaborate on that?

---

<div class="post-metadata">

**Author:** ![jcatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jcatterwaul/32/94210_2.png) [@jcatterwaul](https://forums.kodeco.com/u/jcatterwaul)\
**Post date:** [December 22, 2020, 5:27pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/6 "2020-12-22T17:27:03Z")

</div>

> [@kristjan1997](#):
>
> I’m still confused on why we call self.init(systemName: symbolName) on line 57 in our init? method. Is there a chance you can elaborate on that?

Sure!

After we get to that part of the failable initializer, we know that the character is not nil. So the Image we’re initializing won’t be nil, either. Instead, it will be one of these SFSymbols:

 ![Screen Shot 2020-12-22 at 12.24.44 PM 2](https://files.chunter.kodeco.com/original/3X/b/4/b43a0f98ad060389337ae05a3ef0bb967e25b584.png)

In order to create an Image from one of those symbol names, you call  
[init(systemName:) | Apple Developer Documentation](https://developer.apple.com/documentation/swiftui/image/init(systemname:)).

---

<div class="post-metadata">

**Author:** ![rossp779](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/rossp779/32/81494_2.png) [@rossp779](https://forums.kodeco.com/u/rossp779)\
**Post date:** [March 27, 2021, 10:03pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/7 "2021-03-27T22:03:59Z")

</div>

How come when we do `extension Image {}` swift knows that we are extending Swift’s Image and not the struct image that we just created? about 6:10 minutes into the video

---

<div class="post-metadata">

**Author:** ![rossp779](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/rossp779/32/81494_2.png) [@rossp779](https://forums.kodeco.com/u/rossp779)\
**Post date:** [March 27, 2021, 10:04pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/8 "2021-03-27T22:04:30Z")

</div>

How come when we do `extension Image {}` swift knows that we are extending Swift’s Image and not the struct image that we just created? about 6:10 minutes into the video

---

<div class="post-metadata">

**Author:** ![junghyun](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/junghyun/32/110937_2.png) [@junghyun](https://forums.kodeco.com/u/junghyun)\
**Post date:** [September 11, 2021, 9:23am UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/9 "2021-09-11T09:23:10Z")

</div>

I don’t understand of the grammar in part of " case let … " why do we use ? and how to be possible ?

![스크린샷 2021-09-11 오후 5.44.23](https://files.chunter.kodeco.com/original/3X/b/1/b18a8c5ffc2f5ced953703090752be2851601824.png)

---

<div class="post-metadata">

**Author:** ![jessycatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jessycatterwaul/32/110937_2.png) [@jessycatterwaul](https://forums.kodeco.com/u/jessycatterwaul)\
**Post date:** [September 11, 2021, 12:22pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/10 "2021-09-11T12:22:08Z")

</div>

An extension is written at file-scope. The only `Image` in that scope is `SwiftUI.Image`.

You would have to write

```swift
extension Book.Image {

```

if you specifically wanted to extend that type.

---

<div class="post-metadata">

**Author:** ![jessycatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jessycatterwaul/32/110937_2.png) [@jessycatterwaul](https://forums.kodeco.com/u/jessycatterwaul)\
**Post date:** [September 11, 2021, 12:44pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/11 "2021-09-11T12:44:10Z")

</div>

`guard let` and `if let` are just shorthand.

For example…

```swift
guard let character = title.first

```

is shorthand for

```swift
guard case .some(let character) = title.first

```

But as I mention in the video, what you bind on each line does not have to be optional. If it’s not, you _have to_ use the “case” form.

---

<div class="post-metadata">

**Author:** ![junghyun](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/junghyun/32/110937_2.png) [@junghyun](https://forums.kodeco.com/u/junghyun)\
**Post date:** [September 11, 2021, 1:26pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/12 "2021-09-11T13:26:05Z")

</div>

Thank you.  
Could you give me a reference for the part  
"If it’s not, you have to use “case” form "

---

<div class="post-metadata">

**Author:** ![jessycatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jessycatterwaul/32/110937_2.png) [@jessycatterwaul](https://forums.kodeco.com/u/jessycatterwaul)\
**Post date:** [September 11, 2021, 2:10pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/13 "2021-09-11T14:10:31Z")

</div>

I mention that it’s necessary at 10:39.  
Sorry, I can’t find any documentation on binding non-optionals, only [optionals](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID333).

All there is to it is that if you want to define new variables inside of an `if` or `guard` statement, you do that using `case`.

Example:

```swift
if
  case let ten = 2 * 5,
  ten < 11
{
  print("Ten is less than eleven.")
}

```

It’s an alternate form of this:

```swift
switch 2 * 5 {
case let ten where ten < 11:
  print("Ten is less than eleven.")
default:
  break
}

```

---

<div class="post-metadata">

**Author:** ![junghyun](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/junghyun/32/110937_2.png) [@junghyun](https://forums.kodeco.com/u/junghyun)\
**Post date:** [September 12, 2021, 5:55am UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/14 "2021-09-12T05:55:25Z")

</div>

Thank you very much for you rapid and kind answer.

---

<div class="post-metadata">

**Author:** ![sedawk](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/sedawk/32/81494_2.png) [@sedawk](https://forums.kodeco.com/u/sedawk)\
**Post date:** [October 17, 2021, 8:00pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/15 "2021-10-17T20:00:27Z")

</div>

I have just finished this tutorial and I found how the Image for the book is handled at this point very convoluted. I understand that this will be updated in the future when we grab the files, but to me I should not be passing the title of a book to Book.Image. A book has a stored property for title and there is no reason to pass this. A book knows its own title and therefore, should be able to create its own Image based on that title.

I’m going to continue with your example, but I’m also going to create an app that shadows every step for this tutorial, programming it the way that I think is more intuitive for a new user. (Just crossing my fingers that I don’t back myself into a corner 🤪)

What seems like the most straightforward solution is that the book’s image should be a computed property of Book (ignoring the Emoji case here).

```auto
   var bookImage : Image {
      guard let character = title.first else {
         return Image(systemName: "book")
      }
      
      let symbolName = "\(character.lowercased()).square"
      return Image(systemName: symbolName) 
   }

```

I’ve created a view (BookView) to test. As one would expect, it has one property of type Book.

```auto
struct BookView: View {
   let book : Book
    var body: some View {
       HStack {
          book.bookImage
             .resizable()
             .scaledToFit()
             .frame(width: 80, height: 80)
             .font(Font.title.weight(.light))
             .foregroundColor(.secondary)
          VStack(alignment: .leading) {
             Text(book.title)
             Text(book.author)
                .foregroundColor(.secondary)
          }
       }
    }
}

```

Calling BookView like this:

```auto
BookView(book: Book(title: "Carrie", author: "Stephen King"))

```

seems to work very well and I am assuming will be helpful when it comes to the List view.

---

<div class="post-metadata">

**Author:** ![jessycatterwaul](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jessycatterwaul/32/110937_2.png) [@jessycatterwaul](https://forums.kodeco.com/u/jessycatterwaul)\
**Post date:** [October 17, 2021, 8:43pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/16 "2021-10-17T20:43:28Z")

</div>

> [@sedawk](#):
>
> I understand that this will be updated in the future when we grab the files, but to me I should not be passing the title of a book to Book.Image. A book has a stored property for title and there is no reason to pass this. A book knows its own title and therefore, should be able to create its own Image based on that title.

A Book Image will only ever require a title, not an entire book, but the only place where this will end up mattering is in previews. Elsewhere in the app, there won’t be a Book Image without a Book. So I like your approach. Feel free to continue with it!

You’re right that, at the state of the project where this episode is, a computed property of Book will do wonderfully. Later, you’ll need to convert it to be a method, as arguments will be required. Utilizing a named View type allowed me to avoid having to introduce [the ViewBuilder attribute](https://developer.apple.com/documentation/swiftui/viewbuilder). You’ll need to use that on your method; post a comment for a later episode if that ends up giving you problems.

---

<div class="post-metadata">

**Author:** ![sedawk](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/sedawk/32/81494_2.png) [@sedawk](https://forums.kodeco.com/u/sedawk)\
**Post date:** [October 17, 2021, 10:08pm UTC](https://forums.kodeco.com/t/models-and-views-raywenderlich-com/124108/17 "2021-10-17T22:08:09Z")

</div>

Thank-you for the detailed reply Jessy. Its great discussion and interactions with course authors like you that make this site special. Much appreciated.

I’ve decided just to proceed with my code. It will be more work every lesson, but I think I will learn more.

One issue I think with my approach is that I have mixed UI elements into my data model. Not a big deal for this example, but probably as a programming practice this will make conversion to a different framework or converting a project to a different platform more difficult.

To fix this issue I have made a protocol called “ImageableItem” that requires a computed property (itemImage) to return a SwiftUI Image. Then added this extension to Book:

```auto
extension Book : ImageableItem {
   
   var itemImage : Image {
      guard let character = title.first else {
         return Image(systemName: "book")
      }
      
      let symbolName = "\(character.lowercased()).square"
      
      // Check for Emoji
      guard UIImage(systemName: symbolName) != nil else {
         return Image(systemName: "book")
      }

      return Image(systemName: symbolName)
   }
}

```

I know you mentioned that I will need to convert this to a method later, but I am going to stick with the computed property and try to make that work. I am going to build the ImageableItem protocol in such a way that it ensures any structure adhering to the protocol will be able to generate its image using a computed property. I feel like I should be able to accomplish this. (This may be backing me into a corner, but I’ll chalk it up to a learning experience 😌)

Thanks again for your input.
