<?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 Arun pattanayak on Medium]]></title>
        <description><![CDATA[Stories by Arun pattanayak on Medium]]></description>
        <link>https://medium.com/@arunk.pattanayak?source=rss-ca7e77c52ed3------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*RmhrCTyMlClZxP7gE2PKkw.jpeg</url>
            <title>Stories by Arun pattanayak on Medium</title>
            <link>https://medium.com/@arunk.pattanayak?source=rss-ca7e77c52ed3------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 26 May 2026 22:58:45 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@arunk.pattanayak/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[Swift 6 Concurrency Explained: Actors, Isolation, Sendable, Mailbox, and Why It Replaces GCD]]></title>
            <link>https://medium.com/@arunk.pattanayak/swift-6-concurrency-explained-actors-isolation-sendable-mailbox-and-why-it-replaces-gcd-0366bdd4dd44?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/0366bdd4dd44</guid>
            <category><![CDATA[swift-actor]]></category>
            <category><![CDATA[swift-concurrency]]></category>
            <category><![CDATA[multithreading-in-swift]]></category>
            <category><![CDATA[swift-interview-questions]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 15 Feb 2026 06:56:46 GMT</pubDate>
            <atom:updated>2026-02-15T07:14:30.380Z</atom:updated>
            <content:encoded><![CDATA[<p>Swift 6 introduces the first concurrency system in mainstream mobile development that <strong>prevents data races at compile time</strong>.</p><p>No detection <br>No warnings<br>Prevents</p><p>If you’ve enabled Swift 6 language mode, you’ve likely seen errors about:</p><ul><li>Actor isolation</li><li>Sendable</li><li>Crossing concurrency boundaries</li><li>MainActor violations</li></ul><p>These are not annoyances. They are the compiler actively protecting your app from race conditions.</p><p>This article explains Swift concurrency the way it actually works internally, with mental models, diagrams, and practical examples.</p><h3>The Big Picture: Swift Concurrency Architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iIb8Atdnk6rQF6hMpu1vJw.png" /></figure><p>Swift concurrency is built on three pillars:</p><p><strong>Actors</strong> → Protect mutable state<br> <strong>Isolation</strong> → Enforce ownership boundaries<br> <strong>Sendable</strong> → Ensure safe data transfer</p><p>Together, they eliminate data races.</p><h3>First, What Problem Are We Solving?</h3><p>A data race happens when multiple threads access and modify the same memory simultaneously.</p><pre>class Counter {<br>    var value = 0<br><br>    func increment() {<br>        value += 1<br>    }<br>}</pre><p>Now imagine:</p><pre>DispatchQueue.global().async {<br>    counter.increment()<br>}<br><br>DispatchQueue.global().async {<br>    counter.increment()<br>}</pre><pre>Thread 1 reads value = 0<br>Thread 2 reads value = 0<br><br>Thread 1 writes value = 1<br>Thread 2 writes value = 1</pre><p>Final value = 1 instead of 2.</p><p>This is a data race. GCD does not prevent this. Swift concurrency does.</p><h3>Pillar 1: Actors — Protect Mutable State</h3><p>Actors are reference types that ensure only one task can access their mutable state at a time.</p><pre>actor Counter {<br><br>    var value = 0<br><br>    func increment() {<br>        value += 1<br>    }<br>}</pre><pre>let counter = Counter()<br><br>Task {<br>    await counter.increment()<br>}</pre><p>Swift guarantees safe access.</p><p>No locks needed. No DispatchQueue needed.</p><h3>Actor Mailbox — The Most Important Internal Concept</h3><p>Every actor has a mailbox.</p><p>Mailbox is an internal queue that stores incoming requests.</p><pre>Task { await counter.increment() }<br>Task { await counter.increment() }<br>Task { await counter.increment() }<br><br>[increment]<br>[increment]<br>[increment]</pre><p>Actor processes them one by one:</p><pre>value = 1<br>value = 2<br>value = 3</pre><p>This prevents race conditions.</p><blockquote>Important truth: Actors do NOT execute methods immediately. They enqueue requests in mailbox.</blockquote><h3>Actor Isolation — Ownership of State</h3><p>Isolation means:</p><p>Only the actor that owns the state can access it directly.</p><p>Example:</p><pre>actor BankAccount {<br><br>    var balance = 1000<br><br>    func withdraw(amount: Int) {<br>        balance -= amount<br>    }<br>}</pre><p>This is illegal:</p><pre>account.balance -= 100</pre><p>Compiler error.</p><p>Correct way:</p><pre>await account.withdraw(amount: 100)</pre><p>Why?</p><p>Because balance belongs exclusively to BankAccount actor. This ownership prevents race conditions.</p><h3>Global Actors and MainActor</h3><p>Some actors represent global execution domains.</p><pre>//This guarantees execution on main thread.<br>@MainActor<br>class ViewModel {<br><br>    var title = &quot;&quot;<br><br>    func update() {<br>        title = &quot;Updated&quot;<br>    }<br>}</pre><h3>Pillar 2: Sendable — Safe Data Transfer Between Actors</h3><p>Sendable ensures a type can safely cross concurrency boundaries.</p><p>Concurrency boundary examples:</p><ul><li>actor → actor</li><li>task → actor</li><li>thread → actor</li></ul><pre>//Unsafe example:<br>class User {<br><br>    var name: String<br>}</pre><p>This is dangerous because multiple actors could modify same instance.</p><p>Swift prevents this. Safe example:</p><pre>struct User: Sendable {<br><br>    let name: String<br>}</pre><p>Struct creates copy. No shared mutable state. Safe.</p><p>Compiler enforcement example:</p><pre>actor UserManager {<br><br>//If User is class, Swift 6 error appears.<br>    func update(user: User) {}<br>}<br><br>// FIX<br>struct User: Sendable {<br>    let name: String<br>}</pre><h3>What Isolation and Sendable Together Achieve</h3><p>Isolation protects memory access.</p><p>Sendable protects memory transfer.</p><p>Together, they eliminate unsafe shared state.</p><h3>How Swift Concurrency Is Different From GCD</h3><p>This is the most important conceptual shift.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m1cIF3MXh29z5xUGo0Msfw.png" /></figure><pre>// GCD example:<br>queue.async {<br>    self.value += 1<br>}<br><br>// Swift concurrency equivalent:<br>actor Counter {<br>    var value = 0<br>}</pre><h3>Strict Concurrency in Swift 6</h3><p>Swift 6 enforces compile-time safety.</p><pre>class Manager {<br>    var value = 0<br>    func update() {<br>        Task {<br>            value += 1<br>        }<br>    }<br>}<br><br>// Error: Mutation of captured var in concurrently executing code</pre><p>Fix:</p><pre>actor Manager {<br>    var value = 0<br>    func update() {<br>        value += 1<br>    }<br>}</pre><h3>Preconcurrency — Supporting Legacy Code</h3><p>Many libraries were written before Swift concurrency existed.</p><pre>class LegacyAPI {<br>    func fetch(completion: @escaping (String) -&gt; Void) {}<br>}</pre><pre>@preconcurrency import LegacyLibrary</pre><p>This tells compiler:</p><p>This code was written before concurrency safety existed. Trust developer. It allows gradual migration.</p><p>MainActor violation:</p><pre>// wrong<br>Task {<br>    viewModel.title = &quot;Hello&quot;<br>}<br><br>// Correct<br>Task {<br>    await MainActor.run {<br>        viewModel.title = &quot;Hello&quot;<br>    }<br>}</pre><h3>Best Practices</h3><p>Use actors for shared mutable state.</p><p>Prefer structs over classes. <br>Use MainActor for UI.<br>Avoid shared mutable state.<br>Trust compiler errors.</p><h3>Mental Model That Makes Everything Click</h3><p>Imagine actor as a bank teller.</p><p>Mailbox → people waiting in line<br> Isolation → only teller accesses bank account<br> Sendable → safe documents passed to teller<br> Compiler → security guard enforcing rules</p><blockquote>Interview Questions and Answers</blockquote><h4>Question: What is actor mailbox?</h4><p>Answer:</p><p>Mailbox is an internal queue that stores requests to actor. Actor processes them sequentially, preventing race conditions.</p><h4>Question: What is isolation?</h4><p>Answer:</p><p>Isolation ensures only the owning actor can directly access its mutable state.</p><h4>Question: Why is Sendable needed?</h4><p>Answer:</p><p>Sendable ensures safe transfer of data between concurrency domains, preventing shared mutable state.</p><h4>Question: Why is Swift concurrency safer than GCD?</h4><p>Answer:</p><p>Swift concurrency provides compile-time race detection, while GCD relies on programmer discipline.</p><h4>Question: What is preconcurrency?</h4><p>Answer:</p><p>It allows legacy code to work without strict concurrency enforcement, enabling gradual migration.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0366bdd4dd44" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Review for Akshay Saini’s “Namaste React” Video Series]]></title>
            <link>https://medium.com/@arunk.pattanayak/review-forakshay-sainis-namaste-react-video-series-340d1f97a73c?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/340d1f97a73c</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[website-development]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sat, 13 Apr 2024 11:58:37 GMT</pubDate>
            <atom:updated>2024-04-13T12:25:49.333Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eIuU57tcs6paSPNiTngR5A.jpeg" /><figcaption>taken from <a href="https://namastedev.com/">https://namastedev.com/</a></figcaption></figure><p>As a new learner diving into the world of React development, you’re embarking on an exciting journey filled with endless possibilities. However, navigating this journey can be overwhelming, especially when faced with the complexities of a powerful library like React. Fortunately, there’s a guiding light to illuminate your path: Akshay Saini’s “Namaste React” video series.</p><p><strong>What is “Namaste React”?</strong></p><p>“Namaste React” isn’t just another video series — it’s your gateway to mastering React development from the ground up. Designed with new learners in mind, this comprehensive series breaks down the complicated parts of React into digestible lessons, making it accessible and enjoyable for beginners like us. With Akshay as our guide, we’ll explore React’s core concepts, build real-world projects, and gain the confidence to tackle any React challenge that comes our way.</p><p><strong>Key Features of “Namaste React”:</strong></p><blockquote>Beginner-Friendly Approach: Akshay Saini takes a step-by-step approach to teaching React, starting with the fundamentals and gradually building upon them. Concepts are explained in a clear and concise manner, making them easy to understand for beginners.</blockquote><blockquote>Practical Examples: Throughout the series, Akshay demonstrates real-world examples of React applications, showing how to implement common features and solve common challenges faced by developers.</blockquote><blockquote>Hands-on Exercises: To reinforce learning, each video includes hands-on exercises that allow viewers to practice what they’ve learned. These exercises help developers gain practical experience with React and build confidence in their skills.</blockquote><blockquote>Depth and Breadth: The “Namaste React” series covers a wide range of topics, including React components, state management, routing, hooks, context, and more. Akshay delves deep into each topic, providing a thorough understanding of React’s core concepts and best practices.</blockquote><blockquote>Engaging Presentation: Akshay Saini’s teaching style is engaging and approachable, making learning React an enjoyable experience. His enthusiasm for the subject shines through in every video, inspiring viewers to dive deeper into the world of React development.</blockquote><p><strong>Below are few instances explaining how Akshay’s video helped:</strong></p><p>In one of his videos, Akshay introduces the concept of React components, which are the building blocks of React applications. He explains that components are reusable, self-contained units of UI that can be composed together to build complex user interfaces.</p><p>To illustrate this concept, Akshay creates a simple React application with two components: a Header component and a Footer component. In the video, he demonstrates how to create each component using functional components, a feature introduced in React.</p><pre>// Header component<br>const Header = () =&gt; {<br>  return (<br>    &lt;header&gt;<br>      &lt;h1&gt;Welcome to my React App&lt;/h1&gt;<br>    &lt;/header&gt;<br>  );<br>};<br><br>// Footer component<br>const Footer = () =&gt; {<br>  return (<br>    &lt;footer&gt;<br>      &lt;p&gt;&amp;copy; 2024 My React App&lt;/p&gt;<br>    &lt;/footer&gt;<br>  );<br>};</pre><p>Akshay then explains how to compose these components together to create the main application layout. He demonstrates how to import and use the Header and Footer components within the main App component.</p><pre>// App component<br>const App = () =&gt; {<br>  return (<br>    &lt;div&gt;<br>      &lt;Header /&gt;<br>      &lt;p&gt;Main content goes here&lt;/p&gt;<br>      &lt;Footer /&gt;<br>    &lt;/div&gt;<br>  );<br>};</pre><p>Throughout the video, Akshay provides clear explanations of each step, highlighting important concepts such as component composition, JSX syntax, and the role of functional components in React development. He also encourages viewers to follow along and experiment with the code, reinforcing their understanding through hands-on practice.</p><p>By the end of the video, I have gained a good understanding of React components and how to create and compose them to build dynamic user interfaces(As beginner). I have also learned best practices for structuring React applications and are well-equipped to continue exploring React development with confidence.</p><p>Akshay Saini’s “Namaste React” video series stands out from other creators’ content in several ways:</p><blockquote><strong>Clear and Engaging Teaching Style:</strong> Akshay’s teaching style is known for its clarity and engagement. He explains complex concepts in a simple and straightforward manner, making them easy to understand for learners of all levels. His enthusiasm for the subject shines through in every video, keeping viewers engaged and motivated throughout the learning process.</blockquote><blockquote><strong>Comprehensive Coverage: </strong>The “Namaste React” series covers a wide range of topics, from the basics of React to more advanced concepts. Akshay takes a comprehensive approach to teaching React, ensuring that viewers gain a thorough understanding of the library and its capabilities. Whether you’re a beginner or an experienced developer, there’s something for everyone in the series.</blockquote><blockquote><strong>Practical Examples and Hands-on Exercises:</strong> Akshay provides practical examples and hands-on exercises throughout the series, allowing viewers to apply what they’ve learned in real-world scenarios. By working through these exercises, learners gain practical experience with React and build confidence in their skills.</blockquote><blockquote><strong>Focus on Best Practices:</strong> Akshay emphasises best practices throughout the series, teaching viewers not only how to use React but also how to use it effectively. He covers topics such as component composition, state management, and performance optimisation, helping viewers develop a solid foundation in React development.</blockquote><p>As you embark on your React journey with Akshay Saini’s “Namaste React” video series, remember that learning to code is not just about mastering a new technology — it’s about embracing the joy of discovery, the thrill of problem-solving, and the satisfaction of creating something meaningful. With Akshay’s expert guidance and your own dedication, there’s no limit to what you can achieve. The best part of this course is, it only costs ₹2300/-.</p><p>Link to his website: <a href="https://namastedev.com/">https://namastedev.com/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=340d1f97a73c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Refactoring to Resilience: Transitioning from MVVM to Clean Architecture]]></title>
            <link>https://medium.com/@arunk.pattanayak/refactoring-to-resilience-transitioning-from-mvvm-to-clean-architecture-37e40f868608?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/37e40f868608</guid>
            <category><![CDATA[clean-architecture]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[mvvm-architecture]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 07 Apr 2024 11:08:53 GMT</pubDate>
            <atom:updated>2024-04-07T11:08:53.012Z</atom:updated>
            <content:encoded><![CDATA[<p>In the constantly changing world of software development, architects and programmers are always looking for ways to improve code maintainability, scalability and testability. The change from Model-View-ViewModel (MVVM) architecture to Clean Architecture is one such shift that is gaining ground.</p><p>Because MVVM can separate concerns and provides data binding support, it has become a prevalent method of organising code in most modern mobile as well as web applications. But while projects become more complex, developers face tight coupling between layers, challenges in testing, and the need to keep separation clear.</p><p>Contrarily, Clean Architecture focuses on dividing responsibilities, being independent from external frameworks and ensuring that the code can be tested. It provides specific instructions on how best to split up your code into distinct layers with defined roles leading to less error-prone designs which allow for better maintenance and expansion.</p><p>This blogs will take you through the process of moving from MVVM to Clean Architecture. Specifically, we will explain what clean architecture entails including its guiding principles; we will also outline its constituents as opposed to MVVM. Besides this, there are strategies that can be used for rewriting existing MVVM-based codes so that it follows principles of a clean architecture as well as making development smoother and easier maintenance.</p><pre>{<br>  &quot;data&quot;: [<br>    {<br>      &quot;id&quot;: &quot;bitcoin&quot;,<br>      &quot;rank&quot;: &quot;1&quot;,<br>      &quot;symbol&quot;: &quot;BTC&quot;,<br>      &quot;name&quot;: &quot;Bitcoin&quot;,<br>      &quot;supply&quot;: &quot;18824943.0000000000000000&quot;,<br>      &quot;maxSupply&quot;: &quot;21000000.0000000000000000&quot;,<br>      &quot;marketCapUsd&quot;: &quot;1104472461633.1075176780327501&quot;,<br>      &quot;volumeUsd24Hr&quot;: &quot;66566480087.0421125881533446&quot;,<br>      &quot;priceUsd&quot;: &quot;58602.6054006234050000&quot;,<br>      &quot;changePercent24Hr&quot;: &quot;0.3583330721187001&quot;,<br>      &quot;vwap24Hr&quot;: &quot;57638.2622376795013008&quot;<br>    },<br>    // More assets...<br>  ],<br>  &quot;timestamp&quot;: 1649297859407<br>}</pre><p>We will work on above JSON response to mock our code.<br><a href="https://docs.coincap.io/">https://docs.coincap.io/</a></p><pre><br>struct AssetData: Codable {<br>    let data: [Asset]<br>    let timestamp: TimeInterval<br>}<br><br>struct Asset: Codable {<br>    let id: String<br>    let rank: String<br>    let symbol: String<br>    let name: String<br>    let supply: String<br>    let maxSupply: String<br>    let marketCapUsd: String<br>    let volumeUsd24Hr: String<br>    let priceUsd: String<br>    let changePercent24Hr: String<br>    let vwap24Hr: String<br>}</pre><p>This will be our model structure for the same.</p><pre>import UIKit<br><br>class AssetListViewController: UIViewController {<br>    @IBOutlet weak var collectionView: UICollectionView!<br>    <br>    let viewModel = AssetListViewModel()<br>    <br>    // Declare diffable data source<br>    var dataSource: UICollectionViewDiffableDataSource&lt;Section, Asset&gt;!<br>    <br>    enum Section {<br>        case main<br>    }<br>    <br>    override func viewDidLoad() {<br>        super.viewDidLoad()<br>        <br>        collectionView.collectionViewLayout = createLayout()<br>        <br>        // Initialize and configure diffable data source<br>        dataSource = UICollectionViewDiffableDataSource&lt;Section, Asset&gt;(collectionView: collectionView) { collectionView, indexPath, asset in<br>            return collectionView.dequeueConfiguredReusableCell(using: self.createCellRegistration(), for: indexPath, item: asset)<br>        }<br>        <br>        viewModel.fetchAssets()<br>        <br>        viewModel.$assets<br>            .sink { [weak self] assets in<br>                self?.applySnapshot(assets: assets)<br>            }<br>            .store(in: &amp;viewModel.cancellables)<br>        <br>        // Handle errors<br>        viewModel.$error<br>            .sink { error in<br>                if let error = error {<br>                    print(&quot;Error fetching assets: \(error)&quot;)<br>                }<br>            }<br>            .store(in: &amp;viewModel.cancellables)<br>    }<br>    <br>    private func createLayout() -&gt; UICollectionViewLayout {<br>        let layout = UICollectionViewCompositionalLayout { _, _ in<br>            let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(50))<br>            let item = NSCollectionLayoutItem(layoutSize: itemSize)<br>            let group = NSCollectionLayoutGroup.horizontal(layoutSize: itemSize, subitem: item, count: 1)<br>            let section = NSCollectionLayoutSection(group: group)<br>            return section<br>        }<br>        return layout<br>    }<br>    <br>    private func createCellRegistration() -&gt; UICollectionView.CellRegistration&lt;UICollectionViewListCell, Asset&gt; {<br>        return UICollectionView.CellRegistration&lt;UICollectionViewListCell, Asset&gt; { cell, indexPath, asset in<br>            var contentConfiguration = UIListContentConfiguration.valueCell()<br>            contentConfiguration.text = asset.name<br>            contentConfiguration.secondaryText = &quot;\(asset.symbol) - \(asset.priceUsd)&quot;<br>            cell.contentConfiguration = contentConfiguration<br>        }<br>    }<br>    <br>    private func applySnapshot(assets: [Asset]) {<br>        var snapshot = NSDiffableDataSourceSnapshot&lt;Section, Asset&gt;()<br>        snapshot.appendSections([.main])<br>        snapshot.appendItems(assets)<br>        dataSource.apply(snapshot, animatingDifferences: true)<br>    }<br>}<br><br>extension AssetListViewController: UICollectionViewDelegate {<br>    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {<br>        guard let asset = dataSource.itemIdentifier(for: indexPath) else { return }<br><br>        //On tapping cell data is loaded in AssetDetailViewController <br>        guard let asset = dataSource.itemIdentifier(for: indexPath) else { return }<br>        coordinator?.showAssetDetail(asset: asset)<br>    }<br>}</pre><p>This is our view controller to present the data.</p><pre><br><br>class APIUtility {<br>    static let shared = APIUtility()<br>    <br>    private init() {}<br>    <br>    func fetchAssets() -&gt; AnyPublisher&lt;AssetData, Error&gt; {<br>        guard let url = URL(string: &quot;http://api.coincap.io/v2/assets&quot;) else {<br>            return Fail(error: NSError(domain: &quot;Invalid URL&quot;, code: 0, userInfo: nil)).eraseToAnyPublisher()<br>        }<br>        <br>        return URLSession.shared.dataTaskPublisher(for: url)<br>            .map { $0.data }<br>            .decode(type: AssetData.self, decoder: JSONDecoder())<br>            .eraseToAnyPublisher()<br>    }<br>}<br><br><br>class AssetListViewModel: ObservableObject {<br>    @Published var assets: [Asset] = []<br>    @Published var error: Error?<br>    private var cancellables = Set&lt;AnyCancellable&gt;()<br>    <br>    func fetchAssets() {<br>        APIUtility.shared.fetchAssets()<br>            .receive(on: DispatchQueue.main)<br>            .sink { completion in<br>                if case let .failure(error) = completion {<br>                    self.error = error<br>                }<br>            } receiveValue: { assetData in<br>                self.assets = assetData.data<br>            }<br>            .store(in: &amp;cancellables)<br>    }<br>}</pre><pre>protocol Coordinator {<br>    func start()<br>    func showAssetDetail(asset: Asset)<br>    // Add other navigation methods as needed<br>}<br><br>class MainCoordinator: Coordinator {<br>    private let navigationController: UINavigationController<br>    <br>    init(navigationController: UINavigationController) {<br>        self.navigationController = navigationController<br>    }<br>    <br>    func start() {<br>        let assetListViewController = AssetListViewController.instantiate()<br>        assetListViewController.coordinator = self<br>        navigationController.pushViewController(assetListViewController, animated: false)<br>    }<br>    <br>    func showAssetDetail(asset: Asset) {<br>        let assetDetailViewController = AssetDetailViewController.instantiate()<br>        assetDetailViewController.asset = asset<br>        navigationController.pushViewController(assetDetailViewController, animated: true)<br>    }<br>}<br><br>extension UIViewController {<br>    static func instantiate() -&gt; Self {<br>        let storyboard = UIStoryboard(name: &quot;Main&quot;, bundle: nil)<br>        return storyboard.instantiateViewController(withIdentifier: String(describing: self)) as! Self<br>    }<br>}</pre><p>A little bonus, let’s inject the asset using a property wrapper:</p><pre>@propertyWrapper<br>struct InjectAsset {<br>    var asset: Asset<br>    <br>    init(wrappedValue: Asset) {<br>        self.asset = wrappedValue<br>    }<br>    <br>    var wrappedValue: Asset {<br>        get { return asset }<br>        set { asset = newValue }<br>    }<br>}<br><br>class AssetDetailViewController: UIViewController {<br>    // Use the property wrapper to inject the asset<br>    @InjectAsset var asset: Asset<br>    <br>    override func viewDidLoad() {<br>        super.viewDidLoad()<br>        print(&quot;Asset name: \(asset.name)&quot;)<br>    }<br>}</pre><h3>How Clean Architecture is different from MVVM-C?</h3><p>Clean Architecture and MVVM-C (Model-View-ViewModel-Coordinator) are both architectural patterns used in iOS development, but they serve different purposes and have different focuses. Here’s how they compare:</p><h4>MVVM-C (Model-View-ViewModel-Coordinator):</h4><p><strong>1. Model: </strong>Represents the data model of the application.<br><strong>2. View:</strong> Represents the user interface (UI) of the application.<br><strong>3. ViewModel:</strong> Acts as an intermediary between the View and the Model. It exposes data from the Model to the View in a format suitable for presentation and translates user interactions from the View into actions that affect the Model.<br><strong>4. Coordinator:</strong> Handles navigation and flow between different screens (ViewControllers) in the application. It typically abstracts away the navigation logic from the ViewControllers.</p><p><strong>Characteristics:</strong><br><strong>1. Separation of Concerns:</strong> MVVM-C separates concerns by assigning specific responsibilities to each component. Views focus on UI rendering, ViewModels handle business logic, and Coordinators manage navigation flow.<br><strong>2. Testability: </strong>MVVM-C promotes testability by isolating business logic from UI code, making it easier to write unit tests for ViewModels and Coordinators.<br><strong>3. Reusability:</strong> Components in MVVM-C, especially ViewModels, can be reused across different parts of the application, promoting code reuse and maintainability.</p><h4>Clean Architecture:</h4><p>Clean Architecture, as proposed by Robert C. Martin (Uncle Bob), emphasises a clear separation of concerns and independence of the application’s business logic from external concerns like UI frameworks and database frameworks. It consists of multiple layers, including:</p><p><strong>1. Entities:</strong> Represents the core business logic and data structures of the application.<br><strong>2. Use Cases:</strong> Contains application-specific business rules and logic. It defines actions that can be performed within the application.<br><strong>3. Interface Adapters:</strong> Converts data from the Use Cases into a format suitable for presentation in the UI and vice versa. This layer includes Presenters (or ViewModels), which are responsible for preparing data for display.<br><strong>4. Frameworks &amp; Drivers:</strong> Contains external frameworks, such as UI frameworks (e.g., UIKit) and database frameworks. These frameworks are considered implementation details and are kept separate from the core business logic.</p><h4>Characteristics:</h4><p>1. Decoupling: Clean Architecture promotes loose coupling between different components of the application, making it easier to modify and maintain the codebase.<br>2. Dependency Inversion Principle (DIP): Components in Clean Architecture depend on abstractions rather than concrete implementations, allowing for easier substitution and testing.<br>3. Isolation of Concerns: Each layer in Clean Architecture has a specific responsibility, and dependencies flow inward toward the core business logic, enforcing a clear separation of concerns.</p><h4>Differences:</h4><p>1. Focus: MVVM-C focuses more on structuring UI-related code and managing navigation flow, while Clean Architecture focuses on designing the core business logic of the application.<br>2. Layered Architecture vs. Pattern: Clean Architecture is an architectural design principle that can be applied to various design patterns, including MVVM-C. MVVM-C, on the other hand, is a specific pattern that addresses UI architecture and navigation flow.<br>3. Granularity: Clean Architecture provides a more granular separation of concerns with its layered approach, whereas MVVM-C combines ViewModel and Coordinator responsibilities into one layer for managing UI logic and navigation.</p><p>In summary, while MVVM-C and Clean Architecture share some similarities in promoting separation of concerns and testability, they serve different purposes and can be complementary in structuring iOS applications. Developers can choose the one that best fits the requirements and complexity of their projects.</p><p>Now let’s jump into converting our project from MVVM-C to Clean Architecture.</p><p>To comply with the Clean Architecture principles, this code will be split into three sections: Presentation, Domain and Data. Each of these segments will have its own duties ensuring that the system is better organized and easier to test. Here is a step by step guide on how to refactor AssetListViewController and AssetDetailViewController so that they work in this structure.</p><p>Presentation Layer:</p><ul><li>Contains UI-related logic and components.</li><li>UIViewController instances reside in this layer.</li><li>Handles user input and presents data to the user.</li></ul><p>Domain Layer:</p><ul><li>Contains business logic and use cases.</li><li>Defines entities and business rules.</li></ul><p>Data Layer:</p><ul><li>Handles data retrieval and persistence.</li><li>Communicates with external sources like APIs or databases.</li></ul><p>Presentation Layer:</p><pre>import UIKit<br><br>protocol AssetListViewProtocol: AnyObject {<br>    func presentFetchedAssets(_ assets: [Asset])<br>    func displayError(_ error: Error)<br>}<br><br>class AssetListViewController: UIViewController, AssetListViewProtocol {<br>    var presenter: AssetListPresenterProtocol!<br>    <br>    override func viewDidLoad() {<br>        super.viewDidLoad()<br>        presenter.viewDidLoad()<br>    }<br>    <br>    // Implement AssetListViewProtocol methods<br>    func displayAssets(_ assets: [Asset]) {<br>        // Update UI with assets<br>    }<br>    <br>    func displayError(_ error: Error) {<br>        // Display error message<br>    }<br>}<br><br>// MARK: - AssetListPresenter<br><br>protocol AssetListPresenterProtocol {<br>    var view: AssetListViewProtocol? { get set }<br>    func fetchAssets()<br>}<br><br>class AssetListPresenter: AssetListPresenterProtocol {<br>    weak var view: AssetListViewProtocol?<br>    let interactor: AssetListInteractorProtocol<br>    <br>    init(interactor: AssetListInteractorProtocol) {<br>        self.interactor = interactor<br>    }<br>    <br>    func fetchAssets() {<br>        interactor.fetchAssets()<br>    }<br>    <br>    func presentFetchedAssets(_ assets: [Asset]) {<br>        view?.displayAssets(assets)<br>    }<br>    <br>    func presentError(_ error: Error) {<br>        view?.displayError(error)<br>    }<br>}<br><br>// MARK: - AssetListInteractor<br><br>protocol AssetListInteractorProtocol {<br>    var presenter: AssetListPresenterProtocol? { get set }<br>    func fetchAssets()<br>}<br><br>class AssetListInteractor: AssetListInteractorProtocol {<br>    weak var presenter: AssetListPresenterProtocol?<br>    let assetService: AssetServiceProtocol<br>    <br>    private var cancellables = Set&lt;AnyCancellable&gt;()<br>    <br>    init(assetService: AssetServiceProtocol) {<br>        self.assetService = assetService<br>    }<br>    <br>    func fetchAssets() {<br>        assetService.fetchAssets()<br>            .sink(receiveCompletion: { [weak self] completion in<br>                if case let .failure(error) = completion {<br>                    self?.presenter?.presentError(error)<br>                }<br>            }, receiveValue: { [weak self] assets in<br>                self?.presenter?.presentFetchedAssets(assets)<br>            })<br>            .store(in: &amp;cancellables)<br>    }<br>}<br><br>protocol AssetServiceProtocol {<br>    func fetchAssets() -&gt; AnyPublisher&lt;[Asset], Error&gt;<br>}<br><br>struct AssetDataResponse: Codable {<br>    let data: [Asset]<br>}</pre><h3>Domain Layer:</h3><pre>struct Asset {<br>    let id: String<br>    let name: String<br>    let symbol: String<br>    let priceUsd: String<br>}</pre><h3>Data Layer:</h3><pre>class AssetService: AssetServiceProtocol {<br>    func fetchAssets() -&gt; AnyPublisher&lt;[Asset], Error&gt; {<br>        guard let url = URL(string: &quot;http://api.coincap.io/v2/assets&quot;) else {<br>            return Fail(error: URLError(.badURL)).eraseToAnyPublisher()<br>        }<br>        <br>        return URLSession.shared.dataTaskPublisher(for: url)<br>            .map(\.data)<br>            .decode(type: AssetDataResponse.self, decoder: JSONDecoder())<br>            .map(\.data)<br>            .eraseToAnyPublisher()<br>    }<br>}</pre><h3>Conclusion:</h3><p>Both MVVM-C and Clean Architecture are valid architectural patterns for iOS development, and the choice between them depends on factors such as project requirements, team expertise, and personal preferences. It’s essential to evaluate the specific needs and goals of your project and consider factors such as complexity, maintainability, testability, and scalability when selecting an architecture. Ultimately, the “better” architecture is the one that best fits the needs of your project and team.</p><p>I will recommend to read below blogs/Book for more information.</p><p>References:<br><a href="https://betterprogramming.pub/ios-clean-architecture-using-swiftui-combine-and-dependency-injection-for-dummies-2e44600f952b">https://betterprogramming.pub/ios-clean-architecture-using-swiftui-combine-and-dependency-injection-for-dummies-2e44600f952b</a></p><p><a href="https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps">https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps</a></p><p><a href="https://medium.com/nerd-for-tech/mvvm-coordinators-ios-architecture-tutorial-fb27eaa36470">MVVM+Coordinators IOS Architecture Tutorial</a></p><p><a href="https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/">https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37e40f868608" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Part 2: Conquering Combine Swift Interviews: A Developer’s Guide]]></title>
            <link>https://medium.com/@arunk.pattanayak/part-2-conquering-combine-swift-interviews-a-developers-guide-a1795682b73c?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/a1795682b73c</guid>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[interview]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 31 Mar 2024 16:41:17 GMT</pubDate>
            <atom:updated>2024-03-31T16:41:17.404Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://medium.com/@arunk.pattanayak/conquering-combine-swift-interviews-a-developers-guide-c9cd73ecd881">https://medium.com/@arunk.pattanayak/conquering-combine-swift-interviews-a-developers-guide-c9cd73ecd881</a></p><h4>Q. What is the purpose of the map operator in Combine Swift?</h4><p>Answer: The map operator transforms each element emitted by a publisher by applying a closure to it, producing a new value. It allows for the conversion of one type of value to another or the modification of values emitted by a publisher.</p><h4>Q. Explain the difference between the map and flatMap operators in Combine. Provide examples to illustrate your explanation.</h4><p>Answer: The map operator transforms each element emitted by a publisher independently, while the flatMap operator flattens nested publishers and merges their emissions into a single stream. For example, map would transform each integer emitted by a publisher into a string, while flatMap could handle nested publishers and flatten their emissions into a single stream.</p><h4>Q. How does the filter operator work in Combine? Provide a scenario where you would use it.</h4><p>Answer: The filter operator evaluates each element emitted by a publisher against a predicate closure. It only allows elements that satisfy the predicate to pass through. For example, you could use the filter operator to filter out even numbers from a stream of integers.</p><h4>Q. What is the role of the merge operator in Combine? How does it handle multiple publishers?</h4><p>Answer: The merge operator combines emissions from multiple publishers into a single stream. It subscribes to all publishers simultaneously and forwards values from any of them to its downstream subscriber as they arrive. This allows you to merge streams of data from different sources, such as user input events and network responses.</p><h4>Q. Describe the behavior of the flatMap operator when working with sequences of publishers. Provide an example scenario where you would use it.</h4><p>Answer: The flatMap operator subscribes to each publisher emitted by a sequence of publishers and merges their emissions into a single stream. It&#39;s useful when you have a sequence of asynchronous operations that produce publishers, and you want to flatten their emissions into a single stream. For example, you could use flatMap to handle a sequence of network requests where each request emits a publisher of response data.</p><h4>Q. Explain the purpose of the compactMap operator in Combine. How does it differ from the map operator?</h4><p>Answer: The compactMap operator applies a transformation to each element emitted by a publisher and filters out any resulting nil values. It&#39;s similar to the map operator but automatically handles optional values, unwrapping them and discarding nil results. This is useful when you want to transform optional values emitted by a publisher into non-optional values.</p><h4>Q. What is backpressure, and how does Combine handle it? Discuss the role of the buffer and throttle operators in managing backpressure.</h4><p>Answer: Backpressure occurs when a downstream subscriber is unable to keep up with the rate of emissions from an upstream publisher, leading to a buildup of unprocessed data. Combine handles backpressure by using strategies such as buffering, throttling, or dropping emissions. The buffer operator buffers emitted values and delivers them to the downstream subscriber at a controlled rate, while the throttle operator limits the rate of emissions by discarding values emitted too frequently.</p><h4>Q. How does the combineLatest operator work in Combine? Provide an example scenario where you would use it.</h4><p>Answer: The combineLatest operator combines the most recent values emitted by multiple publishers into a single stream, producing a new value whenever any of the combined publishers emit a value. It&#39;s useful for scenarios where you need to react to changes in multiple sources of data simultaneously, such as updating UI elements based on the latest user input and network responses.</p><h4>Q. Discuss the difference between the switchToLatest and flatMapLatest operators in Combine. When would you use each of them?</h4><p>Answer: Both switchToLatest and flatMapLatest operators subscribe to each publisher emitted by an upstream publisher, but they handle new emissions differently. switchToLatest cancels the previous subscription as soon as a new publisher is emitted, while flatMapLatest cancels the previous subscription only when a new publisher emits a value. You would use switchToLatest when you want to ignore emissions from previous publishers and only react to emissions from the latest publisher, while flatMapLatest is useful when you want to process emissions from each publisher sequentially, with only the emissions from the latest publisher being forwarded downstream.</p><h4>Q. Explain the purpose of the scan operator in Combine. Provide an example scenario where you would use it to maintain state.</h4><p>Answer: The scan operator applies an accumulation closure to each element emitted by a publisher, maintaining a state that is updated with each emission. It&#39;s useful for maintaining and updating state over time, such as calculating running totals or aggregating values. For example, you could use scan to calculate the cumulative sum of values emitted by a publisher.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a1795682b73c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Conquering Combine Swift Interviews: A Developer’s Guide]]></title>
            <link>https://medium.com/@arunk.pattanayak/conquering-combine-swift-interviews-a-developers-guide-c9cd73ecd881?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/c9cd73ecd881</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[combine]]></category>
            <category><![CDATA[reactive-programming]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 31 Mar 2024 16:36:07 GMT</pubDate>
            <atom:updated>2024-07-26T23:52:32.645Z</atom:updated>
            <content:encoded><![CDATA[<p>Greetings, fellow warriors of the code realm, and welcome to the battlefield of Combine Swift interviews! Imagine this: you’re the mighty Kratos, wielding your Blades of Coding Fury, facing off against the daunting challenges of asynchronous programming and reactive streams. The battlefield is littered with syntax errors, and the air crackles with the energy of unresolved promises. But fear not, for you are the god of code, and you shall emerge victorious from this epic saga! With the wisdom of Athena and the strength of Hercules, we shall navigate through this labyrinth of Combine Swift with the finesse of a true gaming deity. So sharpen your axes (or keyboards), summon the spirits of the coding Titans, and let’s embark on this epic odyssey of interview preparation questions in Combine Swift! May the gods of coding smile upon us, and may our code be as legendary as the tales of ancient Greece!</p><p>Understanding Combine Swift:</p><ul><li>Definition: Combine Swift is a powerful framework introduced by Apple, revolutionizing reactive programming in Swift.</li><li>Principles: It operates on the principles of reactive programming, enabling developers to handle asynchronous events and data streams efficiently.</li><li>Core Components: Combine comprises essential components like Publishers, Subscribers, and Operators, each playing a crucial role in data flow and manipulation.</li></ul><p>Essential Concepts in Combine Swift:</p><p>In preparing for Combine Swift interviews, it’s crucial to have a deep understanding of its core concepts. Let’s explore these concepts further with examples:</p><p>Publishers and Subscribers:</p><p><strong>Definition: </strong>Publishers emit values over time, and subscribers receive and handle these values. This mechanism forms the backbone of reactive programming in Combine.</p><pre>import Combine<br><br>let publisher = Just(&quot;Hello, World!&quot;) // Publisher emitting a single value<br>let subscriber = Subscribers.Sink&lt;String, Never&gt;(<br>    receiveCompletion: { completion in<br>        // Handle completion (not applicable in this case)<br>    },<br>    receiveValue: { value in<br>        print(value) // Output: Hello, World!<br>    }<br>)<br><br>publisher.subscribe(subscriber)</pre><p>Operators:</p><p><strong>Definition:</strong> Operators in Combine transform, combine, or manipulate the data emitted by publishers, allowing for powerful data processing pipelines.import Combine</p><pre>let numbers = [1, 2, 3, 4, 5]<br>let publisher = numbers.publisher<br><br>publisher<br> .map { $0 * 2 } // Double each number<br> .filter { $0.isMultiple(of: 3) } // Filter multiples of 3<br> .sink { value in<br> print(value) // Output: 6<br> }<br> .store(in: &amp;cancellables)</pre><p>Error Handling:</p><p><strong>Definition:</strong> Combine provides operators to handle errors emitted by publishers, ensuring graceful error propagation and recovery within data processing pipelines.</p><pre>import Combine<br><br>enum CustomError: Error {<br>    case someError<br>}<br><br>let publisher = Fail&lt;Int, CustomError&gt;(error: .someError)<br><br>publisher<br>    .mapError { error in<br>        return &quot;An error occurred: \(error)&quot; // Map the error to a user-friendly message<br>    }<br>    .sink(<br>        receiveCompletion: { completion in<br>            switch completion {<br>            case .finished:<br>                print(&quot;Finished&quot;) // This won&#39;t be called in this case<br>            case .failure(let error):<br>                print(error) // Output: An error occurred: someError<br>            }<br>        },<br>        receiveValue: { value in<br>            // This won&#39;t be called in this case<br>        }<br>    )<br>    .store(in: &amp;cancellables)</pre><p>Integration with SwiftUI and UIKit:</p><p>Combine Swift seamlessly integrates with both SwiftUI and UIKit, providing developers with powerful tools to build reactive and interactive user interfaces. Let’s explore how Combine enhances the development experience in both frameworks:</p><p>Integration with SwiftUI:</p><p><strong>Declarative UI Programming:</strong> SwiftUI’s declarative approach to UI programming aligns perfectly with Combine’s reactive paradigm. Developers can use Combine to handle asynchronous operations, data updates, and state management seamlessly within SwiftUI views.</p><p><strong>Data Binding:</strong> Combine enables bidirectional data binding in SwiftUI, allowing changes in data to automatically update the UI and vice versa. Publishers can emit values, and SwiftUI views can react to these changes instantly, ensuring a responsive and dynamic user experience.</p><p><strong>Event Handling:</strong> SwiftUI events, such as user interactions or lifecycle events, can be captured and processed using Combine publishers. This enables developers to handle user input, network requests, and other asynchronous tasks directly within SwiftUI views.</p><pre>import SwiftUI<br>import Combine<br><br>class ViewModel: ObservableObject {<br>    @Published var count = 0<br>    <br>    func increment() {<br>        count += 1<br>    }<br>}<br><br>struct ContentView: View {<br>    @ObservedObject var viewModel: ViewModel<br>    <br>    var body: some View {<br>        VStack {<br>            Text(&quot;Count: \(viewModel.count)&quot;)<br>            Button(&quot;Increment&quot;) {<br>                viewModel.increment()<br>            }<br>        }<br>    }<br>}<br><br>struct ContentView_Previews: PreviewProvider {<br>    static var previews: some View {<br>        ContentView(viewModel: ViewModel())<br>    }<br>}</pre><p>Integration with UIKit:</p><p><strong>Combine and UIKit Interoperability:</strong> While UIKit follows an imperative programming model, developers can still leverage Combine to introduce reactive features into UIKit-based applications. Combine publishers can be integrated seamlessly with UIKit components like UIViews, UIViewControllers, and UIKit-based libraries.</p><p><strong>Asynchronous Operations:</strong> Combine simplifies asynchronous operations in UIKit applications by providing a unified API for handling asynchronous tasks, such as network requests, user input processing, and data updates.</p><p><strong>State Management:</strong> Combine facilitates state management in UIKit applications, enabling developers to propagate state changes across different parts of the application efficiently. This ensures consistency and coherence in the user interface, even in complex UIKit-based architectures.</p><pre>import UIKit<br>import Combine<br><br>class ViewModel {<br>    @Published var isLoading = false<br>    private var cancellables = Set&lt;AnyCancellable&gt;()<br>    <br>    func fetchData() {<br>        isLoading = true<br>        <br>        URLSession.shared.dataTaskPublisher(for: URL(string: &quot;https://api.example.com/data&quot;)!)<br>            .map { $0.data }<br>            .decode(type: MyData.self, decoder: JSONDecoder())<br>            .receive(on: DispatchQueue.main)<br>            .sink(receiveCompletion: { _ in<br>                self.isLoading = false<br>            }, receiveValue: { data in<br>                // Handle received data<br>            })<br>            .store(in: &amp;cancellables)<br>    }<br>}</pre><p>Testing Strategies for Combine Code:</p><p>As an interviewee preparing for Combine Swift interview questions, it’s essential to demonstrate a thorough understanding of testing strategies for Combine code. Let’s delve deeper into the unit testing aspect:</p><p>Unit Testing Combine Code:</p><ul><li>Purpose: Unit tests play a critical role in ensuring the correctness, reliability, and maintainability of Combine code. They validate the behavior of individual components or units of code in isolation, helping detect and prevent regressions.</li><li>Setup: Begin by setting up XCTest cases dedicated to testing Combine code. Import the necessary modules (import Combine) and create test cases for each component or functionality you want to verify.</li><li>Testing Publishers: Write tests to verify the behavior of publishers, including their ability to emit values, complete successfully, or fail with errors. Utilize XCTestExpectation or XCTestExpectation.waitForExpectations(timeout:) for testing asynchronous publishers.</li><li>Testing Subscribers: Test subscribers to ensure they receive and handle events emitted by publishers correctly. Validate that subscribers react appropriately to value emissions, completion events, and errors.</li><li>Testing Combine Pipelines: Verify the behavior of Combine pipelines by chaining operators and comparing the resulting output against expected values. Employ XCTest assertions to check the output of the pipeline.</li><li>Handling Asynchronous Operations: Given that Combine deals with asynchronous operations, ensure that your unit tests handle asynchronous behavior effectively. Leverage XCTestExpectation or XCTestExpectation.waitForExpectations(timeout:) to wait for asynchronous tasks to complete.</li><li>Error Handling: Write tests to validate error handling mechanisms within Combine pipelines. Test scenarios where publishers emit errors, and verify that subscribers handle errors appropriately using error handling operators such as mapError, catch, or replaceError.</li></ul><pre>import XCTest<br>import Combine<br><br>class CombineUnitTests: XCTestCase {<br>    var cancellables = Set&lt;AnyCancellable&gt;()<br><br>    func testCombinePipeline() {<br>        // Given<br>        let inputPublisher = Just(5)<br>        let expectedOutput = 10<br>        <br>        // When<br>        let outputPublisher = inputPublisher<br>            .map { $0 * 2 }<br>        <br>        // Then<br>        let expectation = XCTestExpectation(description: &quot;Pipeline Output Matches Expected Value&quot;)<br>        <br>        outputPublisher<br>            .sink { value in<br>                XCTAssertEqual(value, expectedOutput)<br>                expectation.fulfill()<br>            }<br>            .store(in: &amp;cancellables)<br>        <br>        wait(for: [expectation], timeout: 1)<br>    }<br>    <br>    // Additional tests for error handling, asynchronous operations, etc.<br>}</pre><p>Debugging Techniques for Combine Code in Tests:</p><ul><li>Logging and Print Statements: Use print statements or logging frameworks to log intermediate values or events within Combine pipelines during test execution, aiding in tracing and debugging.</li><li>Breakpoints: Set breakpoints in XCTest cases to pause execution and inspect the state of Combine components (publishers, subscribers, etc.) at various points in the test, facilitating debugging.</li><li>Visualization Tools: Utilize Xcode’s Debug View Hierarchy and Debug Memory Graph to visualize Combine pipelines and identify potential issues with memory management or subscription lifecycles during test debugging.</li></ul><p>Debugging Techniques for Combine Code:</p><p>Understanding debugging techniques is essential for troubleshooting issues and ensuring the reliability of Combine code. Let’s explore debugging strategies with examples:</p><p>Print statements provide valuable insights into the execution flow and intermediate values within Combine pipelines.</p><pre>import Combine<br><br>let numbers = [1, 2, 3, 4, 5]<br>let publisher = numbers.publisher<br><br>publisher<br>    .map { $0 * 2 } // Double each number<br>    .sink { value in<br>        print(value) // Output: 2, 4, 6, 8, 10<br>    }<br>    .store(in: &amp;cancellables)</pre><p>Breakpoints:</p><ul><li>Usage: Set breakpoints in XCTest cases or within your code to pause execution and inspect the state of Combine components at various stages.</li><li>Example: Place breakpoints at critical points in your Combine pipeline to analyse the values emitted by publishers, operators, or subscribers.</li></ul><p>Visualisation Tools:</p><ul><li>Usage: Utilise Xcode’s Debug View Hierarchy and Debug Memory Graph to visualise Combine pipelines and identify potential issues with memory management or subscription lifecycles.</li><li>Example: Use the Debug Memory Graph to inspect the lifecycle of Combine components, ensuring proper memory management and subscription handling.</li></ul><pre>import Combine<br><br>let numbers = [1, 2, 3, 4, 5]<br>let publisher = numbers.publisher<br><br>publisher<br>    .map { $0 * 2 } // Double each number<br>    .filter { $0.isMultiple(of: 3) } // Filter multiples of 3<br>    .sink { value in<br>        print(value) // Output: 6<br>    }<br>    .store(in: &amp;cancellables)</pre><p>In this example, we’re debugging a Combine pipeline that doubles each number in the array and filters out multiples of 3. By adding print statements or breakpoints, we can inspect the intermediate values at each stage of the pipeline and ensure the expected output.</p><p>Real-world Application and Project-based Questions:</p><ul><li>Scenario-based Challenges: Interviewers often present real-world scenarios and ask candidates to design Combine-based solutions, assessing their problem-solving skills and understanding of Combine framework.</li><li>Project Integration Tasks: Integrating Combine into existing projects or enhancing functionalities using Combine principles may be part of the interview process, evaluating candidates’ practical application of Combine concepts.</li></ul><p>Scenario-based Challenge:</p><ul><li>Scenario: Imagine you’re developing a weather application that fetches weather data from a remote API. The application needs to display real-time weather updates and provide the user with the option to refresh the data manually.</li><li>Question: How would you implement the data fetching and refreshing functionality using Combine Swift? Consider error handling, asynchronous operations, and UI updates.</li></ul><pre>import Combine<br><br>class WeatherViewModel: ObservableObject {<br>    @Published var weather: Weather?<br>    @Published var isLoading = false<br>    private var cancellables = Set&lt;AnyCancellable&gt;()<br>    <br>    func fetchData() {<br>        isLoading = true<br>        <br>        URLSession.shared.dataTaskPublisher(for: URL(string: &quot;https://api.example.com/weather&quot;)!)<br>            .map { $0.data }<br>            .decode(type: Weather.self, decoder: JSONDecoder())<br>            .receive(on: DispatchQueue.main)<br>            .sink(receiveCompletion: { _ in<br>                self.isLoading = false<br>            }, receiveValue: { weather in<br>                self.weather = weather<br>            })<br>            .store(in: &amp;cancellables)<br>    }<br>}</pre><p>Project Integration Tasks:</p><ul><li>Scenario: You’re tasked with integrating Combine Swift into an existing project that relies heavily on asynchronous operations, such as network requests, database queries, and user input processing. The project also involves updating the UI based on real-time data changes.</li><li>Question: How would you integrate Combine into the existing project architecture to improve code maintainability, responsiveness, and scalability? Provide examples of how Combine can be used to handle asynchronous tasks and update the UI dynamically.</li></ul><pre>import Combine<br><br>class ViewModel {<br>    @Published var isLoading = false<br>    private var cancellables = Set&lt;AnyCancellable&gt;()<br>    <br>    func fetchData() {<br>        isLoading = true<br>        <br>        URLSession.shared.dataTaskPublisher(for: URL(string: &quot;https://api.example.com/data&quot;)!)<br>            .map { $0.data }<br>            .decode(type: MyData.self, decoder: JSONDecoder())<br>            .receive(on: DispatchQueue.main)<br>            .sink(receiveCompletion: { _ in<br>                self.isLoading = false<br>            }, receiveValue: { data in<br>                // Handle received data<br>            })<br>            .store(in: &amp;cancellables)<br>    }<br>}</pre><p>There is a part two of this article, where we will be covering question related to operators in combine.</p><p><a href="https://medium.com/@arunk.pattanayak/part-2-conquering-combine-swift-interviews-a-developers-guide-a1795682b73c">https://medium.com/@arunk.pattanayak/part-2-conquering-combine-swift-interviews-a-developers-guide-a1795682b73c</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c9cd73ecd881" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Unlocking the Power of Dependency Injection: Dive into Resolver Framework]]></title>
            <link>https://medium.com/@arunk.pattanayak/unlocking-the-power-of-dependency-injection-dive-into-resolver-framework-e070095dd96e?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/e070095dd96e</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[interview-preparation]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 31 Mar 2024 14:46:46 GMT</pubDate>
            <atom:updated>2024-03-31T14:51:51.639Z</atom:updated>
            <content:encoded><![CDATA[<p>In modern software development, the concept of dependency injection (DI) has become increasingly important. Dependency injection promotes loose coupling and makes code more testable, maintainable, and scalable. In the Swift ecosystem, one powerful tool for managing dependencies is the Resolver framework. In this blog post, we’ll delve into how Resolver works behind the scenes and explore its key features.</p><h3>Understanding Dependency Injection:</h3><p>Before diving into Resolver, let’s briefly review dependency injection. Dependency injection is a design pattern where objects receive their dependencies from external sources rather than creating them internally. This allows for better separation of concerns and facilitates easier testing and maintenance.</p><h3>What is Resolver?</h3><p>Resolver is a lightweight dependency injection framework for Swift. It simplifies the management of dependencies by providing a convenient way to register, resolve, and manage dependencies throughout your codebase. With Resolver, you can easily inject dependencies into your classes, structs, and SwiftUI views.</p><h3>How Resolver Works Behind the Scenes:</h3><p>At its core, Resolver operates on a simple principle: <strong>registration</strong> and <strong>resolution</strong>. Here’s how Resolver works behind the scenes:</p><h4>Registration:</h4><p>In Resolver, you register your dependencies using the Resolver.register method. Dependencies can be registered as concrete types or protocols.</p><pre>Resolver.register { MyServiceImplementation() as MyService }</pre><p><strong>Resolution:</strong></p><p>Once dependencies are registered, you can resolve them wherever they are needed in your code. Resolver provides various methods for resolving dependencies, including property injection, constructor injection, and manual resolution.</p><pre>class MyViewModel: ObservableObject {<br>    @Injected var myService: MyService<br>}</pre><p><strong>Automatic Injection:</strong></p><p>Resolver supports automatic injection, where dependencies are automatically injected into properties marked with @Injected. This reduces boilerplate code and simplifies the dependency injection process.</p><pre>class MyViewModel: ObservableObject {<br>    @Injected var myService: MyService<br>}</pre><p><strong>Scopes:</strong></p><p>Resolver allows you to define scopes for dependencies, such as singleton, graph, and shared. Scopes determine how instances of dependencies are created and managed, providing flexibility and control over the lifecycle of objects.</p><pre>Resolver.register { MyServiceImplementation() as MyService }<br>        .scope(.singleton)</pre><h3><strong>Pros of Using Resolver:</strong></h3><p>Resolver offers several advantages for managing dependencies in Swift applications, making it a valuable tool for developers. Let’s explore some of the key benefits:</p><p><strong>Promotes Modularity and Separation of Concerns:</strong></p><p>Resolver encourages the separation of concerns by decoupling components and their dependencies. By explicitly defining dependencies and injecting them into components, Resolver helps create modular, loosely-coupled code that is easier to understand, maintain, and extend. This modularity facilitates code reuse and promotes cleaner architecture design.</p><p><strong>Improves Testability:</strong></p><p>Dependency injection is a fundamental principle of test-driven development (TDD) and promotes writing testable code. Resolver makes it easy to replace real dependencies with mock objects or stubs during testing, allowing developers to isolate components and write comprehensive unit tests. By injecting dependencies explicitly, tests become more focused, predictable, and maintainable, leading to higher test coverage and more robust codebases.</p><p><strong>Reduces Boilerplate Code:</strong></p><p>Resolver simplifies the process of dependency injection by automatically resolving dependencies and injecting them into components. With property injection, constructors, and automatic injection, developers can reduce boilerplate code and focus on writing business logic. Resolver’s concise syntax and powerful features streamline the dependency injection process, resulting in cleaner, more readable code.</p><p><strong>Facilitates Scalability and Flexibility:</strong></p><p>As applications evolve and grow in complexity, managing dependencies becomes increasingly challenging. Resolver provides a flexible and scalable solution for managing dependencies, allowing developers to register and resolve dependencies dynamically at runtime. By supporting different scopes (e.g., singleton, graph, shared), Resolver offers fine-grained control over the lifecycle of objects, ensuring efficient resource management and optimal performance.</p><p><strong>Encourages Best Practices:</strong></p><p>Resolver encourages best practices such as protocol-oriented programming (POP) and inversion of control (IoC). By defining dependencies as protocols and registering implementations dynamically, Resolver promotes abstraction and decoupling, making code more flexible, reusable, and extensible. Additionally, Resolver’s support for automatic injection and scoping helps enforce good architectural patterns and coding standards, leading to cleaner, more maintainable codebases.</p><p><strong>Community Support and Active Development:</strong></p><p>Resolver is an open-source project with a growing community of developers contributing to its development and improvement. With regular updates, bug fixes, and new features, Resolver continues to evolve and adapt to the changing needs of the Swift ecosystem. The active community and extensive documentation provide valuable resources and support for developers using Resolver in their projects.</p><p>Dependency injection is a powerful technique for managing dependencies and improving the overall design and testability of your Swift applications. The Resolver framework provides a convenient and efficient way to implement dependency injection in Swift projects. By understanding how Resolver works behind the scenes and leveraging its features, you can write cleaner, more modular, and more testable code.</p><p><a href="https://github.com/ArunK001/MediumArticles/blob/main/Resolver.swift">MediumArticles/Resolver.swift at main · ArunK001/MediumArticles</a></p><p>Resolver has been deprecated as of 2023 and now replaced with Factory 2.0.</p><p>The main reason for covering this is to start with DI concepts. In next post I’will cover Factory 2.0.</p><h4>Reference:</h4><p>Resolver GitHub Repository: <a href="https://github.com/hmlongco/Resolver">https://github.com/hmlongco/Resolver</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e070095dd96e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Update your List/Collection/CustomViews with UIContentConfiguration]]></title>
            <link>https://medium.com/@arunk.pattanayak/update-your-list-collection-customviews-with-uicontentconfiguration-61f10152681a?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/61f10152681a</guid>
            <category><![CDATA[uicollectionview]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[uitableview]]></category>
            <category><![CDATA[uistackview]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Thu, 23 Jun 2022 12:29:42 GMT</pubDate>
            <atom:updated>2022-06-23T12:29:42.537Z</atom:updated>
            <content:encoded><![CDATA[<p>I was browsing through the WWDC video and noticed a new name i.e. <strong>UIContentConfiguration</strong>. Interestingly this was introduced in iOS 14 and I didn’t even know it was there. So, If you are in the place as I was this is going to help you.</p><p>From Apple Docs:</p><blockquote>This protocol provides a blueprint for a content configuration object, which encompasses default styling and content for a content view. The content configuration encapsulates all of the supported properties and behaviors for content view customization. You use the configuration to create the content view.</blockquote><p>Sounds like we are already able to do all these without UIContentConfiguration, isn’t it?</p><p>To clarify let’s discuss, how UIContentConfiguration is going to help.</p><ol><li>when you’re building a completely custom view hierarchy inside your cells, you can still use the system configurations to help. Because configurations are so lightweight, you can use them as a source of default values for things like fonts, colors, and margins that you copy over to your custom views, even if you never apply the configuration directly itself.</li><li>We can reuse the same content view between UITableView, UICollectionView, and UIStackView.</li><li>Supports diffable data sources and traditional data sources.</li><li>UICollectionView cell registration methods, forgoing classic APIs such as identifiers and UICollectionViewDatasource supports UIContentConfiguration (e.g: UICollectionViewCompositionalLayout.list(using: listConfiguration)).</li><li>For list types i.e. UITableView and UICollectionView we can use UIListContentConfiguration.</li><li>Managing different UI states like selected, and highlighted becomes easier with UIContentConfiguration.</li></ol><p><strong>Exploring UIContentConfiguration:</strong></p><p>There are two parts to this</p><ol><li><strong>UIContentConfiguration:</strong> an object that produces a content view.</li><li><strong>UIContentView</strong>: a view with a settable property that is a content configuration.</li></ol><p><strong>UIContentConfiguration</strong> and <strong>UIContentView</strong> both are protocols.</p><p><strong>UIContentConfiguration </strong>has two methods:</p><blockquote>func<em> makeContentView() -&gt; UIView &amp; UIContentView()</em></blockquote><blockquote>func updated(for state: UIConfigurationState) -&gt; Car</blockquote><p><strong>UIContentView</strong> has one variable:</p><blockquote><em>var configuration: UIContentConfiguration</em></blockquote><p>Let’s start implementing UIContentConfiguration:</p><figure><img alt="Implementation for UIContentConfiguration" src="https://cdn-images-1.medium.com/max/1024/1*qqIpvbpf-clMapxTXscWuQ.png" /></figure><p>I have taken the Car structure, which shows the name and color of the car. When use selects any vehicle, we want to change the states of the cell.</p><p>Let implement <strong>UIContentView</strong>:</p><figure><img alt="UIContentView Implementation" src="https://cdn-images-1.medium.com/max/1024/1*rQkJw6Vsf5_YkQ1vRhU-WQ.png" /></figure><p>We have taken a custom content view, which is a subclass of UIView, and implemented UIContentView.</p><p>This class depends on the Car class to get values and configurations. Whenever we send a new configuration this class updates its UI configuration based on new changes.</p><p>Now, coming to our view controller:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LSLGECjC1k5USOizYxfXkQ.png" /></figure><p>There isn’t much, we have created and configured UITableView, UITableViewDiffableDataSource, and NSDiffableDataSouceSnapshot.</p><p>This is what our custom cell looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/976/1*EhcX3vJmRX1NTjd3xvjSYQ.png" /></figure><p>In our custom cell, we need to override the updateConfiguration(using:) method to start updating your UI whenever there is a new configuration added.</p><p>I hope this helps you to start updating your code with UIContentConfiguration.</p><p>References:</p><ul><li><a href="https://www.biteinteractive.com/cell-content-configuration-in-ios-14/">The Developer&#39;s Guide to Cell Content Configuration in iOS 14 - BiTE Interactive</a></li><li><a href="https://developer.apple.com/documentation/uikit/uicontentconfiguration">Apple Developer Documentation</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=61f10152681a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Let’s learn Dependency Injection in Swift]]></title>
            <link>https://medium.com/@arunk.pattanayak/lets-learn-dependency-injection-with-swift-46634ce61271?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/46634ce61271</guid>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 19 Jun 2022 10:26:07 GMT</pubDate>
            <atom:updated>2022-06-19T10:58:49.678Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Dependency Injection" src="https://cdn-images-1.medium.com/max/960/1*qjMRZKt5VEim6j61L2HPqQ.jpeg" /></figure><p>“Dependency Injection” Sounds fancy, Isn’t it?</p><p>When I heard about it, thought it was a tricky concept and could be challenging to learn. So, in this article, we will see if it’s challenging to learn.</p><p>There are three ways we can use dependency injection in swift:</p><ol><li>Initialiser injection</li><li>Method injection</li><li>Property injection</li></ol><p>Now that we know the types, I believe some people already have realized that they know these terms but without realizing it’s a form of “Injection”.</p><p>Before learning about dependency injection, let’s see what kind of problems it solves.</p><p>Let’s see this code:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/1*BnVdtqtd1gtrGrkFEtejEg.png" /></figure><p>What are we doing with the above code</p><ul><li>We have defined two modules <strong>BaseNetworkModule </strong>to handle network calls, and <strong>BaseImageDownloder </strong>to download images.</li><li><strong>MyViewController </strong>is using the base classes to use the above functionality.</li></ul><p>Now, let’s say we need to replace <strong>BaseNetworkModule</strong> and <strong>BaseImageDownloder</strong> with something else.</p><ul><li>Now that our code is tightly coupled with these modules it will be difficult to make modifications if needed.</li><li>If we need to test MyViewController with mock modules, we will not be able to do so.</li></ul><p>Now that we know the problems, let’s explore how <strong>Dependency Injection </strong>will help us solve these concerns.</p><ol><li><strong>Initialiser Injection</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VMdbVTjArZ2s4LYJCeX4Gw.png" /></figure><p>In the above code instead of initializing the networkModule and imageDownloder module within the class, we are assigning those variables using its init(networkModule: imageDownloder:) method.</p><p>By doing so we are not dependent on MyViewContoller to initialize them and this gives us more control over what object to pass.</p><p>Let’s consider this unit test case</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CzOAUX0OVqQKpXXkeAKstw.png" /></figure><p>We have easily replaced our networkModule and imageDownloder with mock models.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MIt-wrsJpyKqpUzfB0vPxA.png" /></figure><p>Now it’s more flexible to change dependent objects as per requirement. In the above code snippet, we have replaced ImageDowloader with LocalImageLoader class.</p><p>If we are using an initializer to inject dependencies that are called <strong>Initialiser Dependency Injection</strong>.</p><p>2. <strong>Method Injection</strong></p><p>This is similar to using Initialiser Dependency Injection, but instead of using an initializer, we will have methods to inject dependencies.</p><p>Let’s how does it look like in code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TvIxxFtqJBxPkqLaUNzanQ.png" /></figure><p>You can see, that we have a new method where we have two parameters <strong>networkModule </strong>and <strong>imageDownloder, </strong>and we are assigning these values to our dependencies.</p><p>This may come in handy when we are using storyboard or xib files.</p><p>The problem with this type of dependency injection is, that it’s easy to forget to implement those methods and if we are not mindful, we can change dependency unknowingly.</p><p><strong>3. Property Injection</strong></p><p>Dependencies can also be implemented using internal or public properties.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*dKJrNL6ol8oM-Psw78jPlA.png" /></figure><p>This gives us the flexibility of modifying dependencies as required, but this is vulnerable to unintended modification.</p><blockquote><strong>So, now the big question “What’s dependency injection?”</strong></blockquote><blockquote>This is injecting dependencies into an object instead of the object creating its dependencies.</blockquote><p>Now I hope Dependency Injection doesn’t sound so complicated anymore.</p><p>There is a third-party powerful light-weight dependency injection library:</p><p><a href="https://github.com/hmlongco/Resolver">GitHub - hmlongco/Resolver: Swift Ultralight Dependency Injection / Service Locator framework</a></p><p>As next part of this dependency injection section, I’ll be covering the above library. If you want to learn the above library, bookmark this section for an update.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=46634ce61271" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iOS Interview Questions on Application States]]></title>
            <link>https://medium.com/@arunk.pattanayak/interview-questions-on-ios-application-states-ba99ead79ce6?source=rss-ca7e77c52ed3------2</link>
            <guid isPermaLink="false">https://medium.com/p/ba99ead79ce6</guid>
            <category><![CDATA[ios-interview-question]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[objective-c]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Arun pattanayak]]></dc:creator>
            <pubDate>Sun, 03 Oct 2021 11:50:45 GMT</pubDate>
            <atom:updated>2021-10-05T05:31:48.050Z</atom:updated>
            <content:encoded><![CDATA[<p>While going to through some of the screening round for iOS developer position I have asked/faced these questions, which are extremely basic but sometime it can be a decision maker if you get hired or not.</p><p>Candidates are asked to answer these question to check their knowledge in application states and if needed how they can utilise this knowledge.</p><p><strong>What are the iOS application states?</strong><br> There are 5 application states in iOS application.</p><p>· <strong>Not-Running</strong>: The application is not running.</p><p>·<strong> Inactive</strong>: The application is in foreground but not receiving events.</p><p>· <strong>Active</strong>: The application is in foreground and receiving events.</p><p>· <strong>Background</strong>: The application is running on background and executing codes.</p><p>·<strong> Suspended</strong>: The application is in background and not executing codes. Usually, it happens after 5 seconds application stays in background state, but this can be extended.</p><p><strong>What is Not-Running state?</strong></p><p>When application is not launched or system terminates/purges/shuts it down, is called Not-Running state.</p><p><strong>What are Inactive and Active state?</strong></p><p><strong>Inactive: </strong>The app is running in the foreground but is currently not receiving events. (It may be executing other code though.) An app usually stays in this state only briefly as it transitions to a different state. Application can go to inactive state upon receiving calls/sms. This can also happen while moving to different state. During this state we can not interact with UI. This is represented with <a href="https://developer.apple.com/documentation/uikit/uiapplication/state">UIApplication.State.inactive</a>.</p><p><strong>Active: </strong>This is the normal state of the application where application stays in foreground and receives events. We can only go to this state from <strong>Inactive State</strong>. This is represented with <a href="https://developer.apple.com/documentation/uikit/uiapplication/state">UIApplication.State.active</a>.</p><p><strong>What is an Event?</strong></p><p>Most events sent to an iOS application are encapsulated in an event object — an instance of the UIEvent class. Events in iOS represent fingers touching (UITouch) views of an application or the user shaking the device. Distributing and handling events is the job of responder objects, which are instances of the UIResponder class. The UIApplication, UIViewController, UIWindow, and UIView classes (and your own RTAppDelegate) all inherit from UIResponder.(<a href="https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/EventHandlingiPhone.html">Apple Doc</a>)</p><p><strong>Explain state transitions?</strong></p><p>Application can transition in following ways.<br>Not-running -&gt; Inactive -&gt; Active -&gt; Inactive -&gt; Background -&gt; Inactive -&gt; Active</p><p><strong>How can you send application to Background state?</strong></p><p>Application can be send to background state by<br>1. Clicking screen lock button<br>2. Entering into multi tasking screen<br>3. Tapping on home button/ by swiping up.<br>4. System presents alert (e.g: low battery alert)</p><p><strong>How do you check application states?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/738/1*v7TXtRMCmRiTxEvc_R5KJw.png" /></figure><p><strong>Explain suspended state?</strong></p><p>Application enters in this state from Background State (Inactive gets invoked in between) by OS. During this state application stays in memory but does not execute any code. As the application does not do anything during this state, battery life does not get impacted. Application will not get notified while entering to suspended state.</p><p>If any application needs memory and system is low on memory, OS may decide to terminate the application from suspended state.</p><p><strong>How long does application stays in Background state before getting suspended?</strong></p><p>Usually application stays in background mode for about <strong><em>5 seconds</em></strong> in general cases before going to suspended state, but we can request OS to extend time if required using capabilities. <br>There are processes which can run for infinite time in background.<br>- Apps that play audible content to the user while in the background, such as a music player app.<br>-Apps that keep users informed of their location at all times, such as a navigation app.</p><p>Also there are applications which come to background mode as required.<br>- Apps that support Voice over Internet Protocol (VoIP).<br>- Newsstand apps that need to download and process new content<br>- Apps that receive regular updates from external accessories</p><p><strong>How to know if application entered foreground or background state?</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0Sie4xzGLMoEGjzI9vBGuA.png" /></figure><p>Using notification we can know when application enters foreground or background modes.</p><p><strong>How do you request additional background time?</strong></p><p>Using <a href="https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio">beginBackgroundTaskWithExpirationHandler</a>, we can request additional time for background task.<br>Call this method when leaving a task unfinished might be detrimental to your app’s user experience. For example, call this method before writing data to a file to prevent the system from suspending your app while the operation is in progress.<br>Each call to this method must be balanced by a matching call to the <a href="https://developer.apple.com/documentation/uikit/uiapplication/1622970-endbackgroundtask">endBackgroundTask:</a> method. You can find remaining time by using <a href="https://developer.apple.com/documentation/uikit/uiapplication/1623029-backgroundtimeremaining">backgroundTimeRemaining</a>. If you don&#39;t call endBackgroundTask: for each task before time expires, the system kills the app.</p><p><strong>AppDelegate function that are related to application states?</strong></p><p>optional func applicationDidBecomeActive(_ application: UIApplication)</p><p>optional func applicationWillResignActive(_ application: UIApplication)</p><p>optional func applicationWillEnterForeground(_ application: UIApplication)</p><p>optional func applicationDidEnterBackground(_ application: UIApplication)</p><p>optional func applicationWillTerminate(_ application: UIApplication)</p><p><strong>What happens during launch of an application?</strong></p><p>User Taps on the icon -&gt; main() -&gt; @main -&gt; Load main UI file -&gt; Initialisation (willFinishLaunchingWithOptions)-&gt; Restore UI state -&gt; Finish Initialisation (didFinishLaunchingWithOptions) -&gt; Running</p><p><strong>What happens during background state?</strong></p><p>Did enter Background -&gt; Can run in background?</p><p>Yes -&gt; handle events (execute code) -&gt; Sleep/Suspend</p><p>No -&gt; Suspend -&gt; If there is a memory warning -&gt; Terminate</p><p><strong>How to enable background mode and implement it?</strong></p><p>Go to project settings.</p><p>Click on <strong>signing and capabilities </strong>-&gt;<strong> +Capabilities -&gt; Background Modes</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/832/1*HE7CDcWsduwOcEFySWaGSA.png" /></figure><p>Now you can see the available background modes. Check the ones you require.</p><p>Go to info.plist file and add <strong>Permitted background task scheduler identifiers </strong>and add your identifiers.</p><p><strong>Import BackgroundTask </strong>to your class and you can use BGTaskScheduler to register you background operation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M2HRPdiy5E0So93olcTPYg.png" /><figcaption><a href="https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/using_background_tasks_to_update_your_app">Please refer apple document for detail implementation</a></figcaption></figure><p><strong>How to make API calls in backgound?</strong></p><p>In order to implement background fetch, there are three things you must do:</p><ul><li>Check the box <strong>Background fetch</strong> in the <strong>Background Modes</strong> of your app’s <strong>Capabilities</strong>.</li><li>Use setMinimumBackgroundFetchInterval(_:) to set a time interval appropriate for your app.</li><li>Implement application(_:performFetchWithCompletionHandler:) in your app delegate to handle the background fetch.</li></ul><p><strong>What are the differences in iOS 13 with application life cycle?</strong></p><p>In iOS 13 application life cycle handle differently with UIWindowSceneDelegate.</p><pre>- (void)sceneDidBecomeActive:(UIScene *)scene {<br>}<br>- (void)sceneWillResignActive:(UIScene *)scene {<br>}</pre><p>We can use these method to handle Inactive and Active states.</p><p>We can control this behaviour by <strong>Application Scene Manifest </strong>in application’s info.plist file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K9wpnCepk6hkZ13030wj6Q.png" /></figure><p>References:<br><a href="https://www.dummies.com/web-design-development/mobile-apps/handling-events-while-your-ios-application-is-executing/">https://www.dummies.com/web-design-development/mobile-apps/handling-events-while-your-ios-application-is-executing/</a></p><p><a href="https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/EventHandlingiPhone.html">https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/EventHandlingiPhone.html</a></p><p><a href="https://hackernoon.com/application-life-cycle-in-ios-12b6ba6af78b">https://hackernoon.com/application-life-cycle-in-ios-12b6ba6af78b</a></p><p><a href="https://www.iosiqa.com/2019/05/application-states.html">https://www.iosiqa.com/2019/05/application-states.html</a></p><p><a href="https://medium.com/@chinthaka01/the-execution-states-of-an-ios-application-84e117132e27">https://medium.com/@chinthaka01/the-execution-states-of-an-ios-application-84e117132e27</a></p><p><a href="https://www.raywenderlich.com/5817-background-modes-tutorial-getting-started">https://www.raywenderlich.com/5817-background-modes-tutorial-getting-started</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ba99ead79ce6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>