Add a ViewModel with @EnvironmentObject in SwiftUI | Todo List #3

  Переглядів 46,147

Swiftful Thinking

Swiftful Thinking

3 роки тому

In this video, we will successfully implement the ViewModel layer into our MVVM (Model-View-ViewModel) app. The ViewModel layer is often the most complex of the layers in MVVM because it includes most of the business logic for the app. This layer brings the entire app together and has connections to the View layer as well as the Model layer. Within the ViewModel, we will add all logic for downloading, updating, adding, and saving data for our app!
Next video: • Save and persist data ...
Last video: • Create a custom data m...

КОМЕНТАРІ: 156
@emrah309
@emrah309 Рік тому
This is a top level beginner level course from Nick that makes you understand good coding practices, property wrappers, MVVM, saving. Thanks Nick!
@AZMerf
@AZMerf 3 роки тому
You do a really nice job of building the foundation and then continuing to build upon that, going back where necessary to remind the learners. Thank you.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
I'm glad you're able to follow along an understand. One of my biggest pet peeves is online courses that are hard to follow because the instructor does something and doesn't explain it haha. Let me know if you ever have questions!
@douglasrutledge1325
@douglasrutledge1325 Рік тому
My third time around on this series. I may sleep 5 hours a day, so I have lots of time. And it's finally getting through. You're doing a great job. I've watched other videos which you've covered and I can say you are the best teacher. Thanks again.
@m.d.perkins1407
@m.d.perkins1407 Рік тому
Really appreciate the video, and great work! I feel like it kind of strayed from the declarative concept for SwiftUI with all the alert stuff, though. You can remove all of that, set the default text for TextField to "Type something here... (3 character minimum)" (or something similar) and add .disabled(textFieldText.count < 3) to your Button. This makes for streamlined, declarative code. Hope this helps, and thanks again for the great videos!
@daniruiz931
@daniruiz931 2 роки тому
Great job! You covered so many important concepts that get me excited to build my own ideas in Xcode. Thanks a lot!
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Thanks for watching Daniel!
@TheSpiralnotizblock
@TheSpiralnotizblock 2 роки тому
As always, a FANTASTIC video!
@gccount
@gccount 4 місяці тому
I am so excited to learn from the series! I 'd like to give more thumbs!
@oscarsilva9644
@oscarsilva9644 Рік тому
How I searched the internet for a video like this! I wish I could give as many thumbs up as I think this video deserves.
@samtree99
@samtree99 Рік тому
You write very clean code! Thank you from a retired C++ programmer. This 3 videos of the MVVM concept are right at the point and precise. Nothing better than simple example that explains important concept. Excellent job and a great teach. Kids need teachers like you 👍🏼
@rfolden8089
@rfolden8089 Рік тому
Old retired C programmers like me need teachers like him also!
@carlosswiftdev2703
@carlosswiftdev2703 11 місяців тому
I knew how to do this but I still learnt something! other tutorials would change the id which I always found odd especially if that's being stored in a database. Nick you're a star 🤩
@AdventureDeveloper
@AdventureDeveloper Рік тому
It's really very interesting course! Thank you so much for your time!
@user-kr3dy2pn9h
@user-kr3dy2pn9h Місяць тому
The video is superb! as always!
@ec92009y
@ec92009y Рік тому
Probably the best MVVM video out there. You show haw to change a pile of disorganized code into a clean MVVM setup. Thanks.
@mr.erikchun5863
@mr.erikchun5863 Рік тому
He's the only one who literally and I mean literally gave us everything for free. Everyone else is money hungry who begins a topic and redirects people to a garbage course on another website that happens to be 75% off for a few hours.
@mihneagane9567
@mihneagane9567 Рік тому
Thank you for the tutorials! You are great!
@jalapisco
@jalapisco Рік тому
Disregard my question. I should have continued watching the video before jumping into conclusions. Thanks again for a great tutorial.
@andresraigoza2082
@andresraigoza2082 2 роки тому
Thank you so much!!! This is great value for me. I am finally learning how to do things right in Xcode. Thanks for sharing
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
You are moving so fast through these videos! 🤓😎
@amorimcode
@amorimcode 4 місяці тому
really good course, migrating from react native to swift ui, that's helping me a lot, thanks!
@robertbe5807
@robertbe5807 2 роки тому
Very good course! Thanks,
@douglasrutledge1325
@douglasrutledge1325 2 роки тому
Expert, hahaha, thanks for the vote of confidence!
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
I know you're well on the way Douglas 😎
@doctorstrangelove798
@doctorstrangelove798 2 роки тому
Thanks, i have a better understanding of the MVVM architecture
@randlyce
@randlyce 3 роки тому
Great Video! learning a lot
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Awesome, thanks again!
@bayraminanc885
@bayraminanc885 3 роки тому
Great work
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Thanks Bayram!
@Stevesvideoshelf
@Stevesvideoshelf 2 роки тому
Whew! This one really challenges me. The Update in CRUD seems to be the hardest concept to wrap my head around. I don't feel like I fully understand the code for it yet. I'll be rewatching this one for sure! Anyway. Thanks again Nick. Great video, as always!
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
The Model that we are updating is a Struct. Structs are based on VALUES and not INSTANCES... When you "update" a Class, you can access the instance of the class and change values inside. However, since Structs don't have instances and are based directly on their values, you can't change a value in a struct, otherwise it would be a different struct. Instead, we can "mutate" the struct, which is really just creating a new Struct and replacing it with the current one. In the update function, we are creating a totally new Struct, however, we are initializing it with most of the values from the current/previous struct.
@sema_f
@sema_f 2 роки тому
Thank you so much!!! 🥰🥳💡
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
You’re welcome 😊
@raysingh__
@raysingh__ 9 місяців тому
great video :)
@leotambasco9294
@leotambasco9294 Рік тому
Hi!!! first of all congratulations for your job! it's really great and helpful I'm new on IOS and MVVC, let me ask you something, if i'm not wrong ListRowView is accessing directly to the model (ItemModel), is it possible in MVVM?
@markerbaugh4016
@markerbaugh4016 2 роки тому
I have just worked through the Bootcamp videos and I'm now building along with this series. I really appreciate what you have done. I notice that when I run the app in the simulator, the console is displaying a lengthy message containing "Unable to simultaneously satisfy constraints." If you look closely at the screen in the video, it looks like it is also displaying a similar message. The message refers to UI... and NS... so I am assuming that it is coming from the underlying UIKit. The message gives hints on resolving the issue, but again this seems oriented to a UIKit solution. Should we try to eliminate this situation from the app and how would we go about finding and eliminating the constraint that is causing it? I did some further testing and I can make the message go away by removing the line .navigationTItle("Todo ...
@lehanas4918
@lehanas4918 2 роки тому
Great video, thanks 👭we are learning....
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
lehanas! Thanks for watching :)
@faikcoskuncakr7418
@faikcoskuncakr7418 2 роки тому
Very very very very good video for me. Thank you sooooooooo muuuucccchhhhh
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Thanks for watching Faik 🥳
@Phdit
@Phdit 2 роки тому
Great video, but i don't understand when and why you use struct or class, and on the inmutable struct, it is not the same making private the arguments and changing the variable inside the function?
@jahongirtursunboyev6470
@jahongirtursunboyev6470 Рік тому
Thanks a lot
@Lilitnandy
@Lilitnandy 2 роки тому
Love your tutorials. what about the alert part when I try to put in in the " textFieldText func where to show alert when the input is less than 3 characters I get this "Modifying state during view update, this will cause undefined behavior." I am not sure if I mistyped something , or it's an update in Xcode 13, since you are in 12. It's probably me , but I would appreciate if you could help me with this.
@spradohak
@spradohak Рік тому
hey guys, quick tip you can use dismiss as a keyPath for the environment instead of presentationMode. like this: @Environment(\.dismiss) var dismiss and then you can just say dismiss() any where, to make the view dismiss itself. Note: when you call it, just write down dismiss() without dot in front of it.
@aprilsianpi7973
@aprilsianpi7973 2 роки тому
Always thank you for the great videos. Can you please make another video focusing on updateItem? I have never seen such a powerful technique on UKposts. To make it harder for learning purposes, It would be really great with optional in the immutable struct.
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Hi April! Thanks for watching. You should be able to update the updateItem function with whatever parameters you want to change. You just need to return a new struct (Model) with the correct values!
@aprilsianpi7973
@aprilsianpi7973 2 роки тому
@@SwiftfulThinking Thank you.
@ritzg98
@ritzg98 7 місяців тому
I'm at about 12:00. There does not appear to be anything wrong with my version of the code (copied from the example code in the video). It gets to the point of displaying the ListView, but then gives a PreviewCrashed message in the simulator. Any insights as to what might be causing this?
@michaelsmirnov9796
@michaelsmirnov9796 2 роки тому
Great videos, love the material, good job. A note - 'indices' is pronounced "in-duh-sees"
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Hahaha I think you're right -____-
@kenturnbull9679
@kenturnbull9679 2 роки тому
@@SwiftfulThinking OH he's right
@kevintopollaj3167
@kevintopollaj3167 6 місяців тому
Great videos thanks for sharing, I would just suggest to be more careful when you use @State because since it is the state of truth for a specific view you should usually do @State private var. 😀
@user-kg5ct3zq4d
@user-kg5ct3zq4d 9 місяців тому
Hello nick I have one question regarding MVVM why you have not put text validation code in viewmodel [as this code also represent presentation business logic and our view should not include any business logic]
@FlashGamer521
@FlashGamer521 Рік тому
Just out of curiosity, if you wanted addItem to update when a user pressed return in the textField rather than via the button, how would that be accomplished? -- I tried a few things, but keep running into Type '()' cannot conform to 'View' errors.
@jacob.lindgren
@jacob.lindgren 2 роки тому
Really well done series! How would you go about tracking only one item selected? To be able to reference that item in another part of the app later.
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
You could add a "selectedItem" variable into the ViewModel!
@angadkler4627
@angadkler4627 2 роки тому
is there a way you can rename the navigation bar title when your in edit mode?
@horai8256
@horai8256 4 місяці тому
How does the immutable struct compare to a class with private properties? With a class, you can still forbid accidental changes to private properties, and "updateCompletion" function doesn't create a new object. I'd like to understand your thoughts on the design choice behind this. Thanks!
@leonardohopp5443
@leonardohopp5443 11 місяців тому
I was wondering why my code didn't work until I realized that I left the @Environment(\.presentationMode) var presentationMode out. There is actually a correlation between the EditButton() and the presentationMode. When you use the NavigationView-Button to go back to the MainView the EditButton won't work. Super weird. Do you have an explanation? Love this Bootcamp :)
@douglasrutledge1325
@douglasrutledge1325 Рік тому
also another scenario. Where a record is created, some data attributes can not be changed for that record but only one of the attributes will be updated, of course pointing to the same id. How is this managed in the ItemViewModel? I hope you have time to help.
@sgtpotatoe
@sgtpotatoe 3 роки тому
Great video! I come from Android development and been learning SwiftUI for a few months now. MVVM is also the standard or most common architecture in Android Apps, but there's a couple things that look different even though the role is exactly the same. I find it very practical that you can initialize the ViewModel in the app struct (at app launch) as a StateObject and then there is no destroying or recreating of that viewmodel instance during the app lifecycle. I'm yet to watch the viewmodel video you have done that deals with viewmodel & coredata, but I wanted to ask something, in this project you had a viewmodel for the model ItemModel, but as you add more views and possibly more models, would you add more viewmodels? And just add them like the first one in app struct?
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hey, thanks for watching! I'm a bit confused about your question. Just to confirm, the ViewModel here is initialized at the app launch using @StateObject and then passed around the app using @EnvironmentObject. We are not destroying and recreating it during the life cycle.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
As for the second part of your question, yes I would make more ViewModels if we added more Views (assuming the new Views didn't share the same ViewModel logic). I would also note that this is a beginner level course and it's much easier to learn/follow by creating ViewModels within the structs that need them. I have not covered Protocols or Dependency Injection yet, but if you know how to use these to make the VM initialization more efficient, then you should definitely do that!
@sgtpotatoe
@sgtpotatoe 3 роки тому
@@SwiftfulThinking Yeah exactly, by initializing it once at app launch you dont have to worry about it. The question is irrelevant to this sorry! All I was curious about is how the view models escalate with app complexity such as adding more models & views, do you tend to use one single viewmodel or multiple viewmodels? Or just depends on the situation?
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
@@sgtpotatoe Complex apps usually use multiple ViewModels. If you had one for the entire app, it would end up being very long and confusing to work with. A rough estimate could be one ViewModel for each screen. Apps with more advanced architecture might also have some "global" ObservableObjects that are more high level than a ViewModel, but function in the same way.
@sgtpotatoe
@sgtpotatoe 3 роки тому
@@SwiftfulThinking Thanks a lot! Really helpful!
@kheder.t.asfour
@kheder.t.asfour 2 роки тому
man when you say MVVM expert I fell like 😌😌😏😏 😂😂
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
You are haha 😁
@MegaAVINASH24
@MegaAVINASH24 Рік тому
Really useful. However in my case addItem(...) has nil value. So when textfield is unfocused it's resetting value to nil and it seems modelobject's value is not binded. It's binded only in viewmodel level. Can anyone suggest a solution for this?
@charpi1472
@charpi1472 Рік тому
Amazing video, quick question though: am I correct in believing that you didn't add the addView functions (saveButtonPressed(), textIsAppropriate(), and getAlert()) to the ListViewModel because these functions deal with the UI aspects and are not CRUD related?
@SM-hr4ml
@SM-hr4ml Рік тому
2 of them can, if you import SwiftUI into the view model class file , but I am really struggling w/ the 3rd, ie saveButtonPressed .... bc of the @Environment call.
@jalapisco
@jalapisco Рік тому
Hello Nick, great tutorial (as always). Quick question: ListView was working fine in the simulator but not in the canvas. I looked it up in stackoverflow and somebody suggested making this change to the preview struct (see the line where ListView() is called). struct ListView_Previews: PreviewProvider { static var previews: some View { NavigationStack { ListView().environmentObject(ListViewModel()) } } } That seemed to do the trick but I'm not entirely sure I understand what I did.
@SwiftfulThinking
@SwiftfulThinking Рік тому
The view requires a ListViewModel to be in the environment or it won’t compile. There’s a video on @EnvironmentObject in the Bootcamp playlist 👍
@panosjapan7
@panosjapan7 8 місяців тому
Had the exact same issue. Thanks!
@halamh5967
@halamh5967 Рік тому
Hello Nick! Great Tutorial Thanks! I just have one question please. At minute 18: 02 you passed item to the addItem function instead of $item, isn't item supposed to be binding?
@SwiftfulThinking
@SwiftfulThinking Рік тому
Im SwiftUI, data normally flows from parent to child. You only need a binding if the child needs to update the parent.
@halamh5967
@halamh5967 Рік тому
@@SwiftfulThinking got it thanks! 🫡
@adobefadel
@adobefadel Рік тому
Thank you for this list, really it is very smart with you I watched it as a movie 🥰 Hint: In 21:32 you can short code to func textIsAppropriate() -> Bool { return textFieldText.count > 3 } Thanks
@douglasrutledge1325
@douglasrutledge1325 Рік тому
this is the part that you skimped on: func updateItem: you are forcing a the change of one value within the ItemViewModel.isCompleted. What if you had to pass an updated value for the .title, how is that done. I've watched this video so many times, thinking I missed something. SO HOW IS THIS DONE. Can you clarify please?
@pierremarais7669
@pierremarais7669 2 роки тому
Thanks for an AMAZING good video, I want to know more on how to use existing sqlite DB within my new app for just reading data and display it, any suggestions where to get a good example please, thanks
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Hey Pierre! I don't have any good references for this, sorry.
@devpaulc
@devpaulc 2 роки тому
great tutorial. I was wondering how would you sort the list alphabetically or, if I'd add a due date to the data model, how would you sort it by due date?
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Hey Paul, yes you could definitely do that! You would need to add the fields to the data model and then sort the items before setting self.items = savedItems. I cover the basics of sorting here: ukposts.info/have/v-deo/fl2YiZCxq4aFyH0.html and a more advanced example in the Crypto App tutorial here: ukposts.info/have/v-deo/kaKZe35vhKGis5c.html
@devpaulc
@devpaulc 2 роки тому
@@SwiftfulThinking thanks for the quick reply. I’ll check those out tonight
@gucp
@gucp 11 місяців тому
27:47 it was all fun and games until this point 😅but I think I got the hang of it, had to use playground to visualise it
@vladimirstepanov7246
@vladimirstepanov7246 2 роки тому
top
@morreke
@morreke 2 роки тому
Great coding practice making use of immutable structs. I'm just wondering if you can use this too if you want to change a value in all your other items. For example an indicator that shows which list item is selected after it got pressed. At the moment in my view I'm looping through "myViewModel.items.indices"with a ForEach loop which gives me an index, and then I'm using this index in my viewModels function "items[index].isActive = true" & "for i in items.indices where i != index { items[i].isActive = false". It works, but if i need to display some other value from the array then i need to use the index too instead of the item itself.
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
The initializer of the ForEach that uses a Range (what you’re using here) specifically says it’s only for an array with a “constant” range. So if you’re changing the number of items in the array, it’s better not to use that. If you’re looping on Items, you can also make a function to find the Item’s index using array.firstIndex(where:)
@morreke
@morreke 2 роки тому
@@SwiftfulThinking Alright good tip thanks a lot ! Now I'm still looking how I can change the values of all other instances (so all except the index)
@dr.craigcurphey4829
@dr.craigcurphey4829 3 роки тому
After watching this video 3x plus writing the code as you build it on the 4th, I think I am missing some nuances and am a bit fuzzy regarding how the itemModel and ListViewModel communicate with each other. If I can get specific about a few questions can I ask you in your website?
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hey Craig, yes, I'm happy to answer questions. It might be better to finish the course first though. I think things might make more sense as we wrap up and test the application in the next few videos!
@Brecht1970
@Brecht1970 10 місяців тому
Hi Nick, how can we edit an item from the list? A new view with a destinationlink I suppose but how do we get the data from that row in the new view? Thanks in advance for your answer and thanks for sharing your knowledge!
@CinematicAdventureOne
@CinematicAdventureOne 10 місяців тому
You can add .swipeAction modifier on foreach row, and add a button with navLink to a new view.
@oscargidefjord848
@oscargidefjord848 2 роки тому
If i want to add more fields of texts to the array from the addView, for example some values (ints), how would you do that?
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
You can add more properties within the Model and update it the same way we are updating the completion boolean.
@lolrie
@lolrie 10 місяців тому
Hey Nick - when updating task completed state, could we just toggle isCompleted using items[index].isCompleted.toggle() rather than creating a new item and placing it into the same index? What's the tradeoff between manipulating a property of what's already there vs. replacing the item entirely? Thanks!
@CinematicAdventureOne
@CinematicAdventureOne 10 місяців тому
Because isCompleted is a constant property, you can’t change it outside of the model struct. That’s why he created an additional initializer and put it in a function inside of model struct to remain the same id and title during initialization for existing item.
@lolrie
@lolrie 10 місяців тому
@@CinematicAdventureOne If we know isCompleted is a property that will change, can't we just declare it with var to avoid creating an additional initializer? What's the benefit of creating it as a constant property?
@artembra8775
@artembra8775 9 місяців тому
@@lolrie same questions
@rasheed1andrew
@rasheed1andrew 2 роки тому
just found out you attended Penn State. nice. we probably crossed path couple of times. this video got me feeling fuzzy but I will watch over and over. here is a question. when you create cells in a list view like you did here. in this example, you can tap and it changes the state of the cell (the circle becomes filled with a green check mark.). if the cells where to be put in a navigation link, what will happen. I feel like on tap, the view will change to the view set in the navigation link but the circle wouldn't change to the green check mark.
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
We are!! I love meeting fellow penn staters. That's awesome.... you're question is fairly specific. If you're using a NavigationLink, the button would then navigate to the next screen, so having the circle animation would be pointless. There are probably better ways to optimize if that's the situation.
@rasheed1andrew
@rasheed1andrew 2 роки тому
@@SwiftfulThinking if you look at the Apple Music app for example. In a list of songs, if you tap the button on the far right, it adds the song to your playlist but if you tap anywhere els on the cell, it plays the music. I wanted to implement the same feature in my app where if you where to tap on a button on the far right an action occurs like subscribe but if you were to tap any where else on the cell it takes you to a detailed view of the cell.
@rasheed1andrew
@rasheed1andrew 2 роки тому
@@SwiftfulThinking I followed these steps and at around 18 minutes into the video creating the add function into the view model, I'm getting a couple of errors.
@rasheed1andrew
@rasheed1andrew 2 роки тому
no exact matches in call to instance method 'append'
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
@@rasheed1andrew It sounds like you might have made a typo somewhere. The full source code is available on my Github if you want to compare: github.com/SwiftfulThinking
@metinsaglam5027
@metinsaglam5027 9 місяців тому
"Thread 1: Fatal error: No ObservableObject of type ListViewModel found. A View.environmentObject(_:) for ListViewModel may be missing as an ancestor of this view." I took an error..
@dimflash1987
@dimflash1987 2 роки тому
🤯
@sergiocaplan1168
@sergiocaplan1168 Рік тому
Just so I know I have it right: When you’re updating the item (toggling the isCompleted): Technically you’re creating a new item, and putting it in the same index as the item before you toggled the isCompleted. So the item that existed before you toggled the isCompleted is erased by the OS? So I have it correct? ps. Thanks for your videos.
@SwiftfulThinking
@SwiftfulThinking Рік тому
Yes exactly. There is more than one way to do this but I find this to be a safe approach for beginners 👍
@rajanmaheshwari
@rajanmaheshwari 10 місяців тому
I am not sure I am the only one facing but adding a tap gesture on ListRowView only works when we tap on the area which has the image and label covered. The empty area to the right doesn’t work. It may be due to HStack which is to the extreme left leading. Adding the label with more than 1 line text works fine. We can tap anywhere in the cell. How to achieve the didSelectItem like behaviour even if the text is small and we want a tap to be enabled within the cell but outside the label and image area.
@SwiftfulThinking
@SwiftfulThinking 10 місяців тому
You can either make the cell a Button or add a .background(Color.black.opacity(0.001) to make the area tappable
@kurtschmucker4229
@kurtschmucker4229 2 роки тому
At about 1:52, you say: "I did a whole video in the SwiftUI Bootcamp on (deleting items from a list)." I have looked, and I can't find such a video. Which Bootcamp video does this?
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
It’s included in this one: ukposts.info/have/v-deo/rJuAoo5-ZKl_zKc.html
@kurtschmucker4229
@kurtschmucker4229 2 роки тому
@@SwiftfulThinking Thanks for the quick reply. My confusion was caused by your channel home page. On your channel home page, the SwiftUI Bootcamp (Beginner Level) lists only 11 videos in the scrolling carousel . I have now seen the whole playlist which has more than 50 videos! This explains why I could not understand several times when you referenced back to a Bootcamp video. I have a lot more videos to watch!
@m__link6499
@m__link6499 3 роки тому
One question please : why sometimes, you created a swift file and adding SwiftUi framework, instead of just creating a SwiftUI file ? 🤔Thank you.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hey great question! I use SwiftUI files when I need the preview section at the bottom because it comes with the template Previews (for the Views). But I use Swift file when I don't need the preview (for everything other than the View). The different is just the template code that comes in the starting file. You can actually edit either of them to be the same thing haha
@jimmyciaston7733
@jimmyciaston7733 Рік тому
Quick question, why in the AddView file, you have functions (ie. saveButtonPressed & textIsAppropriate). Shouldn't this go on the viewModel file?
@CinematicAdventureOne
@CinematicAdventureOne 10 місяців тому
I think you can create a new viewModel just for AddView to play with the function logic. But adding these function and logic to ListViewModel will make it a bit complex and confusing as it’s a beginner tutorial.
@dr.craigcurphey4829
@dr.craigcurphey4829 3 роки тому
Great training video but the complicated workings and relationships between the VM and the View and the Model really confused me so I'll hafta go over it a few times. Maybe I'll have a specific question shortly.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hi Craig! That's exactly why I started with this very simple app. I think a lot of people overcomplicated the ViewModel. All we are really doing is separating the logic for the screen (which is in the View) from the logic for the data behind the screen (which is in the ViewModel). Definitely let me know if you have any questions!
@dr.craigcurphey4829
@dr.craigcurphey4829 3 роки тому
@@SwiftfulThinking that part I understand - what gets me is the alert processing - you have the .alert on the ScrollView but I don't understand why it fires or what its purpose is when the text is < 3 characters keyed in and that is triggered by the button action (saveButtonPressed). so does the modifier on the ScrollView simply define an alert? i don't get it obviously. thanks for helping!
@dr.craigcurphey4829
@dr.craigcurphey4829 3 роки тому
I finally got it - had to re-watch the Alert video! your videos are like a reference libraray!
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
@@dr.craigcurphey4829 Haha that's great to hear. I tried to structure the courses so that I never use anything in a video that I haven't previously covered already :)
@user-pb1ng9wz1l
@user-pb1ng9wz1l 2 роки тому
12:33 how to get the shortcut of text below when you type the first symbol " @ "? On my computer, If I type @En, It won't show up the ENTRY, Encoder, Encodable.
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
I think the compiler in Xcode 13 is just super slow compared to Xcode 12 (which is what I used when making this video). Hopefully they fix it in a future release.
@mystride
@mystride 2 роки тому
If you have 20+ models and main views in your app, is there any performance risk to making them all .envornmentObjects where they are all aware of each other? Or should Views and ViewControllers be in 1:1 relationship. Example: CoolView is only aware of CoolViewController directly? Thank you!
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Eventually there would be a performance loss because you're going to load all of this extra, non-essential code into every View. However, the bigger worry would just be organization. You can't have 2 of the same Type of objects in the same Environment of a view, and you often don't want all of your Views to have access to all of your services.
@mystride
@mystride 2 роки тому
@@SwiftfulThinking That makes sense. Thank you!
@leezicai
@leezicai 8 місяців тому
when: struct ListRowView: View { @State var item: ItemModel } , withAnimation(.linear){ listViewModel.update(item: item) } did not work. change : var item: ItemModel is normal.
@felipevilela1834
@felipevilela1834 8 місяців тому
having the same problem here :/
@balajir9393
@balajir9393 5 місяців тому
Need to import Combine in viewmodel for @Published annotation
@merakshot9277
@merakshot9277 5 місяців тому
i was wondering why it works for me without Combine but there is an answer from ChatGPT My Question was: but it works fine with foundation. You're correct! In your case, the @Published property wrapper is working fine without explicitly importing the Combine framework because SwiftUI implicitly imports Combine when used with @Published, even though you haven't imported Combine explicitly in your TodoViewModel. SwiftUI's @Published property wrapper uses Combine under the hood to provide observable behavior for your properties. This integration allows for automatic change notifications and data binding between your view model and SwiftUI views. So, while you don't need to explicitly import Combine in your TodoViewModel file, the @Published property wrapper will still leverage Combine functionality for publishing property changes. Your TodoViewModel class should work smoothly with @Published as you've implemented it. If you have any more questions or need further clarification, feel free to ask!
@stepanfomincev7331
@stepanfomincev7331 7 місяців тому
33:10 can I replace let isCompleted with var isCompleted then toggle the var, its much easier
@stepanfomincev7331
@stepanfomincev7331 7 місяців тому
hm i guess we added init to not only toggle the completion, it makes sense
@merakshot9277
@merakshot9277 5 місяців тому
it's much safer to make it let and there is some methods that you can toggle isCompleted without necessarily making it var. you watch swift course there is some keynotes ukposts.info/have/v-deo/n4J8oKapjKBeqmw.htmlsi=9Nl8CrdJCH6P9Hq7&t=408
@Bharat_s
@Bharat_s Рік тому
my fav button crashed giving this error "Thread 1: Fatal error: No ObservableObject of type TodoDataModel found. A View.environmentObject(_:) for TodoDataModel may be missing as an ancestor of this view."
@anzzz119
@anzzz119 3 роки тому
I don't fully understand the flow of the data between the views, it will be cool if you can make a video with arrows or something like that will be awesome.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hello! I will try to make a diagram in the Github repo soon. The simple structure is that the ViewModel loads the data and then sends it to the View to display on the screen!
@anzzz119
@anzzz119 3 роки тому
@@SwiftfulThinking what I mean is that you create an struct and the in de main view you declare a variable and sign to the struct, but if you create another view you use instead of var test = struct() you say var test : struct is that the same information??
@anzzz119
@anzzz119 3 роки тому
the data is "inside the struct or the var test?
@ZefsAl
@ZefsAl 2 роки тому
Sometimes hear the sounds of you scratching your stubble ))
@kanghanj
@kanghanj 3 роки тому
great tutorials. a little suggestion: use a better mic.
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hi Hanjun! Yea I need to invest in one 😩 Sorry about that.
@vladislavbogucharov6256
@vladislavbogucharov6256 2 роки тому
Why can't we change the state of the model like this? var item = item item.isCompleted = !item.isCompleted
@SwiftfulThinking
@SwiftfulThinking 2 роки тому
Because the Model is a Struct and not a Class. Structs are based on values, so in order to change the data inside a Struct, we need to "mutate" it or create a new one with updated information. If our model was a Class, then we could do that..
@vladislavbogucharov6256
@vladislavbogucharov6256 2 роки тому
@@SwiftfulThinking Thanks! Your explanations are amazing.
@shreyaanshpurohit9292
@shreyaanshpurohit9292 3 роки тому
Where is the presentationMode boot camp video?
@SwiftfulThinking
@SwiftfulThinking 3 роки тому
Hi Shreyaansh! I included it within the .sheet() video. The presentationMode is just an environment variable that understands what screen is currently showing on the app. We use it to dismiss the current screen. ukposts.info/have/v-deo/nJSjZ3tno2qYqoU.html
@user-ej7bj8hz6t
@user-ej7bj8hz6t Рік тому
20:49
@douglasrutledge1325
@douglasrutledge1325 Рік тому
I'm back!
@knowledgeispower4953
@knowledgeispower4953 3 місяці тому
sup😇
@toomee4674
@toomee4674 Рік тому
Hi! I've watched 3x and still don't understand why! IsCompleted works.
@josephestrada4222
@josephestrada4222 Рік тому
@Environment(\.dismiss) var dismiss func saveButtonPressed(){ listViewModel.addItem(title: textFieldText) dismiss() } Solution now that @Environment(\.presentationMode) is deprecated
Save and persist data with UserDefaults | Todo List #4
14:41
Swiftful Thinking
Переглядів 27 тис.
😨Новая Война в GTA 5 Online #shorts
00:40
King Dm
Переглядів 1,4 млн
How to use LongPressGesture in SwiftUI | Continued Learning #1
16:19
Swiftful Thinking
Переглядів 16 тис.
MVVM is BAD for SwiftUI - Use MVC Instead! (Yes, MVC)
13:28
Rebeloper - Rebel Developer
Переглядів 3,5 тис.
How to use DragGesture to move, drag, swipe in SwiftUI | Continued Learning #4
30:42
Project Setup with Assets and Custom Data Model | SwiftUI Map App #1
15:28
Swiftful Thinking
Переглядів 18 тис.
MVVM vs. MVI - Understand the Difference Once and for All
18:40
Philipp Lackner
Переглядів 22 тис.
Add a dynamic List to display downloaded coins | SwiftUI Crypto App #5
17:36
Swiftful Thinking
Переглядів 15 тис.
VIM: A new SwiftUI Architecture for iOS 17
3:37
Flo writes Code
Переглядів 3,5 тис.