Learn about Model-View-Controller (MVC) and the dreaded massive view controller problem and how Model-View-Controller-Networking (MVC-N) can save the day.
Thank you:) Some notes. (I edited 4 times this post!, Iâm sorry)
This video is more about Singleton Pattern and MVC Pattern with enhancing Network handling.
MVC-N probably is a teacher slung, but, please, provide me with a link that proves that MVC-n term exist. I found here an MVC-N talk but is referred to N as an extension and not a pattern.
In the code, the instructor uses word Injection wrongly and maybe gives the wrong intention to the student about DEPENDANCY INJECTION (another pattern that not used actually in this episode).
Please replace word injection with Singleton or Dependancy (without injection as we donât inject anything in the constructor or outside from our Object).
Inside the completion closure, I liked that guard of weak self but I would prefer to name it as weakSelf and not StrongSelf as your guard is only check if itâs nullable. The strongSelf could lead the student to think that is a strong reference but is not.
Resume for this video.
Replace article topic to Singleton, remove word injection and add a small topic front of the video about Singleton Pattern. More reference links about every pattern in use to other sites (or Wikipedia) would be nice.
Question: Why we use the DispatchQueuemain in the Network Singleton handlers.
All my notes are in the mood to improve the lesson. Feel free to correct me and lets produce the best results for this topic.
@kostapappas Thank you for your feedback. You made several points, and I want to address these in turn, hopefully providing useful information to future viewers too. :]
This series went through several proposals prior to creation. I initially did want to cover the Singleton pattern.
However, we as a team decided this series should be kept short, and 11 videos just isnât enough to cover every design pattern and related concepts.
Hence, we made certain assumptions about viewersâ knowledge, including a basic understanding of iOS and common design patterns. You may notice that MVC, Singleton, Delegate, etc patterns arenât covered explicitly in this series. We assumed most iOS developers would already know about this, and we wanted to present material that would be valuable to most iOS developers.
I interpret this statement as having two parts: (1) Is MVC-N actually a design pattern, and (2) where did it come from?
In response to (1), I propose, and Wikipedia agrees, that a design pattern is a reusable, template solution to a common development problem.
With this definition is mind,
Does MVC-N solve a common development problem?
Yes, most apps need to talk with an external resource, and you need some way to handle this.
Is MVC-N a reusable, template solution?
MVC-N proposes that networking logic doesnât belong in models, views or controllers, the main âtypesâ used in MVC. Instead, this logic should be pulled into separate classes that can be used, in composition fashion, wherever needed. This isnât a concrete implementation, but rather, itâs a methodology: a reusable, template solution.
Thereby, yes, MVC-N is a design pattern.
In response to (2), I personally learned about the idea of âMVC-Nâ (although, not necessarily by this name) from AFNetworking, one of the earliest open-source networking libraries to be widely used for iOS development in Objective-C.
AFNetworking has an AFHTTPSessionManager class. The documentation suggests the following:
Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass AFHTTPSessionManager, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application.
Doesnât that near exactly describe the idea of MVC-N presented in this video?
As for the name âMVC-Nâ itself, Iâll confess this is simply what Iâve both heard it commonly called and call it myself. Articles like the one you mentioned by Marcus Zarra also use this name too, so if anything, Iâd say itâs not wrong to call it this.
Actually, âdependency injectionâ is exactly what I meant.
Whether youâre injecting a dependency as a singleton or using a dependency injection container, youâre still doing dependency injection, right?
I wanted to cover dependency injection explicitly within this series too, but alas, this concept got cut due to time constraints as well.
Also, since weâre nitpicking a bit here, I wouldnât call âdependency injectionâ a design pattern. If anything, Iâd simply call it a design paradigm or practice, maybe?
That is, dependency injection is simply when you pass a dependency to a consuming object.
There are two main ways to do this:
property injection
initializer injection
An example of property injection would be:
let person = Person()
let pet = Pet(name: "Rover")
person.pet = pet
An example of initializer injection would be:
let pet = Pet(name: "Rover")
let person = Person(pet: pet)
Youâd be hard pressed to say that either of the above is actually using a design patternâŠ
Sure, you can use dependency injection frameworks like Swinject to help manage dependencies across your application too (and I recommend you do!), but this isnât required by any means to do âdependency injection.â
Sorry, youâre mistaken here.
strongSelf is a strong reference for the duration of the closure.
This is why you donât have to unwrap it (use either ? or !) anytime you access properties on it thereafter, which you would have to do if it were weak.
This is a convenience for callers. If you didnât dispatch to the main queue, any callers doing operations that must be done on main (e.g. UI related) would have to dispatch to it themselves.
If you prefer, you can instead pass in the queue to dispatch to the method itself. Youâd just change the method signature to also take a dispatch queue.
Thank you again for your comments @kostapappas.
Iâm sure other viewers will have these questions too, so hopefully this helps them in future as well.
I agree with the team. 11 minutes itâs a PERFECT choice.
As junior dev too many names confuses me. So Iâm trying to keep the Patterns as described in GoF and use design principle terms for Clean Code best practices. So (for me) MVC-N = Separation Of Concerns and Single Responsibility as a design principles and implementation of Singleton design pattern.
Setter or property Injection in Swift, as we donât have @Required like Java is not preffered by me. Yes! and thank you for proposing the Swinject. Defenitely I will explore it.
About strongSelf, yes you are 100% correct. The guard let a = weakSomething creates a strong reference for this duration of the closure as increase the reference number. Also a let is always a strong reference (only var can be weak). It was an excellent time to clear that (more here)
I need more time to investigate the DispatchQueue. Is something that probably Iâm doing wrong.
REALY Thank you for the feedback. Keep up the good work
In my experience, thereâs three main trains of thought about this:
Pull networking into its own entity⊠which gives MVC-N shown here.
Put networking in the models⊠basically like Facebook Parse did.
Use a hybrid of the above⊠Firebase sort of does this.
Which of these is âthe bestâ to do? It depends on your project, of course. :]
Iâve personally had the best experience with MVC-N in my own projects, especially if I need to share networking across two or more apps.
However, you can make any of the three options above work⊠just think about what youâre trying to do and plan ahead.
In particular, whenever Iâm architecting a solution, Iâll run it through the SOLID principles and see if it breaks any principle that Iâm unhappy about or anticipate will be a big issue later on.
If youâre not familiar with SOLID, I highly recommend learning it as soon as possible. In particular, I highly recommend Clean Code: A Handbook of Agile Software Craftsmanship, which is the de-factor go-to source for learning SOLID.
Without SOLID, Iâd be lost in most development that I do each day⊠SOLID is a useful testbed for experimenting with âwhat-ifâ scenarios, if you will. At least, thatâs how I use it. ;]
I am new to iOS development and i have few questions.
Is it absolutely necessary for NetworkClient to be singleton?
Will it be wrong to keep it as ordinary class and create instance for request?
I am very interested in this part of code. Can you explain me what is it for?
// MARK: - Instance Properties
public var dataTask: URLSessionDataTask? {
get {
return objc_getAssociatedObject(self, &AssociationKey.dataTask) as? URLSessionDataTask
} set {
dataTask?.cancel()
objc_setAssociatedObject(self, &AssociationKey.dataTask, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
Itâs useful to make the network client a singleton. For example, you can later implement network request queuing, response cache, etc, which is much easier to do if itâs a singleton.
I my own apps, I tend to create a network client for each endpoint (that is, different urls) as necessary. Each of which is a singleton, or even better, injected using a dependency injection library such as Swinject.
This is an associated property. You can learn more about them from this excellent NSHipster article.
UIImageView+URL.swift adds a convenience method to set an image from a URL onto an image view.
This is a very simple example of how to do this. You can check out AlamofireImage for a very nice, complete implementation of this.
I know itâs not a design pattern but what do you think about wrapping all in Operations,
you could have a group operation that contains 2 operations, one for downloading a resource and the other one for parsing ⊠you will have to inject your network client as a weak reference to the constructor of your operation.
In 2015 WWDC, they had a session on advanced operation ⊠I tend to follow this principle
This is good but we can better this implementation to remove repetitive code and make it testable. âloadProductsâ could be a part of protocol. This protocol can have default implementation to get products. Both home and business products view controllers can adhere to this protocol. and we can just pass enum value i.e. home or business to loadProducts with a callback. You will not need to inject singleton network client to view controller. This will make the code more testable as we can easily mock the service by implementing the same protocol.
Regarding @kostapappasâ point about dependency injection and your response:
I was also confused by your âInjectionsâ comment in the example code. I think both of you have valid points, but I tend to agree with @kostapappas. Dependency injection is at least in my understanding generally considered an alternative to using Singletons.
In fact this article is fairly explicit about it. It is titled âAvoiding Singleton Abuseâ, and a proposed solution is to use dependency injection.
All of which goes to show none of this is really set in stone. I would suggest however in future videos that when you make a potentially confusing comment like this in your code or when you create a variable like strongSelf, that you explain whatâs going on in the video.
By âdependency injection,â I was referring to passing dependencies into a consuming / using object, as opposed to having the logic coupled / built into the object itself.
In this albeit loose definition, using a âsingletonâ is a type of dependency injection⊠but letâs be honest, itâs a weak form of dependency injection at best, right?
That is, the consuming object still has issues such as tight coupling to the singleton, which âgoodâ dependency injection avoids (see SOLID â Dependency Inversion Principle).
If this was a full-fledged app in production that I would need to maintain and support over time, I would likely use Swinject and setup dependency injection containers to handle dependency configuration and injection.
I really wanted to cover dependency injection in depth as part of this series â from its simplest form of passing an object around to using dependency injection containers via libraries like Swinject â but alas due to time constraints, I wasnât able to cover it.
Perhaps in a future revision of this series, this topic can be covered and given the time it deserves. :]