View Model View State Reactive Programming
Tinder Firestore Swipe and Match
In this lesson, let's cover some more abstract topics related to code architecture. These two topics will be View Model View State and Reactive Programming. For those that are unfamiliar with these concepts, it'll sound somewhat intimidating at first but in reality its not too complicated. First we'll identify the areas of our code in which we can apply the abstraction. Next I'll go over how we can pull out some logic and plop it inside of our View Model that is supposed to keep track of the state of our views.

Comments (18)
Prabhdeep Singh Randhawa
4 years ago
After watching this video ,I think I still have a lot to learn.
Brian Voong
4 years ago
mashype
4 years ago
I feel like I barely understand the concepts. I see what you are doing and totally get the clarity of the cope, but have you done any video tutorials that explain at a more theoretical level why you are doing the MVVM model? I went through your Game of Chats tutorial that was all MVC, which I used to build a couple of other apps with the same model but would really like to understand more about MVVM and how to use it. As you build more complicated views, I totally see how this approach can be helpful instead of sending notifications all over the place.
Brian Voong
4 years ago
mashype
4 years ago
Thanks. Trying to understand all the nuance of architecture as more of a self-learner is a challenge, so I always like to see it in practical terms as you do in the courses, but I might just need to do some more research on that as well.
benpalmer661
4 years ago
Hi Brian could you please have a look at my question on stackoverflow https://stackoverflow.com/questions/53298913/swift-firestore-tinder-fetch-users-and-add-to-an-array-to-load-on-screen-adv you did send me the completed tinder app before but i can't work it out from there either, and i know you will probably cover this later in the tinder tutorial though i am just trying to stay busy.
Yoel Lev
4 years ago
Love it, the Reactive with MVVM is a very nice approch, i can say that ive learned somthing new, thank you Brian
Brian Voong
4 years ago
Dennisvm82
4 years ago
This was extremely interesting to work with. Thank you for explaining a more advanced topic like this. Learning so many new things every time I watch one of your videos. You are awesome, Brian!
svekariya305
4 years ago
Love the reactive approach!
svekariya305
4 years ago
Hey Brian, How do we bind two or more object in a same closure using generic?
Brian Voong
4 years ago
Paweł Liczmański
4 years ago
This was interesting and more difficult than previous lessons, I needed to watch this lesson twice and then download project, make some breakpoints and analyze to understand.
Cinquain
4 years ago
Yeah this video was definitely more intense than the former ones.
Cinquain
4 years ago
The second time watching this video really helped, I recommend this to be watched twice.
Jeffrey Chang
4 years ago
same, I would also recommend to look into additional reactive programming stuff.
Cinquain
4 years ago
Good tip! Thanks for sharing.
stonypig1
4 years ago
I thought I got rip off little by the 60$ price tag, but after this 3rd section I already felt it is worth every penny, should buy it sooner.
Brian Voong
4 years ago
fef
4 years ago
hi Brian thx for this instructif course, I learn so much with you. I had a question why didn't use (Static var index = 0) in struct before change it on class we will get for exemple with mutating func () { struct.index = struct.index + 1 } to solve problems ? or is not a good alternative ? thx
fef
4 years ago
sorry I find my mistake, and solution, thx ^^
Scott Alphonso
4 years ago
Great Course. Second one I have taken from you and both have taught me tons. I am still going through this one but I have adapted this tinder style functionality in a portion of the app I am working on. One thing I can't figure out is how can I get the swipe functionality to just cycle through the array of cards repeatedly and not dismiss them. I'm assuming I need to do something with having an index on the cardViewModel array but every way I look at it I am breaking the MVVM model/idea.
Scott Alphonso
4 years ago
I researched for hours, after typing the previous message to you I figured it out. In Cardview I replaced self.removeFromSuperview() with self.superview?.sendSubviewToBack(self) . It works without any problems when tested. Thanks again for all you do.
Eduardo Davila Nadal
4 years ago
Thank you Scott for sharing this solution!!
Cinquain
4 years ago
Fire!
Humberto De La Cruz
4 years ago
Hello Brian, this was a tough video because all the conceptual layers, after watching the video twice and studying the code, I think I have a grasp of the architecture (let me know if I am even close): 1. The first thing that happens is that the home controller creates and add the three views (top, middle, and bottom); the top and bottom, since they are static, are just built in their classes and presented as is. For the middle view, the card-view, the process is a little more involved... 2. For the card view the home controller first creates an array with three card view models, with two users and an advertiser (the user model and advertiser model define the format that each piece of information will be presented, for example; bottom left alignment for the user text and center text alignment for the advertiser ), which can be thought of as three buckets, each with the information from each user/advertiser (along with the format), and a little bit of logic (the ability to increase and decrease the index on demand). 3. the home controller then feeds each of the buckets to the card view via the cardViewModel variable inside of the card view. 4. For Each instance of the card view made from each of the buckets, the card view takes the information from each card view model in each bucket and lays it ; creating a frame for the image, adding the bars, adding the gradient, choosing the first image of the user, adding the ability to receive gestures and how to behave with each gesture etc... It is important to note that the card view does not define how each piece of information (text attributes, alignment) is laid out, the User and Advertiser model already do that, the card view just puts in place. 5. Now, the tap gestures are connected back to the card view model via the .advanceToNextPhoto() or cardViewModel.goToPreviousPhoto() functions. When the card view recognizes that the left or right of it's view are tapped, it tells the card view model that it has happened, the card view model does the calculations of increasing or decreasing the index. 6. when the index changes in the card view model, the didSet func for the index fires, in turn changing the image, and providing that information to the imageIndexObserver Variable. 7. (this is the part I am not a 100% certain about) When the card view model index change that causes the didSet for the card view model in the card view to also fire, in turn firing the setUpImageIndexObserver(), allowing it to capture the information in the ImageIndexObserver from the card view model, completing the loop. 8. So the structure set in this video is that the user taps the right of the card view -> cardViewModel.advanceToNextPhoto() -> card view model adds + 1 to the index -> imageIndex didSet fires -> next image and new index get saved in imageIndexObserver variable -> didSet for the card view model in the card view fires -> setUpImageIndexObserver() fires -> which grabs the images from the imageIndexObserver and gives to the card imageView to present and to set up which bar is white.
Humberto De La Cruz
4 years ago
After doing some testing with breakpoints, I found out that actually the didSet for the card view model in the card view does not actually fire, so how does function setUpImageIndexObserver() in the card view ever fire after the user taps?
Omran_K
3 years ago
I think what is happening here is the didSet for the cardViewModel in the CardView instance is fired when HomeViewController instantiates a cardView in setupDummyCards() and sets the cardView.cardViewModel. That is when the didSet of the cardViewModel is fired, which in turn fires setupImageIndexObserver. setupImageIndexObserver then defines the cardViewModel's imageIndexObserver closure property passing on a weak reference to itself(CardView) and instructions on what to do whenever that imageIndexObserver is fired. imageIndexObserver is fired whenever the cardViewModel's advanceToNextPhoto() or goToPreviousPhoto() methods are fired changing the value of imageIndex and firing it's didSet which then uses the new imageIndex value and the corresponding image to carry out the instructions that the CardView provided earlier. The instructions came with a weak reference to the CardView itself, imageIndexObserver can use this reference to change the CardView's imageView.image property as well as update the barsStackView to show the correct image selection. imageIndexObserver can only do this if the CardView has not been deallocated because its reference to it is weak preventing a memory cycle. Otherwise when the CardView is dismissed and self.removeFromSuperview() is called it would stay in memory because imageIndexObserver would be holding a strong reference to it. This is my understanding of how this works, hope it's correct.
HungryStag
4 years ago
Why did you create the CardViewModel as a struct initially as opposed to a class?
joker45
3 years ago
I'm not really see - in this case - a benefit of Reactive Programming. All feels more complex, harder to understand (specially if you try 3 months later to figure out how you create this function) And you not really save line of codes. Maybe for this function / app is Reactive Programming overkill and because of this i don't really understand the benefits.
aymather
3 years ago
100% worth the money man, super impressed with this course so far! Only thing, you set up such a perfect situation to explain the purpose of [weak self] or [unowned self] which I've been trying to understand. Would have loved at least a sparknotes of why you need either one of those. Again, you're the best man! Cheers!
slicedavocado
3 years ago
How would you apply CardViewModel in a Core Data context? Would you name the entity as CardViewModel or simply Card and write the functions in the extension file?
slicedavocado
3 years ago
Forget it, I figured it out
HELP & SUPPORT