<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Vinodh Swamy on Medium]]></title>
        <description><![CDATA[Stories by Vinodh Swamy on Medium]]></description>
        <link>https://medium.com/@vinodhswamy?source=rss-507a15c0b921------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*6QGvnmZ5_EiECLd4Go0yAA.jpeg</url>
            <title>Stories by Vinodh Swamy on Medium</title>
            <link>https://medium.com/@vinodhswamy?source=rss-507a15c0b921------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 18 Oct 2026 22:04:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@vinodhswamy/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Mobile App Architectural Best Practices in Action [User Story 2]]]></title>
            <link>https://levelup.gitconnected.com/mobile-app-architectural-best-practices-in-action-user-story-2-4a3ffaca92bc?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a3ffaca92bc</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[architecture]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Mon, 01 Jan 2024 21:56:24 GMT</pubDate>
            <atom:updated>2024-02-02T04:26:41.916Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v8fho6znkjmsikKgCs_Z4g.png" /><figcaption>Above UI Image Credit to <a href="https://dribbble.com/glmrvn">Alex Dyakov</a> from Dribble.com</figcaption></figure><p>Welcome to “Mobile: Architectural Best Practices in Action” — a series where we embark on a journey through the intricate world of mobile application development. In this series, we won’t just talk theory; we’ll roll up our sleeves and dive into real-world scenarios, use cases, and challenges that developers often face.</p><p><strong>What to Expect:</strong></p><p>In each instalment, we’ll pick a specific user story, a scenario, or a use case that reflects the complex landscape of mobile app development. But we won’t stop at merely identifying the challenge — we’ll approach it with an architectural mindset, dissecting the problem and crafting a robust solution.</p><p><strong>Why Architectural Mindset Matters:</strong></p><p>Why do we bother with an architectural mindset? Because in the dynamic and fast-paced world of mobile development, it’s not just about getting the app to work; it’s about crafting a solution that stands the test of time, scales gracefully, and remains maintainable as your app evolves.</p><p><strong>Diving into the Design:</strong></p><p>We’ll talk about design patterns, styles, and best practices. But here’s the deal — we won’t always take the easy road. We’re going to chat about why we choose one design over another, even if it seems a bit tougher. It’s about making smart choices for great results.</p><p><strong>Join the Conversation:</strong></p><p>This series isn’t just about me sharing insights; it’s a conversation. I invite you to engage, ask questions, and share your own experiences. Let’s learn together as we resolve the complexity of mobile architectural design.</p><p>With that, let us get into our 2nd user story.</p><p>Checkout the previous one <a href="https://medium.com/gitconnected/mobile-architectural-best-practices-in-action-user-story-1-e20c9efa7549">here</a>.</p><h3>User Story 2</h3><p>Ask is for implementing the upcoming feature similar to Instagram stories, on existing chat application’s like Teams, Telegram, etc. we would be needing to create infrastructure for fetching and viewing user-specific stories. Although the exact UI design is pending finalisation, mobile-dependent APIs are available for retrieving user stories in JSON format, also supports SSE for new updates on the stories.</p><p><strong>Acceptance Criteria:</strong></p><p><strong>Fallback to Local Content</strong>: In cases where remote content cannot be fetched due to network issues or API unavailability, the system should gracefully fall back to fetching and presenting content from the local database, also make network call if only there is updated data.</p><p><strong>Efficient Data Sync Mechanism</strong>: Implement an efficient data synchronisation mechanism to keep the local content up-to-date, reflecting changes made remotely when connectivity is restored.</p><p><strong>Transparent Handling of Failures</strong>: The user should not experience disruptions or errors when transitioning from remote to local content. Any failures during remote fetching should be handled transparently, providing a smooth transition to local content.</p><p><strong>Develop as Individual Module</strong>: Develop the Stories Data components as independent module, the presentation/ui module should not be aware of the implementation details on this data components.</p><p><strong>Unit Testing</strong>: Should be able to mock the data easily, should be able to unit test every component involved in the user stories feature.</p><h3>Approach</h3><p>let’s break down and analyze the given requirement</p><p><strong>Objective</strong>: Develop infrastructure components for the app to fetch the <strong>User Stories</strong> and display them on the UI.</p><p><strong>Components Responsibilities</strong>:</p><ol><li>Fetch User Stories from Web ➔ Should be able to fetch the latest user stories json from end point, fetching all the stories respective to the particular user.</li><li>Fetch User Stories from Local DB ➔ Should support for saving the stories to local DB, and fetch them always from local, if the data is not changed on the remote web side.</li><li>Maintain consistent data between web and local.</li></ol><p><strong>Existing Infrastructure</strong>:</p><ul><li>There’s an API endpoint /me/userStories exist which returns the user stories json.</li><li>The above api is paginated, supports default page of 20</li><li>There is SSE support endpoint available on the app receiving updates on the stories.</li><li>Since the feature is on existing app, there will be NetworkHandler, or equivalent classes which uses URLSession, already handling the token exchange, some similar classes handling the databases operations like coredata or sql.</li></ul><h3>Key Considerations:</h3><ol><li>UI is not finalised yet, which means we have to design the infrastructure independent of the presentation layer.</li><li>Since there is logic of relying on local data first and then remote web data if the data has updated, we need a single source of truth for Presentation layer always rely on, the data expiry and updation should be taken care from the Infrastcuture side.</li><li>Fetching of stories is asynchronous, either local or remote, there should option for presentation layer to inform which thread the data should respond, so it can handle the UI updation smooth.</li></ol><p>Now lets relate this work with <strong>Clean Architecture</strong> layers, <strong>Presentation, Domain and Data layers, </strong>based on the requirement it is pretty clear the UI is not final we would not be working on the UI, rather we would be focusing on the Domain and Data layer, and more precisely we will be focusing on the Data layer.</p><p>We need to develop the data layer infrastucture for stories data, the presentation layer should be un aware of the these data layer details, rather should only be aware of the domain details, this exactly fits Repository Pattern which works closely with the Clean Architecture.</p><p>Repository pattern is a software design pattern that provides an abstraction of data, so that your application can work with a simple abstraction that has an interface. Using this pattern can help achieve loose coupling and can keep domain objects like Core Data / Room / Realm</p><p>It also makes code more testable as it allows us to inject as a dependency a mock repository that implements that defined interface.</p><p>lets not get into deeper on the what is repository pattern, rather we will implement the User Stories Data layer using Repository Pattern.</p><p>Lets declare what the presentation layer will be interacting with, the domain layer interfaces/protocols which is basically the Use cases, and Value Types</p><pre>protocol FetchUserStoriesUsecase {<br>    func fetchStories(userId: String,<br>                    pageInfo: Int) async -&gt; Result&lt;[UserStory], FetchUserStoriesError&gt;<br>}<br><br>protocol ViewUserStoriesUsecase {<br>    func fetchFullStoryDetails(userId: String, <br>                               storyId: String) async -&gt; Result&lt;UserStoryDetails, ViewUserStoriesError&gt;<br>}<br><br>protocol SyncUserStoriesUsecase {<br>    func syncUserStories(userStories: Data) async -&gt; Result&lt;Bool, SyncUserStoriesError&gt;<br>}</pre><p>There are 3 use cases,</p><ol><li>FetchUserStoriesUsecase: When we land on the particular screen fetching all the stories.</li><li>ViewUserStoriesUsecase: When user click on particular story, go ahead and mark the user story as viewed, which would use remote client to update.</li><li>SyncUserStoriesUsecase: Syncing the user stories from remote to mobile client and vice versa, currently the syncing part from mobile client to remote is updating the viewed part of the story, and from the remote part is fetch the latest and updated stories whenever we receive the SSE from the backend api.</li></ol><p>Also we can see in the above declaration that the value types (UserStory, UserStoryDetails, FetchUserStoriesError, ViewUserStoriesError)</p><p>Now lets declare the interfaces/protocols what the domain layer would be interacting with, the data later interfaces/protocols, which is basically the Repositories.</p><pre>protocol StoriesRepository {<br>    func fetchStories(userId: String,<br>                    pageInfo: Int) async -&gt; Result&lt;[UserStory], StoriesRepositoryError&gt;<br>    func fetchFullStoryDetails(userId: String,<br>                     storyId: String) async -&gt; Result&lt;UserStoryDetails, StoriesRepositoryError&gt;<br>    func markViewed(storyId: String) async -&gt; Result&lt;Bool, StoriesRepositoryError&gt;<br>}</pre><p>The interface of the StoriesRepository is pretty simple, we need to support both the use cases, fetching all stories, and fetching full details on the particular story.</p><p>Lets have quick look on how the above protocols looks on the over app architecture.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PzglWwN41U7Dzcux07ei0A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1k4GWBeLZ_4467wGBUbg-A.png" /></figure><p>This is how we integrate the User Stories feature interfaces with Clean Architecture. As illustrated in the Clean Architecture graph, the application consists of different layers. The cardinal rule is to avoid dependencies from inner layers to outer layers. Dependencies can only exist from outer layers inward, specifically from <strong>Presentation -&gt; Domain &lt;- Data layers.</strong></p><p>Before delving into the implementation, let’s explore what existing assets we can leverage from the app:</p><ul><li><strong>NetworkHandler</strong>: available, either fetched from the new Modular architecture in CoreKit (Infrastructure Module) or directly from the legacy App code. These services simply need to be utilized, adhering to Protocol/Interface segregation.</li><li><strong>DatabaseHandler</strong>: Similar to the network service, if the app already supports offline storage, there’s likely an existing database. It could be obtained from the new Modular architecture in CoreKit (Infrastructure Module) or from the legacy App code using CoreData. Again, the key is to use it via Protocol/Interface segregation.</li></ul><p>The significance of this lies in the implementation of the Stories feature within the clean architecture, regardless of whether the existing app follows clean architecture, any modular architecture, or is an older single-module app codebase. If the app adheres to clean or modular architecture, injecting the NetworkHandler and DatabaseHandler protocols into the Repositories becomes straightforward. In cases where the app doesn’t follow modular architecture, legacy code for network and database-related APIs can still be employed, applying the same principle of breaking direct dependency using Protocol/Interface segregation.</p><p>We can refer the previous blog for using the <a href="https://medium.com/gitconnected/mobile-architectural-best-practices-in-action-user-story-1-e20c9efa7549">legacy networkService for new User Address, User Orders Feature</a></p><pre>protocol DataBaseHandler {<br>    func fetchObjects&lt;DBObject: NSManagedObject&gt;(usedId: String) async throws -&gt; [DBObject]<br>}<br><br>protocol NetworkHandler {<br>    func fetchData&lt;Json: Decodable&gt;(urlRequest: URLRequest) async throws -&gt; Json<br>}</pre><p>The simplified protocol/interface signatures above will be used inside the Stories Data Layer to implement the StoriesRepository, as mentioned earlier. The actual implementation of these protocols can come from either the legacy codebase or a modular and clean architecture.</p><p>With this, let’s examine how the implementation of the User Stories feature interfaces with Clean Architecture.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PmH7PNwxQC9oMA0LqGz3tg.png" /></figure><p>At a high level, this is how the design of the Stories Data layer looks. Let’s iterate through each acceptance criterion and assess whether our architecture accommodates it or not</p><p><strong>Fallback to Local Content: </strong>The StoriesRepositoryImp has access to both LocalStoriesDataRepository and WebStoriesDataRepository. The internal implementation of StoriesRepositoryImp should be responsible for validating local data first and deciding whether to make a web call. It can also handle the use case of relying on local data if it exists in the event of a failed network web API call.</p><p><strong>Efficient Data Sync Mechanism: </strong>We support Server Sent Events (SSE). Since SSE is limited to receiving UTF encoded text, the mobile client will receive events whenever there are new stories updated or when a user views stories on other devices or platforms. The SyncUserStoriesUsecase implementation will receive these events which will contain the updated stories json, which the use case passes it to StoriesRepository to update the data layer</p><p><strong>Transparent Handling of Failures</strong>: Errors specific to the module and domain level are visible. This means that we will log as well as send all types of error information to the root, allowing the presentation layer to act accordingly.</p><p><strong>Develop as Individual Module</strong>: The StoriesRepository, the source of truth for user stories data in the app, is developed as a separate module within the data layer of the clean architecture. Following clean architecture principles, the presentation layer has a dependency on the domain layer, specifically the Fetch/View/Sync UserStoriesUsecases. They are not aware of the repositories at all.</p><p><strong>Unit Testing</strong>: Let’s check feasibility unit testing from the data layer to the domain and presentation.</p><p><strong>Data Layer</strong></p><ul><li>LocalStoriesDataRepositoryImp: Has injected dependencies of DatabaseHandle. We can inject a mock class or value type confirming to DatabaseHandle for unit testing without making a DB call.</li><li>WebStoriesDataRepositoryImp: Similar to the above, it has a constructor dependency injected for NetworkHandle. We can inject a mock class or value confirming to NetworkHandle for unit testing without making an actual network call.</li><li>StoriesRepositoryImp: This has only one type (StoriesRepository) of dependency, which is taken as two properties in the init constructor injected dependency. We can mock StoriesRepository and inject it to unit test the StoriesRepositoryImp.</li></ul><p><strong>Domain Layer</strong></p><ul><li>FetchUserStoriesUsecase, ViewStoriesUsecase, SyncUserStoriesUsecase: All three use cases depend on the StoriesRepository, declared in the Domain Module itself. We can constructor inject it and unit test the above use cases. SyncUserStoriesUsecase may depend on the interface or service providing the SSE to it, and we can similarly mock it for unit testing.</li></ul><p><strong>Presentation Layer</strong></p><ul><li>Nothing is implemented yet, but we have built the `UserStories` data infrastructure. All the ViewModels will depend on the StoriesUsecases from the domain module. The ViewModels can easily inject the mock implementation of these use cases and unit test the view business logic.”</li></ul><p>It appears that we’ve successfully met all the acceptance criteria. We approached the design of the new feature following the clean architecture blueprint, separating the data layer from the UI. All components are now testable using mocks. We’ve disentangled tight couplings, enhanced unit testing capabilities, and strengthened modularity.</p><p>As mentioned earlier, our exploration doesn’t conclude here. In the upcoming blog, we will delve into another real-world scenario, employing architectural best practices to address distinct challenges. As we progress in our exploration of mobile architecture, anticipate additional hands-on examples, practical insights, and strategies for developing resilient and scalable solutions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a3ffaca92bc" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/mobile-app-architectural-best-practices-in-action-user-story-2-4a3ffaca92bc">Mobile App Architectural Best Practices in Action [User Story 2]</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mobile: Architectural Best Practices in Action [User Story 1]]]></title>
            <link>https://levelup.gitconnected.com/mobile-architectural-best-practices-in-action-user-story-1-e20c9efa7549?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/e20c9efa7549</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[clean-architecture]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[design-patterns]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Tue, 05 Dec 2023 20:48:19 GMT</pubDate>
            <atom:updated>2023-12-26T14:08:50.725Z</atom:updated>
            <content:encoded><![CDATA[<h3>Mobile App Architectural Best Practices in Action [User Story 1]</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ESWbyRRCRbHSpEesONAYBA.jpeg" /></figure><p>Welcome to “Mobile: Architectural Best Practices in Action” — a series where we embark on a journey through the intricate world of mobile application development. In this series, we won’t just talk theory; we’ll roll up our sleeves and dive into real-world scenarios, use cases, and challenges that developers often face.</p><p><strong>What to Expect:</strong></p><p>In each instalment, we’ll pick a specific user story, a scenario, or a use case that reflects the complex landscape of mobile app development. But we won’t stop at merely identifying the challenge — we’ll approach it with an architectural mindset, dissecting the problem and crafting a robust solution.</p><p><strong>Why Architectural Mindset Matters:</strong></p><p>Why do we bother with an architectural mindset? Because in the dynamic and fast-paced world of mobile development, it’s not just about getting the app to work; it’s about crafting a solution that stands the test of time, scales gracefully, and remains maintainable as your app evolves.</p><p><strong>Diving into the Design:</strong></p><p>We’ll talk about design patterns, styles, and best practices. But here’s the deal — we won’t always take the easy road. We’re going to chat about why we choose one design over another, even if it seems a bit tougher. It’s about making smart choices for great results.</p><p><strong>Join the Conversation:</strong></p><p>This series isn’t just about me sharing insights; it’s a conversation. I invite you to engage, ask questions, and share your own experiences. Let’s learn together as we resolve the complexity of mobile architectural design.</p><p>With that let us get into our first user story.</p><h3>User Story 1</h3><p>We need to develop new UI components for the app, which will be part of the existing User Profile Screen.</p><ul><li>Account User Orders UI: Lists all recent user orders.</li><li>Account User Address UI: Lists all user addresses.</li></ul><p>Now, there’s a AccountService class extensively used in the mobile app. It&#39;s a legacy class, developed a while ago, singleton, and internally handles authentication, token exchange, and fetches data locally in case of offline mode. Here&#39;s a simplified version of the class:</p><pre>final class AccountService {<br>    <br>    static let shared: AccountService = AccountService()<br>    private init () {}<br> <br>    func fetchData(requestParam: UserRequestParam) async -&gt; (Data?, AccountServiceError?) {<br>        // The internal logic for fetching the data for the url<br>        // using network classes like urlsession, datatask<br>        return (Data(), nil)<br>    }<br>}</pre><h3>Approach</h3><p>let’s break down and analyze the given requirement</p><p><strong>Objective</strong>: Develop new UI components for the app to enhance the existing User Profile Screen.</p><p><strong>Components to Develop</strong>:</p><ol><li>Account User Orders ➔ UI Display a list of all recent user orders.</li><li>Account User Address UI ➔ Display a list of all user addresses.</li></ol><p><strong>Existing Infrastructure</strong>:</p><ul><li>There’s an AccountService class already in use within the mobile app.</li><li>It’s a legacy class, developed some time ago.</li><li>The class is implemented as a singleton.</li><li>It handles crucial functionalities:</li><li>Authentication &amp; Token exchange</li><li>Local data fetching (for offline mode)</li></ul><h3>Key Considerations:</h3><ol><li>Legacy Status: Since AccountService is acknowledged as a legacy class, indicating that it can be or soon a later replaced.</li><li>Singleton Pattern: The class is implemented as a singleton. Singletons, easy to use, but it gives us challenges such as tight coupling and reduced testability.</li><li>Functionality: The fetchData function is asynchronous, suggesting that it likely performs network operations. The AccountService handles local data fetching, indicating offline support.</li><li>Scope of UI Components:The new UI components are meant to be integrated into the existing User Profile Screen.</li></ol><p>Now, let’s create UserOrderListView and UserAddressListView – the two new UI components that will use the existing legacy service, AccountService.</p><p>Not a big fan of singleton, feel it is an anti pattern. Singletons can be ok. But if you are not careful, they aren’t just an anti-pattern.</p><p>Also for our feature and timeline, we don’t have bandwidth to develop new modular AccountService from scratch, we have to use the existing one.</p><p>An easy and tempting approach is to start the implementation by using AccountService.shared inside UserOrderListView or, if we are following MVVM, inside UserOrderListViewModel.</p><pre>class UserOrderListViewModel {<br>    <br>    func fetchOrders(userId: String) async -&gt; [OrderViewData] {<br>        let (orders, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(orderDetails))<br>        // Here the logic of converting data to type<br>        // Handling error<br>        return []<br>    }<br>}<br><br>class UserAddressListViewModel {<br>    <br>    func fetchAddress(userId: String) async -&gt; [AddressViewData] {<br>        let (address, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(addresses))<br>        // Here the logic of converting data to type<br>        // Handling error<br>        return []<br>    }<br>}</pre><p>While this approach works, it comes with disadvantages:</p><p><strong>Tight Coupling</strong>: Yea it looks like we have coupled the AccountService directly to the view models, since it was readily available, but we know the AccountService is legacy class, it will get deprecated after sometime, depends how much refactoring fund is available :P, what if we have new AccountService which is not singleton later stage, then we have get into these view models and make changes, cause low confidence on product, which will again cost development and testing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/759/1*aG3oVKP7iqudJmV2jYt33A.png" /></figure><p><strong>Unit testing: </strong>Say if we have to unit test the view models, which might reach to the network for fetching the user related information, which is time consuming, not required to unit test behaviour of the viewModel, then if we have to mock the AccountService singleton, which was kind not that hectic on Objective C, but in swift it lot difficult or we have to use 3rd party lib for mocking singleton in swift.</p><p><strong>Modularity</strong>: What if we are developing the new screens (`UserOrderListView` and `UserAddressListView`) in new module/framework, then the new framework has the direct dependency on the existing module which contains AccountService, which we dont want it, because the purpose of new module is ti keep it independant and easily shippable to other apps, if we have direct dependecy on the AccountService Module, we are forced to ship this new framework along with AccountService Module.</p><p>Ok, thats a lot of issues, on this easy fix, lets try extending the 2 seperate functions for fetching orders and addresses</p><pre>extension AccountService {<br>    func fetchOrder(userId: String) async -&gt; Result&lt;[UserOrders], UserOrdersError&gt; {<br>        let (orders, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(userId))<br>                // Here the logic of converting data to type<br>                // Handling error<br>        return Result.success([])<br>    }<br>}<br><br>extension AccountService {<br>    func fetchAddresses(userId: String) async -&gt; Result&lt;[UserAddresses], UserAddressesError&gt; {<br>        let (address, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(userId))<br>                // Here the logic of converting data to type<br>                // Handling error<br>        return Result.success([])<br>    }<br>}</pre><p>Now, we have two separate functions for two different use cases, still part of the same AccountService singleton.</p><p>As we can see in <strong>Clean Architecture </strong>graph, we have different layers in the application. The main rule is <em>not to have dependencies from inner layers to outers layers</em>. There can only be dependencies from outer layer inward.</p><p>After grouping all layers we have: <strong>Presentation, Domain and Data layers.</strong></p><p>Following a protocol-oriented approach, we can remove the dependency on AccountService from UserOrderListViewModel and UserAddressListViewModel, also I would remove the import and impressions related to AccountService from the UserOrderListViewModel &amp; UserAddressListViewModel</p><pre>class UserOrderListViewModel {<br>    private let orderService: FetchUserOrder<br>    init(orderService: FetchUserOrder) {<br>        self.orderService = orderService<br>    }<br><br>    func fetchOrders(userId: String) async -&gt; [OrderViewData] {<br><br>    }<br>}<br><br>class UserAddressListViewModel {   <br>    private let addressService: FetchUserAddressess<br>    init(addressService: FetchUserAddressess) {<br>        self.addressService = addressService<br>    }<br><br>    func fetchAddress(userId: String) async -&gt; [AddressViewData] {<br><br>    }<br>}</pre><p>Thats fine, we have removed the impressions of AccountService Singleton, but we have not implemented how to get the user order list or user address. And we can see there are use case declared and injected to the respective viewmodel, FetchUserOrder use case for fetching user orders, FetchUserAddressess usecase for fetching user address.</p><p>Ok, now UserOrderListViewModel should use `FetchUserOrder` protocol interface to fetch user orders and UserAddressListViewModel should use `FetchUserAddressess` protocol interface to fetch user addresses, lets go and declare the functions on the protocols.</p><pre>protocol FetchUserOrder {<br>    func fetchOrder(userId: String) async -&gt; Result&lt;[UserOrders], UserOrdersError&gt;<br>}<br><br>protocol FetchUserAddressess {<br>    func fetchAddresses(userId: String) async -&gt; Result&lt;[UserAddresses], UserAddressesError&gt;<br>}</pre><p>Now lets use these functions inside the ViewModels to get the respective details, the view models will look like this</p><pre>class UserOrderListViewModel {<br><br>    private let orderService: FetchUserOrder<br><br>    func fetchOrders(userId: String) async -&gt; [OrderViewData] {<br>        let ordersResult = await orderService.fetchOrder(userId: &quot;userId&quot;)<br>        // Here the logic of converting data to type<br>        // Handling error<br>        return []<br>    }<br>}<br><br>class UserAddressListViewModel {<br>    <br>    private let addressService: FetchUserAddressess<br>    init(addressService: FetchUserAddressess) {<br>        self.addressService = addressService<br>    }<br>    <br>    func fetchAddress(userId: String) async -&gt; [AddressViewData] {<br>        let addressesResult = await addressService.fetchAddresses(userId: &quot;userId&quot;)<br>        // Here the logic of converting data to type<br>        // Handling error<br>        return []<br>    }<br>}</pre><p>Cool, we have things sorted from the newly created view models, we <strong>don’t have tight coupling</strong> with AccountService singleton, and we <strong>can inject the LocalMocks</strong> confirming to FetchUserOrder and FetchUserAddresses to unit test UserOrderListViewModel &amp; UserAddressListViewModel.</p><p>But who is going to get the details, since we have no new service for user related details, have to use the existing AccountService singleton, if we scroll up we can see we have extended the singleton AccountService with 2 functions</p><pre>fetchOrder(userId: String) and fetchAddress(userdId: String)</pre><p>Now we can connect the FetchUserOrder protocol to fetchOrder(userId: String) and FetchUserAddressess protocol to fetchAddress(userdId: String), which means we can make the<strong> </strong>AccountService<strong> singleton to confirm to FetchUserOrder and FetchUserAddressess</strong>, since it implements both the methods.</p><pre>extension AccountService: FetchUserOrder {<br>    func fetchOrder(userId: String) async -&gt; Result&lt;[UserOrders], UserOrdersError&gt; {<br>        let (orders, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(userId))<br>                // Here the logic of converting data to type<br>                // Handling error<br>        return Result.success([])<br>    }<br>}<br><br>extension AccountService: FetchUserAddressess {<br>    func fetchAddresses(userId: String) async -&gt; Result&lt;[UserAddresses], UserAddressesError&gt; {<br>        let (address, error) = await AccountService.shared.fetchData(requestParam: UserRequestParam(userId))<br>                // Here the logic of converting data to type<br>                // Handling error<br>        return Result.success([])<br>    }<br>}</pre><p>Now this same singleton should be injected in the ViewModels when getting created, which could be taking place in the Coordinator or App Main Module.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*UqvY-LpV_RGVE1JOQZ3TTg.png" /></figure><p>Now the above has solved Tight Coupling, Unit testing, Modularity problem, as you see <strong>we don’t have direct association with singleton </strong>AccountService, we can <strong>easily unit test the ViewModels injecting the mock </strong>for FetchUserOrder, FetchUserAddress, and we can <strong>reuse the same</strong> UserAddressListViewModel to different app, if this is <strong>extracted out as Module</strong>, by injecting the app specific implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/766/1*NlVCvkGhV8OiSbHpTJxorQ.png" /></figure><p>we’ve taken a close look at the challenges presented by the existing AccountService singleton. By adopting a protocol-oriented approach and embracing dependency injection, we&#39;ve untangled tight couplings, improved unit testing capabilities, and fortified modularity.</p><p>Our exploration doesn’t end here. In the next blog, we’ll dive into another real-world scenario, applying architectural best practices to solve unique challenges. As we continue our journey through mobile architecture, expect more hands-on examples, practical insights, and strategies for crafting resilient and scalable solutions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e20c9efa7549" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/mobile-architectural-best-practices-in-action-user-story-1-e20c9efa7549">Mobile: Architectural Best Practices in Action [User Story 1]</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Code Review Best Practise]]></title>
            <link>https://levelup.gitconnected.com/the-code-review-best-practise-cec57488ef25?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/cec57488ef25</guid>
            <category><![CDATA[code-review-process]]></category>
            <category><![CDATA[pull-request]]></category>
            <category><![CDATA[code-reviewing-guide]]></category>
            <category><![CDATA[code-newbie]]></category>
            <category><![CDATA[code-review]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Wed, 31 May 2023 06:35:53 GMT</pubDate>
            <atom:updated>2023-06-01T13:31:27.568Z</atom:updated>
            <content:encoded><![CDATA[<p>Code review is an important part of the software development process and can help improve code quality and help developers grow professionally. Here are some tips to follow a well-thought-out code review.</p><p>We usually classify them into 5 areas.</p><ul><li>Implementation Semantics</li><li>Api Semantics</li><li>Testability</li><li>Documentation</li><li>Code Style.</li></ul><p>If we represent the each area with technical importance vs the time spent, this is how it looks, also it quite evident that we spend most of time reviewing the implementation compared to technically less important items like code style and documentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NMxeQcSm9HzLJWHVsNscJQ.png" /><figcaption>Code Review Areas plotted with Time spent against Technical Importance</figcaption></figure><h3>API Semantics</h3><p>API semantics refers to the meaning and behavior of an API (Application Programming Interface), which is a set of protocols, classes &amp; modules for building software applications. When reviewing the semantics of an API, you would typically consider the following:</p><p><strong>Purpose</strong><em><br></em>What is the purpose of the API and what does it do?</p><p><strong>Inputs &amp; Outputs</strong><br>What are the inputs and outputs of the API? Are they well-defined and appropriate for the intended use case?</p><p><strong>Error Handling</strong><br>How does the API handle errors? Are the error messages clear and informative?</p><p><strong>Data Models:</strong><br>Are the data models used by the API well-defined and appropriate for the intended use case?</p><h3>Implementation Semantics</h3><p>Implementation semantics refers to the specific implementation of a piece of code, as opposed to the API semantics which define how the code is intended to be used. When reviewing the implementation semantics of a piece of code, you might consider the following:</p><p><strong>Code Structure:</strong><br>Does the code use encapsulation and modularisation to achieve separation of concerns? Are the components loosely coupled as much as possible.</p><p><strong>Code Efficiency:</strong><br>Is the code efficient in terms of runtime and memory usage? Are there any opportunities to optimize the code?</p><p><strong>Code Correctness:</strong><br>Does the code do what it is intended to do? Are there any bugs or issues that need to be addressed?</p><p><strong>Code Maintainability:</strong><br>Is the code easy to modify and maintain over time? Are there any potential issues that could make the code more difficult to work with in the future?</p><p><strong>Code Security:</strong><br>Does the code follow best practices for security? Are there any potential vulnerabilities that need to be addressed?</p><p><strong>Code Reusablity:</strong><br>Does the code use reusable components, functions, and services?</p><h3>Testablity</h3><p>Test coverage: Is the code adequately covered by tests? Are there any areas that are not adequately tested? Ensure that the test cases cover a wide range of possible inputs and scenarios, including both valid and invalid inputs.</p><p><strong>Independent</strong>:<br>Check that the test cases are independent from one another and do not depend on the execution order</p><p><strong>Easy to Understand:</strong><br>Verify that the test cases are easy to understand and maintain.</p><p><strong>Completeness:</strong><br>Make sure that the test cases are thorough and complete, covering all relevant functionality and edge cases.</p><p><strong>Organized:</strong><br>Check that the test cases are properly organized and grouped, with appropriate separation between different types of tests.</p><h3>Documentation</h3><p>Documentation: Is the code adequately documented? Are there any areas that could benefit from additional documentation?</p><p>On a personal note, I prefer the class/function/api/variable names should speak more about the functionality itself. but still on few cases we definitely need documentation when exposing the library api.</p><h3>Code Style</h3><p><strong>Use clear and concise code</strong>:<br>Write code that is clear and concise, rather than overly complex or unnecessarily verbose. This will make it easier for others to understand and maintain the code.</p><p><strong>Follow naming conventions:</strong><br>Follow naming conventions for variables, functions, and other code elements, as this will make it easier for others to understand and work with the code.</p><p><strong>Keep lines of code short:</strong><br>Try to keep lines of code short, as this will make it easier to read and understand the code.<br>Is the code well-formatted and easy to read? Are there any style guidelines in place that are being followed or violated?</p><h3>Additional Thoughts</h3><h3>Ensure your feedback justifies your stance</h3><p>When reviewing code, don’t simply suggest what needs to be fixed or improved upon — explain why the developer should make that change.</p><p>During development, you’ll mostly deal with problems that can be solved with multiple solutions. The comments you include in the code are a product of your knowledge and experience; you might prefer tackling an issue in a specific way, which may be different from the code author’s approach. Therefore, you should articulate your coding choices to explain your reasoning.</p><p>There are two benefits to this approach. First, the code’s author will know why they should make a particular change, which will help them tackle similar problems in the future. Second, since you already justified your comments, they won’t need to follow up with you about the reasoning behind your comment, saving both of you time.</p><h3>Don’t review more than 200–400 lines of code at a time</h3><p>Reviewing more than 400 lines of code (LoC) can have an adverse impact on your ability to find bugs, and in fact, most are found in the first 200 lines. This limitation affected industry practices after Cisco identified it in a comprehensive study on code review.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/886/1*QYITBUESzPBDDz3m3q7PFA.png" /><figcaption>Code Review: Defects Identified Against number of lines the code reviewed</figcaption></figure><p>The study found that, once developers reviewed more than 200 lines, their ability to identify defects waned (see the chart below).</p><p>It’s important to keep in mind that a code review is not just about finding problems, but also about identifying opportunities to improve the code and make it more maintainable in the long run.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cec57488ef25" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/the-code-review-best-practise-cec57488ef25">The Code Review Best Practise</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Design Code for Unit Testing]]></title>
            <link>https://levelup.gitconnected.com/art-of-unit-testing-with-swift-40bac64c1d9b?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/40bac64c1d9b</guid>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[unit-testing-tools]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[unit-testing]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Mon, 22 Nov 2021 07:57:12 GMT</pubDate>
            <atom:updated>2021-12-17T05:01:15.958Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vZq7mjQ_p-RUROnFVVIWNA.png" /></figure><p><strong>Unit testing</strong> is a type of automated testing meant to verify whether a small and isolated piece of the codebase the so-called “unit” behaves as the developer intended. An individual unit test is known as a “<strong>test case</strong>” — consists of a piece of code that exercises the production code in some way, and then verifies whether the result matches what was expected.</p><h3>Why Unit Testing?</h3><ul><li>Unit tests help to fix bugs early in the development cycle and save costs.</li><li>Reduces fragility — making changes in the existing code breaks another working part of code or flow, this can be reduced and identified during the development stage using proper unit testing.</li><li>Good unit tests serve as project documentation, a code snippet on tests explain more on how to use the class or function rather than a paragraph of documentation.</li><li>Unit tests help with code re-use. Migrate both your code and your tests to your new project. Tweak the code until the tests run again.</li></ul><h3>Tips for writing test</h3><p>There are 3 tips that I usually follow when writing tests in Swift.</p><ol><li>Design your code for testability</li><li>Clear API Boundaries</li><li>Avoid getting tied to Implementation Details</li></ol><p><em>Note: Examples I have used swift, but it’s not specific to swift, it’s more on functional programming tips for designing &amp; coding for unit testing.</em></p><h3>Design your code for testability</h3><p>What makes a code easy to test?</p><p>Well according to me, when we are not doing a lot of mocks or hacks or complex setups just to test a single API behaviour then it&#39;s easy to test. something like you gives ActivitiesPayloadResponse struct to ActivitiesViewModel and gets back the viewData from it, it could be activities total count test case or unread activity titles.</p><p>But, we don’t have every class or function simple as giving input data and verifying the output, there are places where we need to do mocks and setups, but let us try to keep it minimal. On other hand, think of someone reviewing our test, he should not spend more than 30 secs to understand it.</p><p>3 core principles for <strong>Designing Code for Testability</strong></p><blockquote>Unified Input and Unified Output</blockquote><p>In the functional programming world, there is a term called pure functions, pure function is a functions which takes inputs and returns an output with no side effects, the same input should generate the same expected output every time, no matter how many times you call it.</p><blockquote>Keep the State Local</blockquote><p>We tend to use singleton in most places because it&#39;s easy to use and apple itself is using it in many places, singleton can be nice for sharing API&#39;s and for convenience, but it also leads to a dangerous pattern of sharing state.</p><blockquote>Dependancy Injection</blockquote><p>Always try to inject the dependant objects which are being used inside our class functions, which means we want to avoid accessing those objects in our implementations as a shared instance or creating and accessing local instance.</p><p>That&#39;s enough of the theory, let&#39;s get practical, I cannot sell this topic without experimenting with it.</p><p>Let’s see all the above principles with an example class called FileLoader, credits to John Sundell picked these intuitive examples from one of his talks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8vzBYO8_9HFq1Qt9GKA1wQ.png" /></figure><p>That&#39;s a FileLoader pretty decent class, it loads the file with the given fileName from the main bundle if exist else throws an error, also it caches the file, which is actually good, so we don&#39;t load from main bundle every time. Now let&#39;s apply the Design of <strong>Code for Testability</strong> to the above class and check if it&#39;s good for unit testing.</p><p><strong>Unified Input/Output</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vcNB5pMZoshGpkIcVe_srA.png" /></figure><p>The FileLoader takes fileName as input, and returns File if the file with filename exists in the main bundle, else throws. But if you see the implementation there are 3 possible outcomes from the function.</p><ul><li>The happy case where a file exist, returns the File loading it or from the cache.</li><li>Throws foundationKit error if the file is corrupted when converting the file to Data</li><li>We throw NSError if the file doesn’t contain the main bundle.</li></ul><p>Definitely, the output is not unified here, this is not satisfying the <strong>Unified Input/ Output</strong> principle</p><p><strong>Keep the State Local</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wn0b8WEUYk_MeuTzGsD9xg.png" /></figure><p>The FileLoader contains shared instance or singleton dependency as you can see Bundle.main and shared FileLoader, we are not keeping the state local. As is clearly evident that the function is not obeying the <strong>Keep the State Local</strong> principle.</p><p>Dependency Injection</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hz7xkmXupqOsbxNTsoRFCw.png" /></figure><p>The FileLoader depends on 2 objects here, one is the cache and the other in the Bundle, and as you can see none of them is injected as dependency, it is accessed locally or using a singleton, which will kind of makes us difficult to test.</p><p>That&#39;s interesting right our decent FileLoader class is no more decent for unit testing, so let see how can we make it obey the <strong>Code for Testability</strong></p><h3>Applying Code for Testability Principles</h3><p>Let us take it one by one, will try to make the FileLoader obey Unified Input/Output principle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MwdVqvAJxRQzfmzfSUAY7w.png" /></figure><p>Here if you see, there is a dedicated error type for FileLoader, where it returns FileLoaderError.invalidFileName for invalid fileName error and FileLoaderError.invalidFileData for corrupted file data, whereas previously we were returning the NSError or the Error is thrown from the try Data(contentURL:), this way have modified the code take unified Input (FileName String) and unified Output (File or FileLoaderError).</p><p>Next let&#39;s try to remove the shared instance, do we really need <br>static let shared = FileLoader()</p><p>Many times we use it because it is easy to access and use, if we think, we might not need a singleton here instead every class that needs it can create and get the file loading operations, or it can be passed as a reference to the classes where it is required.</p><p>The last one the Dependancy Injection, as pointed out earlier we have 2 dependency objects (Cache and Bundle) used by FileLoader.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mixbO9DJDVLtkxmdJucXoA.png" /></figure><p>With this change, we are passing the dependant objects as an initial parameter so this will be super helpful when we are writing unit test for the same, this doesn’t have to be the object itself, it can be 2 protocols if required and also since we are supporting default parameters, the users of FileLoader other than Unit Testing need not worry about injected parameters, they can still create just as FileLoader().</p><p>We did very minimal changes to code, now kind of the FileLoader has changed from <strong>Hard to Test</strong> <strong>→</strong> <strong>Easy to Test</strong>. Now that I claim it&#39;s easy to Test you guys trust me? Not required let&#39;s write some tests for FileLoader and see is it really easy to Test.</p><p>We will try to test caching behaviour of our FileLoader couple of ideal behaviours coming to mind are</p><ul><li>Save file to cache when loading the file first time from bundle</li><li>Retrieve a file from the cache when the file already exists in the cache.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-R49QPJxKObT5LSeWuXR2Q.png" /></figure><p>There can be many cases, just picking these to explain stuff related dependency injection of cache.</p><ul><li>The 1st test case is for unit testing if the file loaded by FileLoader is saved into cache or not. Because our FileLoader’s one of the cool features is, it caches the files once loaded from Main Bundle.</li><li>The 2nd test case is for unit testing if the file accessed by FileLoader is retrieved from cache or not, say we have dependant cache containing the same file already and injected to FileLoader, now if the file is accessed by FileLoader it should return the file from Cache instead of loading from the main bundle.</li></ul><h3>Clear API Boundaries</h3><p>When we usually write a test, we tend to write a couple of types, 1 is a unit test where we verify if the API works correctly or not, validating the output against the given input, the other test is where we actually integrate modules and do an integration test.</p><p>Many times it is difficult to identify the clear boundary between unit and integration tests. If we look at <strong>Michael Feathers</strong> (Author of Working Effectively with Legacy Code) definition of Unit Testing.</p><p>A test is not a unit test if:</p><ul><li><em>It talks to the database</em></li><li><em>It communicates across the network</em></li><li><em>It touches the file system</em></li><li><em>It can’t run at the same time as any of your other unit tests</em></li><li><em>You have to do special things to your environment (such as editing config files) to run it</em></li></ul><p>Ok, Ok, Thats fine, but why?</p><p>Here is what his explanation are.</p><p>First, <strong>speed</strong>. When it comes to unit testing best practices, speed is the most important of them. Relying on things like the database or the network slows tests down.</p><p>Then, we have <strong>determinism</strong>. A unit test must be deterministic. That is to say, if it’s failing, it has to continue to fail until someone changes the code under test. The opposite is also true: if a test is currently passing, it shouldn’t start failing without changes to the code it tests. If a test relies on other tests or external dependencies, it might change its status for reasons other than a code change in the system under test.</p><p>Finally, we have the <strong>scope of the feedback</strong>. An ideal unit test covers a specific and small portion of the code. When that test fails, it’s almost guaranteed that the problem happened on that specific portion of the code. That is to say, a proper unit test is a fantastic tool for obtaining super precise feedback.</p><p>If on the other hand, a test relies on the database, the file system, and another test, the problem could be in any one of those places.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/896/1*jIV4yojCQJjCCyXJwus8yw.png" /></figure><p>As shown in the above picture, there are 2 modules User Profile Module (UI related to UserProfile) and User DB Repo (Database Module) which are been tested individually with inputs and validated using asserts.</p><p>When we are unit testing the UserProfile Module, definitely we would not be using the UserDBRepo instead we mock the UserDBRepo interface in UserProfile Module and unit test, which way we are not making DB or file system calls.<br>Again when unit testing the UserDBRepo Module, we would be injecting in-memory mock DBHandle which handles DB CRUD operations, using which we can unit test all possible APIs for UserDBRepo Interface.</p><p>But when it comes to testing UserProfile Module using UserDBRepo, this is usually not a unit test it is an integration test, and it&#39;s not that we should not write these tests at all, it would be good to write these tests, but often these tests are slow and not reliable, when the project grows, these integration test will consume a lot to time to build and run the entire test suite, and sometimes if the test fails, we are not sure which module has caused the failure.</p><h3>Avoid getting tied to Implementation Details</h3><p>Testing behaviour means testing <strong>what code does</strong>. Testing implementation means testing <strong>how code works</strong>. So which one we should be testing?</p><p>Testing Behaviour OR Testing Implementation</p><h3>Unit Testing On Behaviour</h3><p>When you write tests for behaviour, you can refactor your code (the implementation) in confidence without breaking the tests, the tests only break when behaviour has changed (unintentionally — which means you’ve introduced a bug or intentionally code has new changes, which means tests need to be updated to the new behaviour).<br>These types of tests are extremely valuable because a broken test means your code is broken.<br>Testing behaviour <strong>guarantees</strong> your code works as expected (for the behaviour you have tested).</p><h3>Unit Testing on Implementation</h3><p>When you write tests for implementation, tests break when you change code, even if the behaviour didn’t change.<br>These types of tests aren’t very valuable because a broken test doesn’t mean your code is broken and a passing test doesn’t mean your code works as expected.</p><p>Testing implementation only guarantees your code was written as it was tested.</p><h3>Applying Unit Testing on Behaviour of function/class instead of Implementation.</h3><p>Ok let us see this with an example, let consider simple class ImageViewController</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fDN4w8D6WmgYUsYV_Py4Ww.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zbQSuCJt8fk47njIUNyNfw.png" /></figure><p>That’s our ImageViewController, it has a dependant ImageLoader which loads the remote web images, and the ImageViewController sets the downloaded image to its imageView.<br>Now let&#39;s see what is the implementation steps looks like</p><ul><li>Step 1 ImageViewController creation</li><li>Step 2 Call loadRemoteImage from ImageLoader via reloadImageView for downloading images from remote web URL.</li></ul><p>If we write the test for the above implementation steps?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qLVzvGL__FM4LErd8cOKYQ.png" /></figure><p>Ok, we have mocked the ImageLoader to MockedImageLoader, yea that&#39;s there because we are loading the image from a network call, so understandable. We now inject the same to ImageViewController and call reloadImageView, later we check if the mockImage given to MockedImageLoader is loaded into loadedImages set or not. That&#39;s fair, that&#39;s exactly what has been implemented.</p><p>That seems like a unit test, but are we really testing what the ImageViewController suppose to do? Oh! No! the ImageViewController suppose to load the image from the remote URL and display it in the imageView. But we are rather unit testing logic of ImageLoader is loading given image or not, that&#39;s because we wrote the test with the implementation details in mind, that&#39;s why we ended testing the ImageLoader rather than the ImageViewController itself.</p><p>Now lets us try to write a test for ImageViewController reloadImageView behaviour.<br>Let us tweak our ImageLoader a little so we can write the unit test for the ImageViewController behaviour.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e5nKrCGx9_VRBIF9s9bx8Q.png" /></figure><p>Now will see the unit test for verify the ImageViewController’s reloadImageView behaviour.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cfNHpDVXtdkNy4aY6aJv-A.png" /></figure><p>Interesting right?</p><p>We have not mocked the ImageLoader, yea we don’t need to, we are verifying the outcome of reloadImageView which is checking if ImageView.image is what sent via mockImage, and one more advantage is we don’t need to update the unit test, even though we modify the implementation of ImageViewController and ImageLoader, until the behaviour of ImageViewController reloadImageView is same.</p><p>That&#39;s a very simple example of writing a unit test to class/functions behaviour instead of implementation.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40bac64c1d9b" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/art-of-unit-testing-with-swift-40bac64c1d9b">Design Code for Unit Testing</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[VSCollectionKit: Swift Component based lib for UICollectionView]]></title>
            <link>https://vinodhswamy.medium.com/vscollectionkit-f33f30f4757e?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/f33f30f4757e</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[composition-pattern]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Fri, 24 Apr 2020 14:07:22 GMT</pubDate>
            <atom:updated>2023-03-08T01:44:31.607Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oOtWQcq3vKxTq2rKxb2-Ug.png" /></figure><p><strong>Looking for an understanding on VSCollectionKit, here you go!!!!!</strong></p><p><strong>VSCollectionKit</strong> is a library for building applications views/screens in a consistent and understandable way, with advantages like composition, independent and testing.</p><p>VSCollectionView a handy framework supporting functionality of a UICollectionView or UICollectionViewController in a much simpler way. VSCollectionKit also avoids a lot of collectionView related code hassle and duplicates.</p><p>Lets see what we get using this kit for developing the application views</p><p><strong>Composition</strong>: VSCollectionKit<strong> </strong>breaks down larger features into smaller components that can be isolated modules and be easily combined to form a full feature.</p><p><strong>Mobility</strong>: Using VSCollectionKit, we can develop a component to be independent ie., the component doesn’t know anything about the user using it. This gives us a confident of using it in multiple places of same project hassle free.</p><p><strong>Testing: </strong>Using VSCollectionKit, each and every component can be tested individually. As it makes smaller independent components to become a bigger complex viewcontrollers, there will be less or NIL integrity issues (fixing in one place which causes a bug in a different place).</p><p>Here is an example that helps you to understand better. The screenshots of the Test app developed using VSCollectionKit presented below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tmKOyuyJvXJICfWyxy-xAw.png" /><figcaption>Sample App Screens developed using VSCollectionKit</figcaption></figure><h3><strong>VSCollectionKit Components</strong></h3><p>VSCollectionKit consist of VSCollectionViewController which is a subclass of UIViewController with UICollectionView.</p><p>VSCollectionViewController works in association with 5 other parts like</p><ol><li>VSCollectionViewDataSource</li><li>VSCollectionViewData</li><li>VSCollectionViewDelegate</li><li>VSCollectionViewLayoutProvider</li><li>VSCollectionViewSectionHandller</li></ol><p>Though the component names justify their functionality, a brief description are explained below for our strong foundations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*0Bq7P-TRHdIYIof3" /><figcaption>VSCollectionKit Components</figcaption></figure><ol><li><strong>VSCollectionViewDataSource </strong>is a subclass of NSObject confirming to UICollectionViewDataSource mainly involved in handling or supplying data to our collectionView. It takes VSCollectionViewData and applies inserting and updating the changes to the current UICollectionView.</li><li><strong>VSCollectionViewData </strong>is a struct that mostly contains the details about our data to be displayed on CollectionView. It contains an array of sections confirming to SectionModel protocol. Also, updates array containing details about the changes in data which is getting applied to a collection via VSCollectionViewDataSource.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/893/1*kwnik47GlwAj7zxT-yJCdQ.png" /><figcaption>The SectionViewData, CellViewData and HeaderViewData protocols</figcaption></figure><p><strong>3. VSCollectionViewDelegate</strong> is a subclass of NSObject confirming to UICollectionViewDelegate. This class mainly involves handling delegate events of collectionView. Please note that we are not using this delegate for determining the size of cell or supplementary view.</p><p><strong>4. VSCollectionViewLayoutProvider</strong> is a component which is responsible for supplying the layout information to the collectionView. <strong>VSCollection</strong>Kit uses UICollectionViewCompostionalLayout for cell and supplementaryview size information.</p><p><strong>5. VSCollectionViewSectionHandller</strong> would supply the cell information, layout information and helps in handling events from the collectionView via VSCollectionViewSectionHandller.</p><p>That&#39;s the theoretical view of VSCollectionKit and their components!!!!</p><h3><strong>How to use VSCollectionKit?</strong></h3><p>VSCollectionViewSectionHandller handles adding and removing of SectionHandler for the VSCollectionViewController. We can have n number of sections supported by collectionview via VSCollectionViewSectionHandller’s <em>addSectionHandler(handler: SectionHandler)</em> function.</p><p>The protocol declaration of SectionHandler is below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/1*ne8JzRs-PeNCJR9mM-Wk9g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/893/1*f61H7sza-tJBpEI6NbpeRw.png" /></figure><p>Probably you caught them right!! Yes the collectionview related functions falls in the individual SectionHandler.It seems to be less complexed because it contains only the necessary functions to be implemented, if we still need more we can always go and extent it from components like VSCollectionViewDataSource and VSCollectionViewDelegate.</p><p><strong>An example on how we can use VSCollectionKit to display grid of photos from local.</strong></p><p>As you know, the VSCollectionViewController understands data by VSCollectionData, so our example is quite simple showing list of photos in CollectionView. We would be converting the list of image urls to VSCollectionData’s SectionModel and CellModel.</p><p>Snippet of the above brief.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/1*SC-9_RunaLBm4p4nfH0oZw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/896/1*oXQeszFx7bysN0Xkr1UvqQ.png" /></figure><p>Having a thought on how we are providing the cell and layout information? Let’s think it together! We need to create a class confirming to protocol <em>SectionHandler,</em> which is where we would be implementing the necessary functions to supply the cell and layout information to the collection view.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/895/1*glQr3OST9yORCeePmaekUw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/901/1*wj9hyl7xgke4rL36I4xNng.png" /></figure><p>The final touch of how are we applying the data to collectionView shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/895/1*hK43zay2RJ60snILvj3Mtg.png" /></figure><p>We need to override <strong>var sectionHandlerTypes: [String : SectionHandler.Type]</strong> and add all the sectionHandlers Types which we would be using in our collectionView, provided each sectionControllers should confirm to protocol SectionHandler as shown above.</p><h3>How to Use VSCollectionKit in a Project</h3><p>Include the below line in the project carthage file</p><p>git &quot;https://github.com/Vinodh-G/VSCollectionKit.git&quot; &gt;= 1.3</p><p>and then call carthage update from the project folder where it is used.</p><p>There is a News Sample App developed using the same VSCollectionKit Carthage dependency, it uses VSCollectionKit for all the screens of the app.</p><p>The VSCollectionKit github link is <a href="https://github.com/Vinodh-G/VSCollectionKit">https://github.com/Vinodh-G/VSCollectionKit</a></p><p>The sample app can be found here(In Progress): <br><a href="https://github.com/Vinodh-G/NewsApp">https://github.com/Vinodh-G/NewsApp</a></p><p>@Architecture @Designpattern @Composition</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f33f30f4757e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Generics in Swift]]></title>
            <link>https://vinodhswamy.medium.com/generics-83170b01224?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/83170b01224</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[generics]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Tue, 03 Oct 2017 13:37:02 GMT</pubDate>
            <atom:updated>2020-09-03T17:35:17.860Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JrcIJxhloZCtn1a9GtEeZQ.png" /></figure><p>Generic programming is a way of writing a reusable functions &amp; types in a flexible way</p><p>Its a feature of swift, much of swift standard libaray build with generic code.</p><p>lets understand it solving the existing problem</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FtSpgLCz_whyMYmhTQ1QAg.png" /></figure><p>The above function swaps the two Int using pass by reference, now if I need to write a function which does swaping of strings, I would be writing one more function like shown below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vof2TXk7m92ZNG6Iar5GaQ.png" /></figure><p>As you can see the implementation body of both functions are same, the only difference is in the type of parameters.</p><p>Now lets see how Generics solves the above duplicity of code</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J_-kro2sjb3mOc48U1Qy3Q.png" /></figure><p>Thats how our generic function to swap two values will look like,</p><ul><li><strong>&lt;T&gt; </strong>just after the function name<strong> </strong>indicating this is a generic function which take parameters of type <strong>T</strong></li><li>Function arguments list contains the Type as <strong>T</strong> instead Int, Double or String, which would be replaced with actual type</li></ul><p>The below code shows how the above generic function swapTwoValues used for swapping Strings, Int values.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N51sfMWtifgP1suDqPlUTA.png" /></figure><p>So thats quick Intro of Generics, Generic Function.</p><p>Topics we would be covering reading further</p><ul><li>Generic Types</li><li>Type Constraint to Generic Functions/Types</li><li>Associated Types</li></ul><h3>Generic Types</h3><p>As expected, yea!! you can write generic types in swift, the most common types we use day to day the <strong>Array</strong>, <strong>Dictionary</strong> are Generic Types</p><p>lets dig into the code without any further theory</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d-r9OA4JxIsiox_wqOhwtg.png" /></figure><p>The above structure IntStackwhich uses an array to push and pop the Int items to stack, the `push() &amp; pop()` functions are mutating because they are modifying the structure items array.</p><p>Now lets see if I need a generic type which can push and pop not only Int item types but also other types.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jlh4e5jtwz5hJWQIdPoa2w.png" /></figure><p>There is not much difference isn&#39;t it?</p><p>Struct Name is appended with generics syntax &lt;Element&gt; where Element is a Type which would be replaced with actual Types (Int, Double, Strings, etc)</p><p>Element used as place holder in three places</p><ul><li>The property items which is initialized with array of values of type Element</li><li>The push() function is taking a parameter of type Element</li><li>Return value of funtion pop() is of type Element</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J_rkQQUjRG9nL8JiMCMulA.png" /><figcaption>Generic Stack Operations for Strings</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mfjo8_cBStn1Ou6hidzDig.png" /><figcaption>Generic Stack Operations for Ints</figcaption></figure><p>The above code shows how we have used the Generic Stackpushing and popping items of type String and Int.</p><h4>Extending Generic Type</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VJEObapxtzC8qG2oPzm8jA.png" /><figcaption>Extending a Generic Type Stack</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lYm5MxXtH6WyJqX-kwUrOg.png" /><figcaption>Example showing how to use the extended topItem property</figcaption></figure><p>The above snippet is an extention of value type Stack with topItem as computed property in it, topItem is of type Element will return nil if stack is empty else the last item.</p><h3>Type Constraint to Generic Functions/Types</h3><p>In swift we can enforce certain type constraint on the types that can be used with generic functions and types</p><p>Didn&#39;t get ?</p><p>May be lets read the below line and try mapping it again.</p><p>We can define a generic function or type with a rule saying,</p><ul><li>Type used should always confirm to a particular protocol or protocol composition</li><li>Type used should be inherited from a particular class</li></ul><p>For example, In Swift’s Dictionarydictionary’s keys must always confirm to protocol Hashable else it cannot be used as key in Dictionary</p><p>Lets see a <strong>generic function</strong> with type constraint</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VCkcbjEm1rX6nadk1olGFQ.png" /></figure><p>&lt;T:Equatable&gt; the syntax indicate that the generic function will take types only confirming to protocol Equatable</p><p>By default all Data types String, Int, Double, etc are confirming to protocol Hashable which confirms Equatable protocol , so the above code works with out any issue.</p><p>Lets not wait to see a <strong>generic type</strong> with type constraint, will create a NavigationControllerStack for pushing and popping viewcontrollers which is of class UIViewControllers or its subclasses</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lj4veEzo4T_GlpzMaHmq9Q.png" /><figcaption>Generic NavigationControllerStack</figcaption></figure><p>Thats how the NavigationControllerStack looks like, the syntax &lt;Element:UIViewController&gt; after the class name indicates that, this class will take Element only if they are inherited from UIViewController.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NiqoMdVhZLfIstae4-BvkA.png" /></figure><p>In the above code snippet, we create a ContactsViewController instance which is inherited from UIViewcontroller and Push to the NavigationControllerStack , same way PeopleViewController instance which is inherited from UIViewcontroller is Pushed.</p><h3>Associated Types in Generics</h3><p>Here we will see how we can use generics in protocols. Unlike classes, structs, enums, protocols supports generics in different way, the swift terminology calls it as Associated Types</p><p>An associated type in protocol says</p><blockquote>“I dont know what exact type this is, some concrete class/struct/enum that adopts me will fill in the details.”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xGWOkz9G2aipW8P-5Lbnvw.png" /></figure><p>The above snippet shows the declaration of Containment protocol , Containment declares an `associatedtype` called Item which protocol doesn&#39;t know what exact type it is, the class or struct who implements Containment will know about it.</p><p>The Container protocol defines two required capabilities that any container must provide:</p><ul><li>It should be able access the top item in the container through function topItem() at returns a Item type</li><li>It should be able to access a count of the items in the container through a count property that returns an Int value.</li></ul><p>Will use the the above Containment Protocol in our Stack value type</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qNKWzBnpQ6Tw8RBErmFcGg.png" /></figure><p>The protocol Containment with associated type Item which was as place holder filed by our Stack struct as Element</p><p>Means the protocol funtion topItem() returns the item of type Element which was Item in protocols declaration.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p1JiGw6WljKjk6E25-nleQ.png" /></figure><p>Thats about the basics of Generics and related topics, If interested further feel free to check out the <a href="https://github.com/Vinodh-G/Data-Structures/blob/master/Trie-Datastructure-Example/Trie-Datastructure-Example/Trie.swift">TRIE Data stucture</a> Implemented using Generics.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83170b01224" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Strong Cycle /Retain Cycle in Swift]]></title>
            <link>https://vinodhswamy.medium.com/strong-cycle-retain-cycle-in-swift-f452f07518b2?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/f452f07518b2</guid>
            <category><![CDATA[retain-cycle]]></category>
            <category><![CDATA[cars]]></category>
            <category><![CDATA[strong-cycle]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[closure-reference]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Thu, 14 Sep 2017 17:42:12 GMT</pubDate>
            <atom:updated>2017-09-14T17:42:12.308Z</atom:updated>
            <content:encoded><![CDATA[<p>Before Jumping into the <strong>Strong/Retain</strong> Cycle problem let’s have very brief understanding how our object memory is managed with ARC.</p><p><strong>ARC</strong> is a compile time feature XCode provides us for automated memory management. It stands for <em>Automatic Reference Counting. </em>In simple terms, ARC <strong>frees</strong> objects only if the strong reference count goes to ‘<strong>zero</strong>’</p><p>According to ARC Memory management, an object can be one of reference<strong>strong, weak or unowned</strong> type with a variable, will be discussing more about them further, for now, if the object doesn&#39;t have any key word before let statement then by default it will be with <strong>strong</strong> reference.</p><p>let name = String() // name variable has a strong reference to instance of String</p><p>Lets understand with code,</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ypI-1t2Fdi1zwPTEYfZ3BA.png" /><figcaption>Employee class</figcaption></figure><p>The above snippet declares a class called Employee with name, empid &amp; title as the ivars, At line number 19 we create a instance jack of class Employee passing all the employee details, so jack variable has a strong reference to object.</p><p>According to ARC memory management object with at least one strong reference will not be free/deallocated.</p><p>At line 20 we nil the reference to the object jack which in turn deallocates or frees the object which it was referring to, thats how the deinit() funtion of class Employee is called before it frees the object, and as we see the log <strong>Employee: Jack removed.</strong></p><p>Let’s add the reference to the variable jack before niling it out.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yQeBOJ1ktFlJGzdc_v-FNQ.png" /></figure><p>&quot;Where did the deinit log “<strong>Employee: Jack removed</strong>” go ?&quot; we made jack = nil right? why did’nt it logged ? Now thats ARC memory management, the jack object was not deallocated even though we made it nil, because the variable jackReference at line number 20 has a strong reference to an instance were jack was pointing to, so the strong reference count of object were jack was pointing too was not zero hence not deallocated or freed, if we make jackReference = nil then we will see the log of deinit <strong>Employee: Jack removed.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yx7RUIqGbS-HH7RdhEq_hA.png" /></figure><p>That’s the verify brief ARC intro.</p><p>Now coming to actual problem, <strong>Strong/Retain Cycle</strong></p><p>As we know each time we declare a class property by default it has a strong reference to object which it is pointing to unless we specify something, so when can a strong cycle appear?</p><p>Cases were ObjectA has a strong reference with ObjectB and ObjectB, in turn, has a strong reference to ObjectA</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/962/1*o4FAAeJiX90eK33V7GEeOA.png" /></figure><p>Let’s understand with a code as usual</p><p>Let’s make use for our Employee class itself, and let&#39;s declare one more class MacBook</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*tTNXWYhEvPk1hVSmkXJA3w.png" /><figcaption>Employee and MacBook Definition</figcaption></figure><p>So that’s how the classes look, Employee has 4 ivars or properties with strong reference name, empid, title &amp; macBook so the first 3 properties are of type String, the macBook is of type class MacBook, it is defined below Employee class in the snippet, same way the MacBook has 2 properties serialNumber &amp; assignee as we can see the property assignee is of type class Employee.</p><p>Now let’s see how the strong cycle occurs</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DgP9W-YvqppNkj2trD-6_w.png" /></figure><p>What!! where is the strong cycle? I created the instance employee line 33, created an instance of mac at line 34, assigned employee?.macBook = mac then I nil both employee and mac you know both got removed as I can see in the log, so were is the strong cycle?</p><p>Actually, the strong cycle is not created yet, in employee we made the property macBook to point to an instance mac which is a strong reference relation with mac, but as we can see in the MacBook class there is property called assinee which we didn&#39;t set to employee yet, let&#39;s add mac.assinee = employee before we nil both employee and mac.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jR13cUyqONmoJz_4Kma5-Q.png" /><figcaption>Retain Cycle Issue</figcaption></figure><p>Why didn’t the log print now?? we made both employee and mac nil, so? so here we made a crime of making strong reference cycle between employee and mac</p><ul><li>employee object has a strong reference to property macBook which is pointing to mac</li><li>mac object has a property assinee with a strong reference pointing employee</li></ul><p>Thus they both became a retain cycle, means employee will be retained by mac and mac will be retained by employee so they both don&#39;t get freed or deallocated.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YhjcGhf2Ot8zd4IgE3d8VQ.png" /></figure><p>How can we resolve this? there comes the saviour <strong>weak </strong>reference</p><p>A <em>weak reference</em> is a reference that does not keep a strong hold on the instance it refers to and so does not stop ARC from deallocating the referenced instance. This behaviour prevents the reference from becoming part of a strong reference cycle. You indicate a weak reference by placing the weak keyword before a property or variable declaration.</p><p>That’s what apple document speaks about weak reference, let’s try breaking the above retain cycle with the weak keyword.</p><p>Let employee still have a strong reference with macBook we will make the assinee property of MacBook weak by just adding the keyword <strong>weak</strong> before the var as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I4ONaL79xDGX-j1B0WQ6dw.png" /></figure><p>Did you notice anything? yea there is a key word weak before,var assinee:Employee and now you can see the both employee and macbook object/instance is deallocated as confirmed in the console Employee : Jack removed, &amp; Mackbook : JHSF8S32 removed is logged.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PuxFz_98lRBGMgHvT2y1Ww.png" /></figure><p>So we did break the retain cycle with the <strong>weak</strong> reference type.</p><p>So what about <strong>unowned</strong> ? when is that used?</p><p>A <strong>unowned</strong><em> </em>reference does not keep a strong hold on the instance it refers to.</p><p>That statement seems repeating? isn’t it the same definition even <strong>weak</strong> reference we read? <strong>Yes</strong>!! Like weak reference when a variable or property declared with <strong>unowned</strong> key word before, doesn&#39;t hold the strong reference to the object which it is pointing to.</p><p>So you mean to tell, we can break the above Employee and MacBook <strong>retain</strong> cycle with unowned reference as well? <strong>Yes!!</strong></p><p>Then why do we need the unowned keyword ? there should be some condition were we should use unowned not weak and vise versa, lets see what apple doc tells about it.</p><p>“<em>Like a weak reference, an unowned reference does not keep a strong hold on the instance it refers to. however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime.</em>”</p><p>Lets tweak the above statement little for our understanding</p><blockquote><strong><em>“weak</em></strong><em> reference is used where there is possibility for that reference to become nil at some point during its lifetime. an </em><strong><em>unowned</em></strong><em> reference is used where there is </em><strong><em>no</em></strong><em> possibility for that reference becoming nil at any point until the self-object exist”</em></blockquote><p>Seems still confused, if it is let’s resolve that reading further with code example.</p><p>You indicate unowned reference by placing the unowned keyword before a property or variable declaration.</p><p>Let’s use our previous Employee class and one more class say,ICard each an every employee will have one iCard and each iCard would be pointing to one employee</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/626/1*V0RL84Em4dMeBhkIAGi8ag.png" /></figure><p>Now that’s our employee class, which has 3 properties name, title &amp; iCard were iCard is of class type ICard which is defined as shown below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/632/1*8fqizkVQ5b-ZsrW0-ZSoQg.png" /></figure><p>As expected as we know there is retain cycle between employee and,icard the iCard variable of Employee class has strong reference to ICard and same way employee variable of ICard has strong reference to Employee</p><p>We know the trick to break the retain cycle lets go and add <strong>weak</strong> keyword before the employee variable of ICard class</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/859/1*zPtwfooqet8E-RUNNOksVw.png" /></figure><p>Ohh!! no seems my compiler is not happy about it, it says <em>‘weak’ variable should have optional type ‘Employee?’ </em>Ohh that&#39;s a good suggestion but I cannot make my employee variable in ICard class as optional by adding <strong>?</strong>, because the ICard class is valid only if it has a valid employee, every instance of ICard should have a valid employee associated with it, so making it optional is not the solution.</p><p>Ok, we let’s use <strong>unowned</strong> key , as we read earlier this also used to break the retain cycle.</p><p>Ok we lets use <strong>unowned</strong> key , as we read earlier this also used to break the retain cycle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/829/1*t8jEyFHKW9XcCaUp_3WBsg.png" /></figure><p>Wow my compiler was happy, it didn’t shout at me this time, and see line 71 I created an instance of Employee jack , line 73 I create an instance of ICard passing the jack as an argument, line 74 I assigned jack.iCard = iCard, and I nill both the objects, with out any surprise or retain cycle the Employee and ICard has been removed as we can see from the logs</p><p>Got little when to use unowned ? or weak?</p><p>Ok back to our previous example Employee and MacBook , why didn&#39;t we use assinee as unowned, in code : <a href="https://cdn-images-1.medium.com/max/800/1*I4ONaL79xDGX-j1B0WQ6dw.png">Employe and MacBook Definition</a> because in that use case there is a chance the assignee might become nil when jack takes new laptop, in that case, the assignee variable of MacBook would be nil until it points to the new employee it is assigned to.</p><p>So that’s not the only retain/strong cycle problem, it just doesn’t occur between class instances, there are chances of creating a retain cycle while using closures, If not sure about what is closures I recommend read <a href="https://medium.com/p/4484aaa2d67b/edit">closure</a> before continuing further.</p><p>Let’s create PhotosViewController responsible for displaying the photos, and one more class PhotosViewModel which is responsible for getting the photos to our PhotosViewController</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/841/1*Y8FF7SwlKF315OmT1H0Rjw.png" /></figure><p>That’s our,PhotosViewModel at the top we have declared a closure type DidGetPhotos which takes one parameter photos which is array, As mentioned earlier this class is responsible for getting the photos to the PhotosViewController through didGetPhotos closure.</p><p>Now let’s see our PhotosViewController</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/704/1*9yk_NdA3STsMc4vVGQeNcg.png" /></figure><p>Let’s read the PhotsViewController line by line</p><p>line 102 we create declare and initialize a photosViewModel object of type PhotosViewModel, so thats the object responsible for getting photos</p><p>line 104 we defined a loadPhotos() function in which we assign a didGetPhotos closure to our photosViewModel, so this is the place we get a <strong>callback</strong> from our ViewModel getting all the photos. and inside the closure we call the function updatePhotosInView() to display the photos given by photosViewModel</p><p>Does this have a Retain cycle? let’s check it out, as usual, let’s create an instance of PhotosViewContoller and nil it out, verify that it logs inside deinit(), its deallocated or freed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/815/1*_b9Qqpxsfh1nubzi7LFdFA.png" /></figure><p>Where is our deinit() log? we created an instance we called loadPhotos() and we set the photosViewController to nil, ideally, it should have deallocated right? before finding an answer let’s read below fact about closure</p><blockquote>In swift accessing a self inside a closure makes the closure have strong reference to self.</blockquote><p>Did it mean closure will retain self if it is used inside closure ?? <strong>Yes</strong></p><p>let’s picturise</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/780/1*HLCwgANoGqx74gNsVjd8nQ.png" /></figure><p>Ohh Yea!!, seems there is retain cycle, photoViewController has a strong reference to photosViewModel, photosViewModel has a strong reference to didGetPhotos() closure, and we accessed the self inside the closure in line 106 loadPhotos() function.</p><p>Let’s break it with a trick we learned before (weak, unowned) , so will go ahead a make the didGetPhotos property weak?, no, you cannot, the compiler will shout at me, can we do something inside the closure ??</p><p>Yes absolutely!! , we have to break the cycle from closure, as we know the closure captures reference right, so we need to tell the didGetPhotos closure inside the PhotoViewController to capture the self with weak reference.</p><p>let’s check the code now how it looks?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/815/1*GbyQ0wq3dzhSmbpKM-tM7A.png" /></figure><p>Ohh yeah there you go, seems the photoViewContoller is deallocated now, as you can see the log<em> Deinited the PhotosViewController, </em>what did we do?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rQ1QkWwA5Qu8rnoimBEqZQ.png" /></figure><p>Observe line number 105 we captured the self as weak reference by providing [weak self] before the closure parameters, as you see we pass that as an array , I mean we pass those captured values in an array [], means we can capture more than one reference inside the closure.</p><p>That’s all I have now about <strong>Retain/Strong</strong> Cycles, feel free to drop a comment if there is anything, hope will come next time with some new problems and techniques.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f452f07518b2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SOLID Principles in Swift]]></title>
            <link>https://vinodhswamy.medium.com/solid-principles-in-swift-7dc2b793fd68?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/7dc2b793fd68</guid>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[interface-segregation]]></category>
            <category><![CDATA[open-closed-principle]]></category>
            <category><![CDATA[solid-principles]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Sun, 16 Apr 2017 17:42:52 GMT</pubDate>
            <atom:updated>2021-06-07T08:37:55.764Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yp26JLwcouiuALmhqfCTOg.png" /></figure><p>SOLID is a mnemonic acronym named by Robert C. Martin used in Software Programming, It represents 5 principles of Object Oriented Programming.</p><ul><li><strong>S</strong>ingle Responsibility Principle</li><li><strong>O</strong>pen Closed</li><li><strong>L</strong>iskov’s Subsititution</li><li><strong>I</strong>nterface Segregation</li><li><strong>D</strong>ependency Inversion</li></ul><p>These principle solve bad architecture problems like</p><p><strong>Delicacy </strong>— A change in one place breaks unexpected parts, its difficult to trace if there is no good test coverage.</p><p><strong>Immobility </strong>— A component is difficult to reuse in another project or use in multiple places of same project, because it has to many dependencies.</p><p><strong>Irritable</strong> — Takes a lot of effort for change, because it affects several parts.</p><p>These SOLID principle are not strict rules, but just guidelines to improve the quality of the your architecture.</p><p>Lets dig in the principles one by one</p><p><strong>Single Responsibility Principle</strong></p><blockquote>Each an every class you create/change should have only one responsibility</blockquote><p>Let us see an example explaining it, I have to develop a messenger app screen to get the list of past conversations. So I have a ConversationInteractor which gets me the array of previous conversations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/840/1*Em9aJGoMTJ9jgkYWx5W1fA.png" /></figure><p>How many responsibility does this class have ?</p><ul><li>Gets the conversation data form the API</li><li>Parse and create conversation structs or objects from API response</li><li>Saves the conversation array to Database either core data or something.</li></ul><p>If we have to implement NSURLSession for getting Json Data from API, and JSONSerialization to parse and Core Data Stack for saving to Database, this class becomes huge monster class.</p><p>we can solve this problem moving the each responsibility down to different classes</p><p>I have created separate classes for each responsibility which ConversationInteractor was handling, this is how our classes looks now.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*4kwFCldGN_iw2Bx56Wuotg.png" /></figure><p>As we can see now we have split the responsibility of the bigger task into 3 classes (ConversationInteractor, RemoteService, ConversationDBOperation) which makes easy for us to deal with particular class rather than the giant ConversationInteractor</p><p>This principle helps you to keep your classes as clean as possible, and we have a advantage of testing each and every API separately, with previous implementation we would not be able to test `fetchRemoteConversationJsonData()`, `convertJsonToConversation(data:Any)`and `saveToDatabase(conversations:[Any])` because they were private functions inside ConversationInteractor. Now it seems we can test each an every pieces (`ConversationInteractor`, `RemoteService`, `ConversationDBOperation`) separately.</p><p>As we can see all the 3 classes are connected via a protocol, which can be easily decoupled, we would be covering this topic in detail further.</p><p><strong>Open Close Principle</strong></p><blockquote>Classes and Modules should be open for extension but closed for modification</blockquote><p>Strive to write code that doesn&#39;t have to change every time the requirements change.</p><p>To understand this principle easily lets take a basic example of calculating the area of geometry shape.</p><p>Lets say we have requirement to calculate area of rectangle, so the rectangle and related area calculator class looks like shown below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/766/1*0Jm0Jg6XRhhZOANh-kUZ1g.png" /></figure><p>Now the requirement has come to calculate area of not only Rectangle even for Circle, so our AreaCalculator class will look something like.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*_czBtd-hRWKrtA41DeMO2A.png" /></figure><p>This will work but what if tomorrow one more requirement comes to calculate the area of Triangle, area function inside AreaCalculator class keeps growing with if else conditions, according to <strong>Open Close Principle </strong>we should not modify the existing class rather extent it.</p><p>One way of solving this problem is create a protocol (which is similar to Interface in Java) called GeometricShape and declare area protocol method, implement the GeometricShape protocols inside Rectangle or Circle or any other geometric shape class, if it is confusing still may be checking the code below may clear it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/775/1*G1CT8OIfDXsC1AkLEr7dCQ.png" /></figure><p>so if there is requirement tomorrow to calculate the area of even Triangle, we should be able to achieve it without modifying the existing AreaCalculator struct just by extending the GeometricShape Protocol for Triangle, This obeys the SOLID Open Close Principle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*CoV3f-kwa5DcUD5bP3aphw.png" /></figure><p>Thats a very common example for understanding the principle of not modifying the working class, lets see some real world example for <strong>Open Close Principle, v</strong>ery common example which we use on most of case when showing some data on UITableView, say we have requirement to show list of products and ads in the ListView or TableView, the ViewController or ActivityController would look something like as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*686zJ6lmZBn1T0EpBS_Z_Q.png" /></figure><p>Looks like something similar to our old AreaCalculator problem right, say suppose if we need to display new type cell called SuggestionCell, we need to go and change the existing ListViewController handling the new type of cell, this ListViewController is not obeying the OCP.</p><p>Now let’s apply OCP to our ListViewController, the class should be opened for extension and closed for modification, which means we should not modify the ListViewController but should be able to support new types of cells.</p><p>Let’s create protocol SectionHandler which has method related to creating a UITableViewCell and sectionType property, SectionContainer which handles all the types of SectionHandlers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gcJif1sAG-5A_kqVb9buoA.png" /></figure><p>If we checkout the above snippet, can see the SectionContainer picks respective SectionHandler based on the cellModel type and calls tableView related method asking for UITableViewCell, which means we should be having the SectionHandlers w.r.t. the use case, here in our case its ProductSectionHandler and AdSectionHandler, both confirming to SectionHandler protocol.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1009/1*rM4PdGGRCTRjtuDd6AI6Qg.png" /></figure><p>Okay its kind of confusing right, now let’s see our original `ListViewController `which is obeying to OCP, so we can understand it better.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/962/1*6i9PUH4yy6S1sEvckFc1cw.png" /></figure><p>Oh yea we don’t have if else statement in the `tableView:cellForRow indexPath function, how is the ListViewController created? well checkout below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/887/1*AbNEP7z6s7BTR31GUIr5wg.png" /></figure><p>Now kind of convinced? No!! ok prove me if we add new SuggestionCell to list how it will look, ok let’s see below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EXkI4Tbd5UHssM5chZIWew.png" /></figure><p>Kind of agreeing now? we didn’t change the existing class ListViewController for supporting new SuggestionCell, we just created the new SuggestionSectionHandler class confirming to SectionHandler for supporting the new SuggestionCell.</p><p>Pictorial representation of Open Close Principle in brief shot.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*tTTjovZDafmWd7m7h3N0bg.png" /><figcaption>Credit: <a href="https://www.brainconcert.com/articles/openclosed-principle">https://www.brainconcert.com/articles/openclosed-principle</a></figcaption></figure><p><strong>Liskov’s Subsitution Principle</strong></p><blockquote>Child classes should never break the parent class type definitions</blockquote><p>It means, we must make sure that new derived classes should extend the base classes without changing the base class behaviour</p><p>As simple as, a subclass should override the parent class methods in a way that doesn’t break the functionality of base class from client point of view.</p><p>Lets see this with an example, we have two classes <strong>Rectangle</strong> and <strong>Square</strong> since Square is also a form of Rectangle, so Square is subclass of Rectangle</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PF_LSEmGTgvhDZ4kquYy3g.png" /></figure><p>Here in the above block Square inherits the width and height property from Rectangle and overrides the width and height property to return the same height and width since it is Square.</p><p>Since our requirement is to calculate the area of Rectangle and Square, we will to use the <strong>AreaCalculator</strong> class.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*obMQ4CsQm2eDYpEjet1wwQ.png" /></figure><p>Lets go a head and write Unit test cases to calculate the area of Rectangle and Square</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C7PDlBAW-MSFg6CHSuBvng.png" /></figure><p>In above both test cases should pass since we have used instance of <strong>Rectangle</strong> to find area of rectangle and instance of <strong>Square</strong> to find area of square, now lets go a head and create a test case in which we will try to substitute object of <strong>Rectangle</strong> with object of <strong>Square</strong>, since Square inherits from Rectangle we should be able to find area of rectangle with Square instance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BnySXUeUCeZujzyIMdEjlA.png" /></figure><p>In the above test case we have used instance of Square class to find the area of rectangle, since square inherits from Rectangle, but its very unfortunate that the above test case fails, the AreaCalculator returns the value of 16, were as the expected area was 12, this violates the Liskov’s Principle of Derived class (<strong>Square)</strong> breaking the parent class (<strong>Rectangle)</strong> functionality of calculating the area.</p><p>We can solve this problem breaking the inheritance</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b2cdsBeh783n45sE7dBa-g.png" /></figure><p>The solution seems similar to <strong>Open Close Principle</strong>, so based on above example we can conclude that violating <strong>Liskov’s Principle</strong> violates <strong>Open Close Principle</strong> as well.</p><p><strong>The Interface Segregation Principle</strong></p><blockquote>Make fine grained interface that are client specific</blockquote><p>This principle solves FAT interface problems of Object Oriented Programming</p><p>A interface is called FAT when it has to many methods which contains more information than we really want.</p><p>Lets understand <strong>Fat Interface in Protocols </strong>with an example, we have a GestureProtocol with the method didTap: which a View would be using it to handle the Gesture</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oPafL4wY5Y6IX1KenL4R_Q.png" /></figure><p>After sometime as usual the requirement came to handle more gesture like didDoubleTap: and didLongPress: so our GestureProtocol becomes</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cZh1h-LubEhAabxW_VLxjg.png" /></figure><p>Again as usual not all the Views in our app requires all the gestures some View would require only didTap: gesture in that case our UserDetailView class which would need only didTap: gesture would look like</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bPSrS2T_4ouPk8DGW_Tl_g.png" /></figure><p>We can solve the problem using little protocols instead of a big ones, the below code snippet shows segregation of Gesture protocols into small ones</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Xv3AJClspHSuRtPvXtEffw.png" /></figure><p>Other way we can solve this problem in swift 3.0 is using @objc key before the protocol declarations and protocol methods, which in turn gives us a options to declare a protocol method as optional, who ever wants can implement, the below code snippet shows the same.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*68NKscKI01sLPMNkHj7GwQ.png" /></figure><p>Now let’s dig into <strong>Fat Interface in Classes </strong>with an example, we have view in our app which displays the user profile photo, the two classes User and UserProfileImageView classes looks like shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C8gyX1r997jVX9Oe_a8tJA.png" /></figure><p>Observing closely the above snippet, the UserProfileImageView’s loadProfileFor(user:User) function requires only the profileImageURL details, but unfortunately we are injecting too many informations in it, we can solve this problem using <strong>UserProfileViewDetails</strong> protocol which just has the information required by <strong>UserProfileImageView’s</strong> <strong>loadProfileFor(user:User), </strong>the below code will explain you detail.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qsk_ivU7BE3SAFJJlZb6HQ.png" /></figure><p>Now the UserProfileImageView’s <strong>loadProfileFor(user:UserProfileViewDetails)</strong> which is the client has only the profileImageURL information with it to display the User Profile Image, which agrees with the <strong>Interface Segregation Principle.</strong></p><p><strong>The Dependency Inversion Principle</strong></p><blockquote>High level modules should not depend on low level modules both should depend on Abstractions</blockquote><p>Lets Consider the class <strong>ConversationDataContoller</strong> which we used in <strong>Single Responsibility Principle</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wIhU6GUVnqpqn6Dd33DQYg.png" /></figure><p>here the CoreDataController is a low level module, its easy to reuse in other projects, the problem is with high level module ConversationDataController, its tightly coupled with CoreDataController.</p><p>Lets discuss this in detail, as I have mentioned earlier the ConversationDataController is used in the Messenger App to get the previous conversations json, parse it, and save to Core Data Database, so it can use the previous conversations to display it offline as well in the Messenger App, now new requirement from a client or product team came like can we use the same ConversationDataContoller from Messenger App into another App, with little change something like use <strong>File System Archiving</strong> instead of <strong>Core Data </strong>for saving the previous conversations.</p><p>In that case we cannot use the <strong>ConversationDataContoller</strong> into another app easily because it is tightly coupled with <strong>CoreDataController</strong> or in other words it has a dependecy in low level module CoreDataController.</p><p>We can solve this dependency using a Database Protocol. In this way ConversationDataController can use abstract protocol without caring for type of database used, lets see how the ConversationDataController will look after applying this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zSTEV_3Vmg14Oj5U1yetLQ.png" /></figure><p>Now you can reuse the ConversationDataController without any hazzle or hectic into another App which uses File Sytem Archiving for database, just by including the <strong>FileSystemArchiving</strong> class as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dd3oCQH8B8EnhsPdeTywZA.png" /></figure><p><strong>Quick Summary</strong></p><ul><li>Each an every class should have only one responsibility</li><li>Should not modify the existing class for change requirement, rather extent the class</li><li>Extending or Inheriting a child/derived class should not break any parent or base class functionality</li><li>The Interface or class API’s to client should have minimum information required by the client</li><li>Class A should not depend on Class B or vice versa, both should be losely coupled</li></ul><p>Use SOLID principles as your weapon in the war of coding :)</p><p>Reference :</p><ul><li><a href="https://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp">https://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp</a></li><li><a href="https://realm.io/news/donn-felker-solid-part-4/">https://realm.io/news/donn-felker-solid-part-4/</a></li><li><a href="https://marcosantadev.com/solid-principles-applied-swift/">https://marcosantadev.com/solid-principles-applied-swift/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7dc2b793fd68" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[UIImageView + Async Dowload Remote Image]]></title>
            <link>https://vinodhswamy.medium.com/uiimageview-async-dowload-remote-image-bce114152d6d?source=rss-507a15c0b921------2</link>
            <guid isPermaLink="false">https://medium.com/p/bce114152d6d</guid>
            <category><![CDATA[urlsessiondatatask]]></category>
            <category><![CDATA[uiimageview]]></category>
            <category><![CDATA[urlsessions]]></category>
            <category><![CDATA[asynchronous]]></category>
            <dc:creator><![CDATA[Vinodh Swamy]]></dc:creator>
            <pubDate>Sun, 12 Feb 2017 13:09:01 GMT</pubDate>
            <atom:updated>2017-02-21T23:35:11.347Z</atom:updated>
            <content:encoded><![CDATA[<p>UIImageView+AsyncLoad is an extension of UIImageView for loading and displaying images asynchronously on iOS. Developer will have a hassle free environment for showing the remote image on imageview without doing much work, more sepcifically not worring about network calls, with out blocking the UI.</p><p>https://github.com/Vinodh-G/UIImageView-AsyncLoad</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/1*RB6wxUfRZXP9ckTZJRtBBQ.png" /><figcaption>UIImageView + AsyncLoad</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bce114152d6d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>