Now this is the best iOS architecture video that was ever created, even 3 years after creation and probably will still remain on the top till the end of this platform XD
I like how you explain things from the mistakes that most developers made, and then show the correct ways of doing things. And the example is very simple so it is easier for me to digest. I hope it'll go to a more complex examples in a real world application so I can understand it completely and start implementing the whole things. Currently I still don't have the courage to try it out because when the problem gets a little complex, I usually get confused and lost. :|
Hi Tity, we're glad you enjoyed and learned something with us! All our examples have been used in real-world applications. For instance, Neat Trivia www.essentialdeveloper.com/neat-trivia relies heavily on composition. We find ways to break complexity into a bunch of simple tasks and solve them one by one. Composition is the key to combine the simple solutions to solve the complex problem. Stay tuned for more! ✅
First of all well dont for the amazing videos you share with us. Also I would like to ask something. When you are composing the concrete types you are adding the into an array. Isn't this creating a strong reference cycle?
Thank you, Marsel! The composite holds a strong reference to the concrete types since they're inside the array. But that's exactly what we want to keep all those instances in memory for as long as the composite exists. The concrete types inside the array don't hold a reference to the composite - so there's no retain cycle ✅
Hi Caio, thanks for putting up such helpful videos and I really likes your approach. Kudos! I had couple of doubts, if you could clarify. 1. Are the wrapper classes singleton? 2. Where do I need to init these SDKs/Frameworks 3. How to resolve the problem of different SDKs taking different type of meta structure. Otherwise, if you could provide a sample, then it would be much helpful. Thanks again!
Hi Kushal, thank you! ## 1. Are the wrapper classes singleton? No. ## 2. Where do I need to init these SDKs/Frameworks. In the Composition Root. th-cam.com/video/cnHo2-gxqIQ/w-d-xo.html ## 3. How to resolve the problem of different SDKs taking different type of meta structure The Wrappers (aka Adapters) are responsible for 'adapting' the communication between your app and the frameworks. So, that's the place where you can convert the app request to the framework request structure. And also translate the framework response into a structure the app expects. ✅
@@EssentialDeveloper I am really impressed with the way you describe things in your video tutorial, but for novice developer like me its very difficult to understand without seeing actual code. Thats why i am requesting if you can share your sample xcode project or github repo link with me.
Thanks Caio, for explaining the composer and factory. So it is the factory that creates actual concrete instances of protocols and establishes a link between them, great. So does it mean: 1. It is a factory that also links (LoginPresenter & LoginViewController), (Any Analytics wrapper & LoginViewController) etc. Because whatever LoginPresenter, analytics wrapper was created, exactly those need to be used in LoginViewController also. 2. It is the factory that is creating the whole login flow, then it has to know all the players involved in the flow, how to create them and also their dependencies. For ex. LoginUseCase needs a networkManager to get remote data. LoginPresenter needs an output of type LoginView and so on. 3. Who should actually talk to the factory? Is it the app delegate in this case? 4. Does it mean every business flow requires some kind of factory/assembler? I know it's a lot I am asking but it would be great if you can answer or point me towards something that answers these.
Hello, Tarun Sharma. The goal is to create a flexible, maintainable, and scalable architecture, so separating type creation and composition from use cases, presenters, views, etc., is very important. We've covered all those questions on our free 'Professional iOS Engineering Season 1' series - www.essentialdeveloper.com/professional-ios-engineering-season-1.
Hi Caio, thank you for this content! The things you are explaining are fascinating, though I feel like I'm missing some core concepts to fully understand everything. I've been doing iOS for about 3.5 years, though only about 1 year full-time. Do you have any tips on where to learn more about composers and factories, what they're for, and how to use them?
Hi! In this context, both can be used to distribute messages to many objects. You'd use Composite when you want to compose many objects that share the same polymorphic interface. And Observer when you want to listen to events. ✅
Great series of videos. Nice job. One thing I'm wondering - in the video desription you advertise a FREE iOS course, yet when I try it and would like to take it, I need to enroll in a paid course. Am I doing something wrong or?
Hi Ivan, thank you for your support! That free course ended a couple of weeks ago. You can find the new one at www.essentialdeveloper.com/how-to-boost-your-ios-developer-income ✅
Hi Essential Dev. In java, we would call any object (in this case, the Presenter) conforming to the LoginUseCaseOutput protocol as a LoginUseCase Listener. In swift, we can call it (the Presenter) a LoginUseCase Delegate, right? I mean, is the notion of delegate in swift the same as listener in other languages like Java?
@@EssentialDeveloper No doubt naming is subjective. What I specifically asked is if Delegate. i.e. Delegation pattern, is the same as listener/observer pattern? My understanding, so far, suggests so..
Hey Abel, thanks! We can use the "generic compose function" to compose any function with matching signature. For example: func logEventOnCrashlytics(event: Event) {} func logEventOnFirebase(event: Event) {} let logEventOnCrashlyticsAndFirebase = compose([logEventOnCrashlytics, logEventOnFirebase]) logEventOnCrashlyticsAndFirebase(.loginEvent) ✅⛩
Hi Andres, it is ok, but we must be careful not to create unnecessary dependencies. If you ever need to decouple the use cases (for example, to reuse one of them in a separate module or another app) you might need to add a protocol in between or an adapter layer. ✅
Essential Developer team, Thanks for your answer, I really appreciate what you are doing for us. Btw I wrote an app based on the first three episodes of your Clean Architecture series, now I’m going to incorporate episodes 4 and 5. if you have the time, could you please record an episode to talk about MAIN/router implementation or how to interconnect the layers. I think that I’m doing it wrong based on the last five minutes of the “Core iOS Application Architecture Patterns” WWDC 2014 talk. At this moment in my code, all the interconnections are orchestrated by the AppDelegate, but I think it should be done by class, a router, something like an iOSRouter, in that way it would be easier to implement a factory that returns a router base on the OS the app will run, watchOS, macOS and so on, thanks.
Hi Andres, thanks for the support. We have a complete series where we create an app from scratch and discuss the architecture evolution as we go, including the Main and Router modules: www.essentialdeveloper.com/professional-ios-engineering-season-1. We believe you're on the right track to a clean codebase. Separating object creation from logic is an important step! In our series, we use the Abstract Factory Design Pattern to solve that problem.
What do you think about using frameworks like RXSwift at the business logic layer? e.g.: it can be used to send the output data of the use case to many other objects instead of making the composition of the delegates.
Hi Elias! Just like with any 3rd-party framework, we recommend keeping RxSwift away from high-level modules and business logic. But it's up to you and your team to decide if you're happy to couple your business logic with 3rd-party dependencies. What worked out well for us, was to decouple the high-level components from reactive frameworks, and only use it to compose the isolated modules in the Composition Root. This way, you reduce its impact on the overall architecture of the app. ✅
@@EssentialDeveloper if I may ask, isn't using this kind of output pattern for the use case an indicator that the ui design pattern that will be used is the MVP. Where will the ViewModel fit into this if that wasn't the case? Thanks.
No, the Use Case shouldn't enforce, know, or care about the UI design pattern. That's an implementation detail of the UI (you should be able to change the pattern without affecting the Use Case). A composition Adapter could implement the output protocol and communicate with a ViewModel, for example.
@@EssentialDeveloper if i may ask, how if we have chaining request? if we decouple framework like rxswift in business logic? for example our usecase depend on abstraction framework logic like url session, and url session doin chaining request using rx swift? how to handle that?
Hi! The business logic only communicates with the abstraction, so it doesn't know about implementation details. The request chaining is done in the implementation of the abstraction. The business logic doesn't need to know about the request chaining - all it needs is a result - regardless of how many requests are made/chained ✅
Hi Caio, First of all I wanna thank you for your enriching videos. Do you have patreon? I would love to donate some Dollars :) I’m a German computer science student and working part-time as an IOS developer. Lately, out of ever increasing interest, I have been working on software architecture. I started to learn routines to get better and better. Your videos have given me a lot of food for thought. I now have the following scenario, which has raised a question. I really like this software architecture divided into use cases, but I wonder where the login method of the LoginUseCase is called. The only thing that makes sense to me would be that this happens in the UI module, i.e. a ViewController, Viewmodel, etc., since the user is obviously the initiator of this login use case. In my case, I chose the variant where the UseCaseInput is reflected via a protocol, which the LoginViewModel then implements. And exactly at this point I'm just standing and wondering, how should I make the connection between LoginUseCaseInput and LoginUseCase, so that by user initiated actions the use case is played through. I hope you might be able to answer my question.
Hello! Thank you for your message. In this example, the Input protocol is implemented by the UseCase. You can find the answer in detail in the pt.2: th-cam.com/video/C2GyNTN4j4o/w-d-xo.html
@@EssentialDeveloper Yo thank you for your answer. I watched the pt2. at least 3 times, but I didn't find the answer to my question. It might be a lack of understanding. Therefore I asked the question: "Who would call the login-method?" to this video, because here you talking about some concrete code, which is easier to understand for me. Maybe you could explain, how a user-interaction would deliver the Input to the Usecase. But don't feel pressured by me, I'm grateful enough for your videos. Thanks in advance.
At around 22min in the pt.2 video we show how the view controller can send the messages / call the methods on the Input protocol. It can also be done indirectly through closures as we show later in the same video.
Great video. Loving the series and the channel as a whole. Have linked to it on the Slack channel for the Clean Swift Mentorship program (clean-swift.com/mentorship/), as it is really close to the Clean Swift architecture presented there. Will have to watch the video a few times for it all to sink in, but really great content and answered some questions raised by episode 2. Many thanks.
Hey Andrey. The PDF material is very good, and the Slack channel-while not super-busy-is quick to respond, full of interesting content, and if you want to know more lots of helpful people. Like most of these things, the more you put into it the more you can get out, but I've certainly got some interesting feedback, ideas and content out of it. You can always dip in and out as required, and maybe try it for a month or two and see how it works for you. You can always cancel if you don't think you are getting value after that.
Now this is the best iOS architecture video that was ever created, even 3 years after creation and probably will still remain on the top till the end of this platform XD
Thanks, Piotr!
It's the best way to understand complicated things in a simple way that I've seen in my life.
I like how you explain things from the mistakes that most developers made, and then show the correct ways of doing things. And the example is very simple so it is easier for me to digest. I hope it'll go to a more complex examples in a real world application so I can understand it completely and start implementing the whole things. Currently I still don't have the courage to try it out because when the problem gets a little complex, I usually get confused and lost. :|
Hi Tity, we're glad you enjoyed and learned something with us! All our examples have been used in real-world applications. For instance, Neat Trivia www.essentialdeveloper.com/neat-trivia relies heavily on composition. We find ways to break complexity into a bunch of simple tasks and solve them one by one. Composition is the key to combine the simple solutions to solve the complex problem. Stay tuned for more! ✅
I had read many of those things you said in the video but I completely understand the principles after your applying of them in code
First of all well dont for the amazing videos you share with us.
Also I would like to ask something. When you are composing the concrete types you are adding the into an array. Isn't this creating a strong reference cycle?
Thank you, Marsel! The composite holds a strong reference to the concrete types since they're inside the array. But that's exactly what we want to keep all those instances in memory for as long as the composite exists. The concrete types inside the array don't hold a reference to the composite - so there's no retain cycle ✅
Hi Caio! Great series! Looking forward to any new videos from you team. Thanks!
Thanks!
Hi Caio, thanks for putting up such helpful videos and I really likes your approach. Kudos!
I had couple of doubts, if you could clarify.
1. Are the wrapper classes singleton?
2. Where do I need to init these SDKs/Frameworks
3. How to resolve the problem of different SDKs taking different type of meta structure.
Otherwise, if you could provide a sample, then it would be much helpful. Thanks again!
Hi Kushal, thank you!
## 1. Are the wrapper classes singleton?
No.
## 2. Where do I need to init these SDKs/Frameworks.
In the Composition Root. th-cam.com/video/cnHo2-gxqIQ/w-d-xo.html
## 3. How to resolve the problem of different SDKs taking different type of meta structure
The Wrappers (aka Adapters) are responsible for 'adapting' the communication between your app and the frameworks.
So, that's the place where you can convert the app request to the framework request structure. And also translate the framework response into a structure the app expects. ✅
@@EssentialDeveloper I really appreciate, if you have some sample that can cover all these problems and can share it with us.
The Adapter pattern ↴
th-cam.com/video/xLkBrCJaDHU/w-d-xo.html
Composition Root ↴
th-cam.com/video/cnHo2-gxqIQ/w-d-xo.html
Our series demonstrating those concepts ↴
th-cam.com/play/PLyjgjmI1UzlSUlaQD0RvLwwW-LSlJn-F6.html
@@EssentialDeveloper I am really impressed with the way you describe things in your video tutorial, but for novice developer like me its very difficult to understand without seeing actual code. Thats why i am requesting if you can share your sample xcode project or github repo link with me.
Here it is: github.com/essentialdevelopercom/quiz-app
Thanks Caio, for explaining the composer and factory. So it is the factory that creates actual concrete instances of protocols and establishes a link between them, great. So does it mean:
1. It is a factory that also links (LoginPresenter & LoginViewController), (Any Analytics wrapper & LoginViewController) etc. Because whatever LoginPresenter, analytics wrapper was created, exactly those need to be used in LoginViewController also.
2. It is the factory that is creating the whole login flow, then it has to know all the players involved in the flow, how to create them and also their dependencies. For ex. LoginUseCase needs a networkManager to get remote data. LoginPresenter needs an output of type LoginView and so on.
3. Who should actually talk to the factory? Is it the app delegate in this case?
4. Does it mean every business flow requires some kind of factory/assembler?
I know it's a lot I am asking but it would be great if you can answer or point me towards something that answers these.
Hello, Tarun Sharma. The goal is to create a flexible, maintainable, and scalable architecture, so separating type creation and composition from use cases, presenters, views, etc., is very important. We've covered all those questions on our free 'Professional iOS Engineering Season 1' series - www.essentialdeveloper.com/professional-ios-engineering-season-1.
Hi Caio, thank you for this content! The things you are explaining are fascinating, though I feel like I'm missing some core concepts to fully understand everything. I've been doing iOS for about 3.5 years, though only about 1 year full-time. Do you have any tips on where to learn more about composers and factories, what they're for, and how to use them?
Thanks! If you want to master those concepts, check out the iOS Lead Essentials program: iosacademy.essentialdeveloper.com/p/ios-lead-essentials/
Hi Caio. Thanks for the video. What do you think the pros and cons between Composer and Observer pattern?
Hi! In this context, both can be used to distribute messages to many objects. You'd use Composite when you want to compose many objects that share the same polymorphic interface. And Observer when you want to listen to events. ✅
Great series of videos. Nice job.
One thing I'm wondering - in the video desription you advertise a FREE iOS course, yet when I try it and would like to take it, I need to enroll in a paid course. Am I doing something wrong or?
Hi Ivan, thank you for your support! That free course ended a couple of weeks ago. You can find the new one at www.essentialdeveloper.com/how-to-boost-your-ios-developer-income ✅
The answers for my troubles which I couldn't even find words to ask properly 👍
Hi Essential Dev. In java, we would call any object (in this case, the Presenter) conforming to the LoginUseCaseOutput protocol as a LoginUseCase Listener. In swift, we can call it (the Presenter) a LoginUseCase Delegate, right? I mean, is the notion of delegate in swift the same as listener in other languages like Java?
Hi Deb. Naming is very subjective. Every team may call it differently. But Delegation is a specific pattern: en.wikipedia.org/wiki/Delegation_pattern
@@EssentialDeveloper No doubt naming is subjective. What I specifically asked is if Delegate. i.e. Delegation pattern, is the same as listener/observer pattern? My understanding, so far, suggests so..
They're not the same, but can be similar. For example, you can implement observers with delegation.
Thank you so much for such a great session
Glad you enjoyed it!
Hi Caio! Great videos, How you will use the generic compose function? That you implement in the last minutes of the video
Hey Abel, thanks! We can use the "generic compose function" to compose any function with matching signature. For example:
func logEventOnCrashlytics(event: Event) {}
func logEventOnFirebase(event: Event) {}
let logEventOnCrashlyticsAndFirebase = compose([logEventOnCrashlytics, logEventOnFirebase])
logEventOnCrashlyticsAndFirebase(.loginEvent)
✅⛩
Essential Developer, thanks for the quick reply. Keep doing the videos it's amazing how you guys manage to easily explain advanced topics
Awesome series! Thanks Caio!
Hi! Is it ok to use a use case from another use case?
Hi Andres, it is ok, but we must be careful not to create unnecessary dependencies. If you ever need to decouple the use cases (for example, to reuse one of them in a separate module or another app) you might need to add a protocol in between or an adapter layer. ✅
Essential Developer team, Thanks for your answer, I really appreciate what you are doing for us. Btw I wrote an app based on the first three episodes of your Clean Architecture series, now I’m going to incorporate episodes 4 and 5. if you have the time, could you please record an episode to talk about MAIN/router implementation or how to interconnect the layers. I think that I’m doing it wrong based on the last five minutes of the “Core iOS Application Architecture Patterns” WWDC 2014 talk. At this moment in my code, all the interconnections are orchestrated by the AppDelegate, but I think it should be done by class, a router, something like an iOSRouter, in that way it would be easier to implement a factory that returns a router base on the OS the app will run, watchOS, macOS and so on, thanks.
Hi Andres, thanks for the support. We have a complete series where we create an app from scratch and discuss the architecture evolution as we go, including the Main and Router modules: www.essentialdeveloper.com/professional-ios-engineering-season-1.
We believe you're on the right track to a clean codebase. Separating object creation from logic is an important step! In our series, we use the Abstract Factory Design Pattern to solve that problem.
What do you think about using frameworks like RXSwift at the business logic layer? e.g.: it can be used to send the output data of the use case to many other objects instead of making the composition of the delegates.
Hi Elias! Just like with any 3rd-party framework, we recommend keeping RxSwift away from high-level modules and business logic.
But it's up to you and your team to decide if you're happy to couple your business logic with 3rd-party dependencies.
What worked out well for us, was to decouple the high-level components from reactive frameworks, and only use it to compose the isolated modules in the Composition Root. This way, you reduce its impact on the overall architecture of the app. ✅
@@EssentialDeveloper if I may ask, isn't using this kind of output pattern for the use case an indicator that the ui design pattern that will be used is the MVP. Where will the ViewModel fit into this if that wasn't the case? Thanks.
No, the Use Case shouldn't enforce, know, or care about the UI design pattern. That's an implementation detail of the UI (you should be able to change the pattern without affecting the Use Case). A composition Adapter could implement the output protocol and communicate with a ViewModel, for example.
@@EssentialDeveloper if i may ask, how if we have chaining request? if we decouple framework like rxswift in business logic? for example our usecase depend on abstraction framework logic like url session, and url session doin chaining request using rx swift? how to handle that?
Hi! The business logic only communicates with the abstraction, so it doesn't know about implementation details. The request chaining is done in the implementation of the abstraction. The business logic doesn't need to know about the request chaining - all it needs is a result - regardless of how many requests are made/chained ✅
It is brilliant. Thanks.
Thanks Caio! This video helped me understand composition, which I otherwise failed to do through theory and definitions. Many thanks 🙏 😀
Hi Mansi! Glad it was helpful ✅
Watching you code is like watching pro starcraft players
thanks a lot, i love simplicity
Hi Caio,
First of all I wanna thank you for your enriching videos. Do you have patreon? I would love to donate some Dollars :)
I’m a German computer science student and working part-time as an IOS developer. Lately, out of ever increasing interest, I have been working on software architecture. I started to learn routines to get better and better. Your videos have given me a lot of food for thought.
I now have the following scenario, which has raised a question.
I really like this software architecture divided into use cases, but I wonder where the login method of the LoginUseCase is called.
The only thing that makes sense to me would be that this happens in the UI module, i.e. a ViewController, Viewmodel, etc., since the user is obviously the initiator of this login use case.
In my case, I chose the variant where the UseCaseInput is reflected via a protocol, which the LoginViewModel then implements. And exactly at this point I'm just standing and wondering, how should I make the connection between LoginUseCaseInput and LoginUseCase, so that by user initiated actions the use case is played through.
I hope you might be able to answer my question.
Hello! Thank you for your message. In this example, the Input protocol is implemented by the UseCase. You can find the answer in detail in the pt.2: th-cam.com/video/C2GyNTN4j4o/w-d-xo.html
@@EssentialDeveloper Yo thank you for your answer. I watched the pt2. at least 3 times, but I didn't find the answer to my question. It might be a lack of understanding. Therefore I asked the question: "Who would call the login-method?" to this video, because here you talking about some concrete code, which is easier to understand for me.
Maybe you could explain, how a user-interaction would deliver the Input to the Usecase. But don't feel pressured by me, I'm grateful enough for your videos. Thanks in advance.
At around 22min in the pt.2 video we show how the view controller can send the messages / call the methods on the Input protocol. It can also be done indirectly through closures as we show later in the same video.
Great video. Loving the series and the channel as a whole. Have linked to it on the Slack channel for the Clean Swift Mentorship program (clean-swift.com/mentorship/), as it is really close to the Clean Swift architecture presented there. Will have to watch the video a few times for it all to sink in, but really great content and answered some questions raised by episode 2. Many thanks.
Hi Andy, thank you for your support!
Hi Andy! I'm also thinking about to by clean-swift bundle, but I have a little doubt. Could you please share your opinion about it?
Hey Andrey. The PDF material is very good, and the Slack channel-while not super-busy-is quick to respond, full of interesting content, and if you want to know more lots of helpful people. Like most of these things, the more you put into it the more you can get out, but I've certainly got some interesting feedback, ideas and content out of it. You can always dip in and out as required, and maybe try it for a month or two and see how it works for you. You can always cancel if you don't think you are getting value after that.
Thanks
wish I watched this 2 years ago... Otherwise I wouldn't write that much shitty code.