//
//  ExtendedPostModelTests.swift
//  SwiftyPress ModelTests
//
//  Created by Basem Emara on 2019-05-11.
//  Copyright © 2019 Zamzam Inc. All rights reserved.
//

#if !os(watchOS)
import XCTest
import SwiftyPress
import ZamzamCore

final class SeedPayloadModelTests: XCTestCase {
    
    func testDecoding() throws {
        let model = try JSONDecoder.default.decode(SeedPayload.self, fromJSON: #fileID)
            
        XCTAssertEqual(model.posts[0].id, 41276)
        XCTAssertEqual(model.posts[0].title, "Swifty Protocol-Oriented Dependency Injection")
        XCTAssertEqual(model.posts[0].slug, "swift-protocol-oriented-dependency-injection")
        XCTAssertEqual(model.posts[0].type, "post")
        XCTAssertEqual(model.posts[0].excerpt, "The key to dependency injection is protocols. From there sprouts many variations, flavours, and techniques. Although this is yet another dependency injection™ blog post, I would like to share a pure Swift, battle-tested DI implementation with no outside dependencies or magic. It combines protocol extension and type erasure to give you a solid, flexible dependency injection.")
        XCTAssertEqual(model.posts[0].content, "<p>The key to dependency injection is protocols &#8211; from there sprouts many variations, flavours, and techniques. Although this is <em>yet another dependency injection™</em> blog post, I would like to share a pure Swift, battle-tested DI implementation with no outside dependencies or magic. It combines protocol extension and type erasure to give you a solid, flexible dependency injection that works great with unit test and even frameworks.</p>\n<h2>The Dependency Container</h2>\n<p>The first thing we must do is come up with a container that will house all our dependencies. This will be referenced later from consumers to grab dependencies they want.</p>\n<pre class=\"lang:swift decode:true\">protocol Dependency {\r\n    func resolveService() -&gt; HTTPServiceType\r\n    \r\n    func resolveWorker() -&gt; AuthenticationWorkerType\r\n    func resolveService() -&gt; AuthenticationService\r\n    \r\n    func resolveWorker() -&gt; UsersWorkerType\r\n    func resolveStore() -&gt; UsersStore\r\n    func resolveCache() -&gt; UsersStore\r\n}</pre>\n<p>Now that we got the blueprint to our container and its dependency protocols, let&#8217;s implement the concrete dependency instances:</p>\n<pre class=\"lang:swift decode:true \">class CoreDependency: Dependency {\r\n    \r\n    func resolveService() -&gt; HTTPServiceType {\r\n        return HTTPService()\r\n    }\r\n    \r\n    func resolveWorker() -&gt; AuthenticationWorkerType {\r\n        return AuthenticationWorker(\r\n            service: resolveService()\r\n        )\r\n    }\r\n    \r\n    func resolveService() -&gt; AuthenticationService {\r\n        return AuthenticationNetworkService(\r\n            httpService: resolveService()\r\n        )\r\n    }\r\n    \r\n    func resolveWorker() -&gt; UsersWorkerType {\r\n        return UsersWorker(\r\n            store: resolveStore(),\r\n            cacheStore: resolveCache()\r\n        )\r\n    }\r\n    \r\n    func resolveStore() -&gt; UsersStore {\r\n        return UsersNetworkStore(\r\n            httpService: resolveService()\r\n        )\r\n    }\r\n    \r\n    func resolveCache() -&gt; UsersStore {\r\n        return UsersCoreDataStore() //..or use UsersRealmStore\r\n    }\r\n}</pre>\n<p>This is where the main meat of the dependency injection occurs. The dependency objects implement the protocols so the concrete types are hidden from the caller. This way, the dependency types can be swapped out underneath without affecting the rest of the application.</p>\n<p>Also notice that some dependencies reference other dependencies within the container. The implications of this is powerful because you are building a dependency graph and any part of it can be changed which will cascade.</p>\n<h2>The Dependencies</h2>\n<p>There are no singleton dependencies in our container because we always want to deal with immutable objects, otherwise state management will bite you later. Instead, its a factory serving fresh instances. The dependencies are <code>structs</code> that implement the protocols.</p>\n<p>Here&#8217;s an example of some of the dependencies:</p>\n<pre class=\"lang:swift decode:true\">protocol HTTPServiceType {...}\r\n\r\nstruct HTTPService: HTTPServiceType {\r\n    ...\r\n}\r\n\r\n///\r\n\r\nprotocol AuthenticationService {...}\r\n\r\nstruct AuthenticationNetworkService: AuthenticationService {\r\n    private let httpService: HTTPServiceType\r\n    \r\n    init(httpService: HTTPServiceType) {\r\n        self.httpService = httpService\r\n    }\r\n}\r\n\r\n///\r\n\r\nprotocol AuthenticationWorkerType {...}\r\n\r\nstruct AuthenticationWorker: AuthenticationWorkerType {\r\n    private let service: AuthenticationService\r\n    \r\n    init(service: AuthenticationService) {\r\n        self.service = service\r\n    }\r\n}</pre>\n<p>We&#8217;re using classic constructor injection to feed the dependencies in.</p>\n<p>The <code>HTTPService</code> dependency handles the raw network requests/responses and where you would <code>import Alamofire</code> for example. Never leak your 3rd-party dependencies to the rest of the app! Instead, encapsulate it under one of your custom dependencies. That&#8217;s what <code>HTTPService</code> will do for <code>Alamofire</code>.</p>\n<p>Now based on our dependency container, <code>HTTPService</code> gets injected into <code>AuthenticationNetworkService</code> so it can make the REST API endpoint calls. It doesn&#8217;t know that it&#8217;s using <code>Alamofire</code> underneath and can be completely swapped out for another network library or <code>URLSession</code>.</p>\n<p>From here, <code>AuthenticationNetworkService</code> gets injected into <code>AuthenticationWorker</code> that gets referenced by the rest of the app. This way, the REST API server or endpoints can be completely swapped out and your app wouldn&#8217;t have to know. It would still call the <code>AuthenticationWorker</code> API&#8217;s.</p>\n<h2>The Injection</h2>\n<p>It&#8217;s now time to start using our dependency container. We will use a protocol extension to pass in the dependency container so the caller can start resolving the dependency types it wants.</p>\n<p>We need a singleton to hold a reference to the dependency container. So although we couldn&#8217;t get away from singletons altogether, the dependency container is a factory and still serving immutable instances.</p>\n<pre class=\"lang:swift decode:true\">/// The singleton dependency container reference\r\n/// which can be reassigned to another container\r\nstruct DependencyInjector {\r\n    static var dependencies: Dependency = CoreDependency()\r\n    private init() { }\r\n}\r\n\r\n/// Attach to any type for exposing the dependency container\r\nprotocol HasDependencies {\r\n    var dependencies: Dependency { get }\r\n}\r\n\r\nextension HasDependencies {\r\n    \r\n    /// Container for dependency instance factories\r\n    var dependencies: Dependency {\r\n        return DependencyInjector.dependencies\r\n    }\r\n}</pre>\n<p>The <code>DependencyInjector</code> should be configured early on in the app lifecycle. That way, your frameworks can have its own dependency container, such as <code>CoreDependency</code>, and consumers can override any of the dependencies it desires. This works great for consumers who want to use a different <code>UserDefaults</code> app group or Keychain access group.</p>\n<p>We do this in the <code>willFinishLaunchingWithOptions</code>:</p>\n<pre class=\"lang:swift decode:true\">extension UIApplicationDelegate {\r\n    \r\n    func configure(dependency: Dependency) {\r\n        DependencyInjector.dependencies = dependency\r\n    }\r\n}\r\n\r\n///\r\n\r\nclass AppDependency: CoreDependency {\r\n    \r\n    override func resolveCache() -&gt; UsersStore {\r\n        return UsersRealmStore()\r\n    }\r\n}\r\n\r\n///\r\n\r\n@UIApplicationMain\r\nclass AppDelegate: UIResponder, UIApplicationDelegate {\r\n\r\n    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -&gt; Bool {\r\n        configure(dependency: AppDependency())\r\n        return true\r\n    }\r\n}</pre>\n<p>Finally, the protocol extension for <code>HasDependencies</code> is used to provide the dependency container to whoever wants it:</p>\n<pre class=\"lang:swift decode:true\">class ViewController: UIViewController, HasDependencies {\r\n\r\n    private lazy var authenticationWorker: AuthenticationWorkerType = dependencies.resolveWorker()\r\n    \r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n        \r\n        authenticationWorker.login(with: \"whatever\") {\r\n            //completed\r\n        }\r\n    }\r\n}\r\n</pre>\n<h2>The Unit Test</h2>\n<p>Not only does this dependency injection work great for frameworks, but of course works great for unit tests. It can be configured on a global and scoped level too!</p>\n<p>For the global level of your unit tests, you can create a <code>TestDependency</code> that subclasses <code>CoreDependency</code>:</p>\n<pre class=\"lang:swift decode:true \">class TestDependency: CoreDependency {\r\n    \r\n    // Override with mocks, spy, or whatever\r\n    \r\n    override func resolveService() -&gt; AuthenticationService {\r\n        return AuthenticationTestService()\r\n    }\r\n}\r\n\r\nstruct AuthenticationTestService: AuthenticationService {\r\n    var isAuthorized: Bool {\r\n        return true\r\n    }\r\n    \r\n    func signup(with request: Any, completion: @escaping () -&gt; Void) {\r\n        print(\"AuthenticationTestService.signup\")\r\n    }\r\n    \r\n    func login(with request: Any, completion: @escaping () -&gt; Void) {\r\n        print(\"AuthenticationTestService.login\")\r\n    }\r\n    \r\n    func logout() {\r\n        \r\n    }\r\n}</pre>\n<p>You set this in your <code>setUp()</code> function of your test case:</p>\n<pre class=\"lang:swift decode:true \">class MyCore_Tests: XCTestCase, HasDependencies {\r\n    \r\n    override func setUp() {\r\n        super.setUp()\r\n        \r\n        // Use test dependency or even a scoped one to the test!\r\n        DependencyInjector.dependencies = TestDependency()\r\n    }\r\n}</pre>\n<p>What&#8217;s even more powerful is you can create a scoped dependency container for a specific test case, see <code>ScopedDependency</code>:</p>\n<pre class=\"lang:swift decode:true \">class MyCore_Tests: XCTestCase, HasDependencies {\r\n    \r\n    private lazy var authenticationWorker: AuthenticationWorkerType = dependencies.resolveWorker()\r\n    private lazy var usersWorker: UsersWorkerType = dependencies.resolveWorker()\r\n    \r\n    override func setUp() {\r\n        super.setUp()\r\n        \r\n        // Use test dependency or even a scoped one to the test!\r\n        DependencyInjector.dependencies = ScopedDependency()\r\n    }\r\n    \r\n    override func tearDown() {\r\n        super.tearDown()\r\n        \r\n        // Set dependencies back to what it was\r\n        DependencyInjector.dependencies = TestDependency()\r\n    }\r\n    \r\n    private class ScopedDependency: TestDependency {\r\n        \r\n        override func resolveService() -&gt; HTTPServiceType {\r\n            return MockHTTPService()\r\n        }\r\n    }\r\n    \r\n    private struct MockHTTPService: HTTPServiceType {\r\n        \r\n        public func post(url: String, parameters: [String: Any], headers: [String: String]?, completion: @escaping () -&gt; Void) {\r\n            //Blah, blah\r\n            print(\"MockHTTPService.post\")\r\n        }\r\n        \r\n        public func get(url: String, parameters: [String: Any], headers: [String: String]?, completion: @escaping () -&gt; Void) {\r\n            //Blah, blah\r\n            print(\"MockHTTPService.get\")\r\n        }\r\n    }\r\n}\r\n\r\nextension MyCore_Tests {\r\n    \r\n    func testAuthenticationExample() {\r\n        authenticationWorker.signup(with: \"whatever\") {\r\n            XCTAssertTrue(true)\r\n        }\r\n    }\r\n    \r\n    func testUserExample() {\r\n        usersWorker.fetchCurrent {\r\n            XCTAssertTrue(true)\r\n        }\r\n    }\r\n    \r\n}</pre>\n<h2>Conclusion</h2>\n<p>The combination of a dependency container, a protocol extension to expose it, and immutable dependencies give you a pure Swift DI that works well with frameworks and unit tests. See this <a href=\"https://github.com/iosmentor-io/Pure-Swift-DI\" target=\"_blank\" rel=\"noopener noreferrer\">working example</a> to try it out.</p>\n<p><em><strong>HAPPY CODING!!</strong></em></p>\n<h2>More Reading</h2>\n<ul>\n<li><a href=\"https://www.swiftbysundell.com/posts/dependency-injection-using-factories-in-swift\" target=\"_blank\" rel=\"noopener noreferrer\">Dependency injection using factories in Swift</a></li>\n<li><a href=\"http://www.danielhall.io/a-swift-y-approach-to-dependency-injection\" target=\"_blank\" rel=\"noopener noreferrer\">A Swift-y Approach to Dependency Injection</a></li>\n<li><a href=\"http://merowing.info/2017/04/using-protocol-compositon-for-dependency-injection/\" target=\"_blank\" rel=\"noopener noreferrer\">Using protocol compositon for dependency injection</a></li>\n</ul>\n")
        XCTAssertEqual(model.posts[0].commentCount, 10)
        XCTAssertEqual(model.posts[0].link, "https://staging1.basememara.com/swift-protocol-oriented-dependency-injection/")
        XCTAssertEqual(model.posts[0].authorID, 2)
        XCTAssertEqual(model.posts[0].mediaID, 41287)
        XCTAssertEqual(model.posts[0].meta["_series_part"], "2")
        XCTAssertEqual(model.posts[0].terms, [80, 62, 50, 55])
        XCTAssertEqual(model.posts[0].createdAt, DateFormatter.iso8601.date(from: "2018-04-11T21:34:11"))
        XCTAssertEqual(model.posts[0].modifiedAt, DateFormatter.iso8601.date(from: "2019-05-13T11:44:11"))
        
        XCTAssertEqual(model.posts[1].id, 41373)
        XCTAssertEqual(model.posts[1].title, "Protocol-Oriented Themes for iOS Apps")
        XCTAssertEqual(model.posts[1].slug, "protocol-oriented-themes-for-ios-apps")
        XCTAssertEqual(model.posts[1].type, "post")
        XCTAssertEqual(model.posts[1].excerpt, "Themes are usually downplayed as an after-thought instead of being an integral part of the development process. How many times have you inherited a codebase where the design team wants to tweak it, or business wants you to clone the app with a whole different theme. In this post, I'm going to show you the native way of theming an iOS app as intended by Apple that is often overlooked.")
        XCTAssertEqual(model.posts[1].content, "<p>Themes are usually downplayed as an after-thought instead of being an integral part of the development process. How many times have you inherited a codebase where the design team wants to tweak it, or business wants you to clone the app with a whole different theme. Then you look at the code&#8230;</p>\n<p><em>Color and font changes are sprinkled all over storyboards and views!!</em></p>\n<p>Ok you wish they had a bit more foresight when they were making the app the first time, but then they wouldn&#8217;t have reached out to you now right? In this post, I&#8217;m going to show you the native way of theming an iOS app as intended by Apple. It&#8217;s often overlooked, well because&#8230;</p>\n<h2>UIAppearance Sucks</h2>\n<p>I&#8217;m sure most of you have toyed with <a href=\"https://developer.apple.com/documentation/uikit/uiappearance\" target=\"_blank\" rel=\"noopener noreferrer\"><em>UIAppearance</em></a> and quickly gave up on it because of its limitations, especially if you&#8217;ve been spoiled with CSS stylesheets for web development or theme resources for Android apps. Apple&#8217;s way of theming is quite awkward, but it&#8217;s what we got and I urge you not to roll out your own or use yet another dependency.</p>\n<p>In a nutshell, <code>UIAppearance</code> allows you to style <em>UIKit</em> controls globally using a proxy, or a class that stands in as a placeholder which applies itself to the control when it gets added to the window hierarchy. For example, you can globally change labels to red text like this:</p>\n<pre class=\"lang:swift decode:true\">UILabel.appearance().textColor = .red</pre>\n<p>It&#8217;s like a static function that gets applied to all future instances. Though, it&#8217;s like a sledge hammer for a nail because it applies to <em>ALL</em> labels in the app, even in places you didn&#8217;t even know labels existed! This is where most people give up on <code>UIAppearance</code>.</p>\n<h2>UIAppearance Sucks&#8230; Well Kinda&#8230;</h2>\n<p>Apple&#8217;s answer to styles and themes is for you to subclass your <em>UIKit</em> controls and use <code>UIAppearance</code> on those custom controls like this:</p>\n<pre class=\"lang:swift decode:true\">AppLabel.appearance().textColor = .red</pre>\n<p>That&#8217;s the awkward part, Apple wants you to use object-oriented programming to theme your apps. I don&#8217;t think they understood that a CSS-<em>class</em> isn&#8217;t really a <em>class</em> 🙄.</p>\n<p>You can take it one step further though:</p>\n<pre class=\"lang:swift decode:true\">AppLabel.appearance(whenContainedInInstancesOf: [MyCustomView.self]).textColor = .red</pre>\n<p>This will change the appearance of all <em>AppLabel&#8217;s</em> only contained in <em>MyCustomView&#8217;s</em>. So that&#8217;s your other option &#8211; to change your UI hierarchy to accommodate styling 🤦\u{200d}♂️. Why couldn&#8217;t they just add a new space-delimited string property called styles that gets realized by its children??</p>\n<p>Anyways, surprisingly things become really powerful when you start feeding <code>whenContainedInInstancesOf</code> an array of classes, which defines the hierarchy chain of the control. The specificity let&#8217;s you zero in on controls.</p>\n<pre class=\"lang:swift decode:true\">AppLabel.appearance(whenContainedInInstancesOf: [MyViewController.self]).textColor = .blue\nAppLabel.appearance(whenContainedInInstancesOf: [MyCustomView.self]).textColor = .red\nAppLabel.appearance(whenContainedInInstancesOf: [MyCustomView.self, MyViewController.self]).textColor = .yellow</pre>\n<p>Another Apple awkwardness is that the outer most parent wins (unlike CSS and the rest of the world). So in the above example, <code>[MyViewController.self]</code> wins over <code>[MyCustomView.self]</code>, even though <code>MyCustomView</code> is the closest parent.</p>\n<p>The way it works is the selector starts from top-to-bottom of the hierarchy, which means when it first hits <code>MyViewController</code> it stops. The label will be blue, not red, even if it&#8217;s contained in a <code>MyCustomView</code>. Fortunately though, the longer your array is (the more specific it is), the higher priority it is. In this case, the labels in <code>MyCustomView</code> will be yellow if it is on the <code>MyViewController</code> screen.</p>\n<p>Once you understand and toy around with these quirks, it becomes a full-fledged styling framework!</p>\n<h2>Styleable Controls</h2>\n<p>First thing we must do is subclass all the controls we want to style in our app. Not the best use of object-oriented programming, but it&#8217;s native theming (<em>see rant above</em>). Here&#8217;s what I got:</p>\n<p><em>AppLabel.swift:</em></p>\n<pre class=\"lang:swift decode:true\">class AppLabel: UILabel {\n    \n}\n\nclass AppHeadline: UILabel {\n    \n}\n\nclass AppSubhead: UILabel {\n    \n}\n\nclass AppFootnote: UILabel {\n    \n}</pre>\n<p><em>AppButton.swift:</em></p>\n<pre class=\"lang:swift decode:true\">class AppButton: UIButton {\n    \n}\n\nclass AppDangerButton: UIButton {\n    \n}</pre>\n<p><em>AppSwitch.swift:</em></p>\n<pre class=\"lang:swift decode:true \">class AppSwitch: UISwitch {\n    \n}</pre>\n<p><em>AppView.swift:</em></p>\n<pre class=\"lang:swift decode:true\">class AppView: UIView {\n    \n}\n\nclass AppSeparator: UIView {\n    \n}</pre>\n<p>In our storyboard, we will now use these custom classes:</p>\n<p><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/09/UIKit-Xcode-Custom-Class-500x281.png\" alt=\"\" width=\"500\" height=\"281\" class=\"aligncenter size-medium wp-image-41382\" srcset=\"https://staging1.basememara.com/wp-content/uploads/2018/09/UIKit-Xcode-Custom-Class-500x281.png 500w, https://staging1.basememara.com/wp-content/uploads/2018/09/UIKit-Xcode-Custom-Class-768x432.png 768w, https://staging1.basememara.com/wp-content/uploads/2018/09/UIKit-Xcode-Custom-Class.png 854w\" sizes=\"(max-width: 500px) 100vw, 500px\" /></p>\n<p>However, we will not change colors in the storyboard.. leave them all on the defaults! Nor will we style and theme the custom controls in the <code>awakeFromNib()</code> event!</p>\n<p>Instead we will style our controls like this:</p>\n<pre class=\"lang:swift decode:true\">AppLabel.appearance().textColor = .red\nAppSubhead.appearance().textColor = .purple\nAppFootnote.appearance().textColor = .orange\n\nAppButton.appearance().setTitleColor(.green, for: .normal)\nAppButton.appearance().borderColor = .green\nAppButton.appearance().borderWidth = 1\nAppButton.appearance().cornerRadius = 3\n</pre>\n<p>This should take place in the <code>AppDelegate.willFinishLaunchingWithOptions</code> event so it can be ready before any controls are loaded into your app. You can call the <code>UIAppearance</code> proxy later to change your styles, but it will only apply to newly added controls to the window. All existing controls need to be removed and added back to have the new styles take effect (yes more quirks, but I have a helper below I will mention).</p>\n<h2>The Theme Protocol</h2>\n<p>We need swappable themes for our app right? Even if you only have one theme, designing it in such a way will allow you to maintain the styles much more easily and add different themes later.</p>\n<p>Here&#8217;s a protocol for the themes we can use:</p>\n<pre class=\"lang:swift decode:true \">protocol Theme {\n    var tint: UIColor { get }\n    var secondaryTint: UIColor { get }\n    \n    var backgroundColor: UIColor { get }\n    var separatorColor: UIColor { get }\n    var selectionColor: UIColor { get }\n    \n    var labelColor: UIColor { get }\n    var secondaryLabelColor: UIColor { get }\n    var subtleLabelColor: UIColor { get }\n    \n    var barStyle: UIBarStyle { get }\n}</pre>\n<p>Then we can extend the protocol to change the appearance for controls using the above properties which themes will conform to. The extension can look something like:</p>\n<pre class=\"lang:swift decode:true\">extension Theme {\n    \n    func apply(for application: UIApplication) {\n        application.keyWindow?.tintColor = tint\n        \n        UITabBar.appearance().barStyle = barStyle\n        \n        UINavigationBar.appearance().barStyle = barStyle\n        UINavigationBar.appearance().tintColor = tint\n        UINavigationBar.appearance().titleTextAttributes = [\n            .foregroundColor: labelColor\n        ]\n        \n        if #available(iOS 11.0, *) {\n            UINavigationBar.appearance().largeTitleTextAttributes = [\n                .foregroundColor: labelColor\n            ]\n        }\n        \n        UICollectionView.appearance().backgroundColor = backgroundColor\n        UITableView.appearance().backgroundColor = backgroundColor\n        UITableView.appearance().separatorColor = separatorColor\n        UITableViewCell.appearance().backgroundColor = .clear\n        UITableViewCell.appearance().selectionColor = selectionColor\n        \n        UIView.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self])\n            .backgroundColor = selectionColor\n        \n        UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self])\n            .textColor = secondaryLabelColor\n        \n        AppLabel.appearance().textColor = labelColor\n        AppSubhead.appearance().textColor = secondaryLabelColor\n        AppFootnote.appearance().textColor = subtleLabelColor\n        \n        AppButton.appearance().borderColor = tint\n        AppButton.appearance().setTitleColor(tint, for: .normal)\n        AppButton.appearance().borderWidth = 1\n        AppButton.appearance().cornerRadius = 3\n        \n        AppDangerButton.appearance().borderWidth = 0\n        AppDangerButton.appearance().setTitleColor(labelColor, for: .normal)\n        AppDangerButton.appearance().backgroundColor = tint\n        \n        AppSwitch.appearance().tintColor = tint\n        \n        AppView.appearance().backgroundColor = backgroundColor\n        AppSeparator.appearance().backgroundColor = separatorColor\n        AppSeparator.appearance().alpha = 0.5\n    }\n}</pre>\n<p>And the themes that conform would only have to fill in the property values:</p>\n<pre class=\"lang:swift decode:true\">struct DarkTheme: Theme {\n    let tint: UIColor = .yellow\n    let secondaryTint: UIColor = .green\n    \n    let backgroundColor: UIColor = .black\n    let separatorColor: UIColor = .lightGray\n    let selectionColor: UIColor = .init(red: 38/255, green: 38/255, blue: 40/255, alpha: 1)\n    \n    let labelColor: UIColor = .white\n    let secondaryLabelColor: UIColor = .lightGray\n    let subtleLabelColor: UIColor = .darkGray\n    \n    let barStyle: UIBarStyle = .black\n}</pre>\n<p>Here&#8217;s what another theme would look like:</p>\n<pre class=\"lang:swift decode:true\">struct LightTheme: Theme {\n    let tint: UIColor = .blue\n    let secondaryTint: UIColor = .orange\n    \n    let backgroundColor: UIColor = .white\n    let separatorColor: UIColor = .lightGray\n    let selectionColor: UIColor = .init(red: 236/255, green: 236/255, blue: 236/255, alpha: 1)\n    \n    let labelColor: UIColor = .black\n    let secondaryLabelColor: UIColor = .darkGray\n    let subtleLabelColor: UIColor = .lightGray\n    \n    let barStyle: UIBarStyle = .default\n}</pre>\n<p>Finally you call the theme early in the app lifecycle:</p>\n<pre class=\"lang:swift decode:true \">@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n    private let theme = DarkTheme()\n    \n    var window: UIWindow?\n\n    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -&gt; Bool {\n        theme.apply(for: application)\n        return true\n    }\n}</pre>\n<p>There you have it &#8211; native, simple theming for your iOS app.. no dependency, magic, or singleton!</p>\n<h2>Extending Themes</h2>\n<p>What if one of your custom themes wants to add extra styling? Implementing the <code>func apply(for application: UIApplication)</code> on the theme will wipe out existing logic which is not what we want, so instead I can add a <code>func extend()</code> to the protocol and call it within the <code>apply(for:)</code> extension:</p>\n<pre class=\"lang:swift decode:true \">protocol Theme {\n    ...\n    func apply(for application: UIApplication)\n    func extend()\n}\n\nextension Theme {\n    \n    func apply(for application: UIApplication) {\n        ...\n        extend()\n    }\n    \n    func extend() {\n        // Optionally extend theme\n    }\n}</pre>\n<p>You see how <code>apply(for:)</code> calls <code>extend()</code> right in the protocol extension? Now the themes that conform can simply put their extended styling logic in <code>extend()</code>:</p>\n<pre class=\"lang:swift decode:true \">struct LightTheme: Theme {\n    ...\n}\n\nextension LightTheme {\n    \n    func extend() {\n        let proxy1 = UIImageView.appearance(whenContainedInInstancesOf: [UITableViewCell.self])\n        proxy1.borderColor = separatorColor\n        proxy1.borderWidth = 1\n        \n        let proxy2 = UIImageView.appearance(whenContainedInInstancesOf: [UIButton.self, UITableViewCell.self])\n        proxy2.borderWidth = 0\n    }\n}</pre>\n<h2>Changing Themes</h2>\n<p>Another reason why most people abandon <code>UIAppearance</code> is you can&#8217;t change styles for existing controls that are already loaded. Apple makes it clear in the <a href=\"https://developer.apple.com/documentation/uikit/uiappearance\" target=\"_blank\" rel=\"noopener noreferrer\">documentation</a>:</p>\n<blockquote><p>iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.</p></blockquote>\n<p>It&#8217;s pretty ridiculous that every single control has to be removed and added again to realize the new styles. After changing <code>UIAppearance</code> values, you have to traverse through the entire <code>UIWindow</code> hierarchy and remove/add  controls:</p>\n<pre class=\"lang:swift decode:true \">UIApplication.shared.windows.forEach { window in\n    window.subviews.forEach { view in\n        view.removeFromSuperview()\n        window.addSubview(view)\n    }\n}\n</pre>\n<p>It makes my stomach turn, but I guess users shouldn&#8217;t be changing themes often &#8211; plus it&#8217;s still native theming right?</p>\n<p>Take it one step further and turn it into an extension:</p>\n<pre class=\"lang:swift decode:true\">public extension UIWindow {\n    \n    /// Unload all views and add back.\n    /// Useful for applying `UIAppearance` changes to existing views.\n    func reload() {\n        subviews.forEach { view in\n            view.removeFromSuperview()\n            addSubview(view)\n        }\n    }\n}\n\npublic extension Array where Element == UIWindow {\n    \n    /// Unload all views for each `UIWindow` and add back.\n    /// Useful for applying `UIAppearance` changes to existing views.\n    func reload() {\n        forEach { $0.reload() }\n    }\n}</pre>\n<p>Now in your original <code>Theme</code> protocol, you can abstract it away:</p>\n<pre class=\"lang:swift decode:true\">protocol Theme {\n    ...\n}\n\nextension Theme {\n    \n    func apply(for application: UIApplication) {\n        ...\n        \n        // Ensure existing views render with new theme\n        application.windows.reload()\n    }</pre>\n<p>Note that the first time the theme gets applied in <code>AppDelegate.willFinishLaunchingWithOptions</code>, the  <code>window</code> object won&#8217;t have any subviews in it so it will just be ignored. The <code>reload</code> will only run if called after <code>AppDelegate.willFinishLaunchingWithOptions</code>.</p>\n<h2>Beyond Colors</h2>\n<p>So far I&#8217;ve only emphasized colors, but you can style fonts with <code>UIAppearance</code>, but I prefer to only use the built-in ones in storyboard because it respects dynamic font sizes. If your designer insists, you&#8217;ll want to support accessibility which is a whole other topic.</p>\n<p>But did you know you can use <code>UIAppearance</code> on just about any property? You can even change text properties for all <code>UILabel</code> controls! Of course this would be obnoxious to do, but it&#8217;s possible:</p>\n<pre class=\"lang:swift decode:true \">UILabel.appearance().text = \"Hello World!\"</pre>\n<p>You could, however, add your own custom properties and set them via <code>UIAppearance</code> as well! Let&#8217;s take the selected highlight color for <code>UITableViewCell</code>. This is not a native property from <code>UIKit</code> unfortunately, so you&#8217;d have to do something like this:</p>\n<pre class=\"lang:swift decode:true \">let selectedView = UIView()\nselectedView.backgroundColor = .lightGray\n\nmyTableViewCell.selectedBackgroundView = selectedView</pre>\n<p>You could take it one step further and turn it into an extension:</p>\n<pre class=\"lang:swift decode:true \">extension UITableViewCell {\n    \n    /// The color of the cell when it is selected.\n    var selectionColor: UIColor? {\n        get { return selectedBackgroundView?.backgroundColor }\n        set {\n            guard selectionStyle != .none else { return }\n            selectedBackgroundView = UIView().with {\n                $0.backgroundColor = newValue\n            }\n        }\n    }\n}</pre>\n<p>When you try to update this property via <code>UIAppearance</code>, you&#8217;ll notice it doesn&#8217;t do anything. To expose your custom properties to <code>UIAppearance</code>, you have to add the <code>dynamic</code> keyword to the property to force the <em>Swift</em> compiler to use an <em>Objective-C</em> message that <code>UIAppearance</code> relies on:</p>\n<pre class=\"lang:swift decode:true \">extension UITableViewCell {\n    \n    /// The color of the cell when it is selected.\n    @objc dynamic var selectionColor: UIColor? {\n        get { return selectedBackgroundView?.backgroundColor }\n        set {\n            guard selectionStyle != .none else { return }\n            selectedBackgroundView = UIView().with {\n                $0.backgroundColor = newValue\n            }\n        }\n    }\n}</pre>\n<p>Now you can do this:</p>\n<pre class=\"lang:swift decode:true \">UITableViewCell.appearance().selectionColor = .init(red: 38/255, green: 38/255, blue: 40/255, alpha: 1)</pre>\n<p>At this point, we got everything we need.</p>\n<h2>Demo Time!</h2>\n<p>I put together a sample project with a segmented control to switch between themes:</p>\n<p><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot-500x354.png\" alt=\"\" width=\"500\" height=\"354\" class=\"aligncenter size-medium wp-image-41397\" srcset=\"https://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot-500x354.png 500w, https://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot-768x544.png 768w, https://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot-1024x725.png 1024w\" sizes=\"(max-width: 500px) 100vw, 500px\" /></p>\n<p>The <code>Theme</code> protocol that does the heavy lifting looks like this:</p>\n<pre class=\"lang:swift decode:true \">protocol Theme {\n    var tint: UIColor { get }\n    var secondaryTint: UIColor { get }\n    \n    var backgroundColor: UIColor { get }\n    var separatorColor: UIColor { get }\n    var selectionColor: UIColor { get }\n    \n    var labelColor: UIColor { get }\n    var secondaryLabelColor: UIColor { get }\n    var subtleLabelColor: UIColor { get }\n    \n    var barStyle: UIBarStyle { get }\n    \n    func apply(for application: UIApplication)\n    func extend()\n}\n\nextension Theme {\n    \n    func apply(for application: UIApplication) {\n        application.keyWindow?.tintColor = tint\n        \n        UITabBar.appearance().with {\n            $0.barStyle = barStyle\n            $0.tintColor = tint\n        }\n        \n        UINavigationBar.appearance().with {\n            $0.barStyle = barStyle\n            $0.tintColor = tint\n            $0.titleTextAttributes = [\n                .foregroundColor: labelColor\n            ]\n            \n            if #available(iOS 11.0, *) {\n                $0.largeTitleTextAttributes = [\n                    .foregroundColor: labelColor\n                ]\n            }\n        }\n        \n        UICollectionView.appearance().backgroundColor = backgroundColor\n        \n        UITableView.appearance().with {\n            $0.backgroundColor = backgroundColor\n            $0.separatorColor = separatorColor\n        }\n        \n        UITableViewCell.appearance().with {\n            $0.backgroundColor = .clear\n            $0.selectionColor = selectionColor\n        }\n        \n        UIView.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self])\n            .backgroundColor = selectionColor\n        \n        UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self])\n            .textColor = secondaryLabelColor\n        \n        AppLabel.appearance().textColor = labelColor\n        AppHeadline.appearance().textColor = secondaryTint\n        AppSubhead.appearance().textColor = secondaryLabelColor\n        AppFootnote.appearance().textColor = subtleLabelColor\n        \n        AppButton.appearance().with {\n            $0.setTitleColor(tint, for: .normal)\n            $0.borderColor = tint\n            $0.borderWidth = 1\n            $0.cornerRadius = 3\n        }\n        \n        AppDangerButton.appearance().with {\n            $0.setTitleColor(backgroundColor, for: .normal)\n            $0.backgroundColor = tint\n            $0.cornerRadius = 3\n        }\n        \n        AppSwitch.appearance().with {\n            $0.tintColor = tint\n            $0.onTintColor = tint\n        }\n        \n        AppStepper.appearance().tintColor = tint\n        \n        AppSlider.appearance().tintColor = tint\n        \n        AppSegmentedControl.appearance().tintColor = tint\n        \n        AppView.appearance().backgroundColor = backgroundColor\n        \n        AppSeparator.appearance().with {\n            $0.backgroundColor = separatorColor\n            $0.alpha = 0.5\n        }\n        \n        AppView.appearance(whenContainedInInstancesOf: [AppView.self]).with {\n            $0.backgroundColor = selectionColor\n            $0.cornerRadius = 10\n        }\n        \n        // Style differently when inside a special container\n        \n        AppLabel.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).textColor = subtleLabelColor\n        AppHeadline.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).textColor = secondaryLabelColor\n        AppSubhead.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).textColor = secondaryTint\n        AppFootnote.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).textColor = labelColor\n        \n        AppButton.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).with {\n            $0.setTitleColor(labelColor, for: .normal)\n            $0.borderColor = labelColor\n        }\n        \n        AppDangerButton.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).with {\n            $0.setTitleColor(subtleLabelColor, for: .normal)\n            $0.backgroundColor = labelColor\n        }\n        \n        AppSwitch.appearance(whenContainedInInstancesOf: [AppView.self, AppView.self]).with {\n            $0.tintColor = secondaryTint\n            $0.onTintColor = secondaryTint\n        }\n        \n        extend()\n        \n        // Ensure existing views render with new theme\n        // https://developer.apple.com/documentation/uikit/uiappearance\n        application.windows.reload()\n    }\n    \n    func extend() {\n        // Optionally extend theme\n    }\n}</pre>\n<p>Then you can add as many themes as you want:</p>\n<pre class=\"lang:swift decode:true\">struct OceanTheme: Theme {\n    let tint: UIColor = .blue\n    let secondaryTint: UIColor = .orange\n    \n    let backgroundColor: UIColor = .cyan\n    let separatorColor: UIColor = .lightGray\n    let selectionColor: UIColor = .init(red: 38/255, green: 38/255, blue: 40/255, alpha: 1)\n    \n    let labelColor: UIColor = .magenta\n    let secondaryLabelColor: UIColor = .lightGray\n    let subtleLabelColor: UIColor = .darkGray\n    \n    let barStyle: UIBarStyle = .default\n}</pre>\n<p>Finally in my segmented control change event, I can simply change themes like this:</p>\n<pre class=\"lang:swift decode:true \">@IBAction func themeSegmentedControlChanged(_ sender: UISegmentedControl) {\n    let theme: Theme\n        \n    switch sender.selectedSegmentIndex {\n    case 1: theme = LightTheme()\n    case 2: theme = OceanTheme()\n    default: theme = DarkTheme()\n    }\n        \n    theme.apply(for: UIApplication.shared)\n}</pre>\n<p>The complete source code can be <a href=\"https://github.com/basememara/ThemeKit\" target=\"_blank\" rel=\"noopener noreferrer\">downloaded and run here</a>.</p>\n<h2>Conclusion</h2>\n<p><code>UIAppearance</code> has been around since iOS 5, but it is often overlooked and underestimated. Apple uses this framework to style its own apps, such as <em>Find Friends</em> and many other apps. Sticking with native functionality is always a good idea and hopefully I&#8217;ve given you a newfound appreciation for the built-in theming framework.</p>\n<p>To learn more about <code>UIAppearance</code>, check out these resources:</p>\n<ul>\n<li><a href=\"https://developer.apple.com/videos/play/wwdc2011/114/\" target=\"_blank\" rel=\"noopener noreferrer\">WWDC 2011: Customizing the Appearance of UIKit Controls</a></li>\n<li><a href=\"https://developer.apple.com/videos/play/wwdc2012/216/\" target=\"_blank\" rel=\"noopener noreferrer\">WWDC 2012: Advanced Appearance Customization on iOS</a></li>\n<li><a href=\"https://spin.atomicobject.com/2017/08/16/uiappearance-container-hierarchies/\" target=\"_blank\" rel=\"noopener noreferrer\">Understanding UIAppearance Container Hierarchies</a></li>\n</ul>\n<p><em><strong>Happy Coding!!</strong></em></p>\n<hr />\r\n<h2 style=\"text-align: center;\">FREE Masterclass Webinar: Creating Cross-Platform Swift Frameworks for iOS, watchOS, &amp; tvOS!</h2>\r\n<p>An essential part of creating scalable apps is code organization. Watch my updated \"Creating Cross-Platform Swift Frameworks\" webinar; it will change the way you build iOS apps! <a href=\"https://iosmentor.io/webinars/swift-frameworks/\" target=\"_blank\" rel=\"noopener\"><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/04/swift-framework-webinar.png\" alt=\"\" width=\"406\" height=\"257\" class=\"aligncenter size-full wp-image-41351\" /></a></p>\n")
        XCTAssertEqual(model.posts[1].commentCount, 2)
        XCTAssertEqual(model.posts[1].link, "https://staging1.basememara.com/protocol-oriented-themes-for-ios-apps/")
        XCTAssertEqual(model.posts[1].authorID, 2)
        XCTAssertEqual(model.posts[1].mediaID, 41397)
        XCTAssertEqual(model.posts[1].meta["_series_part"], "7")
        XCTAssertEqual(model.posts[1].terms, [80, 53, 62, 55, 81])
        XCTAssertEqual(model.posts[1].createdAt, DateFormatter.iso8601.date(from: "2018-09-29T17:12:15"))
        XCTAssertEqual(model.posts[1].modifiedAt, DateFormatter.iso8601.date(from: "2019-03-18T02:25:53"))
        
        XCTAssertEqual(model.posts.last?.id, 41294)
        XCTAssertEqual(model.posts.last?.title, "So Swift, So Clean Architecture for iOS")
        XCTAssertEqual(model.posts.last?.slug, "swift-clean-architecture")
        XCTAssertEqual(model.posts.last?.type, "post")
        XCTAssertEqual(model.posts.last?.excerpt, "The topic of iOS app architecture has evolved a long way from MVC. Unfortunately, the conversation becomes a frameworks and patterns war. The reality is: Rx is a framework; MVVM is a presentation pattern; and so on. Frameworks and patterns always come and go, but architectures are timeless. In this post, we will examine the Clean Architecture for building scalable apps in iOS.")
        XCTAssertEqual(model.posts.last?.content, "<blockquote><p>You are not paid to code; you are paid to create solutions.</p></blockquote>\n<p>The topic of iOS app architecture has evolved a long way from MVC. Unfortunately, the conversation becomes a frameworks and patterns war. The reality is: Rx is a framework; MVVM is a presentation pattern; and so on. Frameworks and patterns always come and go, but architectures are timeless. In this post, we will examine the Clean Architecture for building scalable apps in iOS.</p>\n<h2>What About Bob?</h2>\n<p>The Clean Architecture was coined by Uncle Bob almost 20 years ago. It is independent of platforms, frameworks, databases, or UI. It is testable. It&#8217;s a way of life (ok, software life). Sound good?</p>\n<p>If you have an hour to spare for learning, I highly suggest watching this lecture called <strong>The Principles of Clean Architecture by Uncle Bob Martin</strong> <em>(skip to 10:00 if you don&#8217;t want the biology lesson, although still interesting)</em>:</p>\n<p><iframe width=\"500\" height=\"281\" src=\"https://www.youtube.com/embed/o_TH-Y78tt4?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe></p>\n<h2>A Thing About Screaming Architecture</h2>\n<p>Regarding project structure, let&#8217;s first get the feature vs. type debate out the way. The application should scream what it does without any IDE or explanation at all. Anyone should be able to open up the file system and know exactly what the application does. Take a look at the two apps below:</p>\n<p><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/04/feature-vs-type-project.png\" alt=\"\" width=\"266\" height=\"568\" class=\"aligncenter size-full wp-image-41299\" /></p>\n<p>In the first app, all it tells me is that it&#8217;s an MVC project and has something to do with products and users. Why do I have to know MVC to figure out what it does? I have to compile and run it in my mind to figure out what it does. What&#8217;s worse, I have to expand all the folders to start investigating. In a complex app, imagine hundreds of controllers or views polluting your eyes. Maintaining and debugging are nightmare too, jumping back and forth between folders is like a game of ping pong.</p>\n<p>Now take a look at the second app. Right off the bat, I can tell it lists products, displays it, and shows a user&#8217;s profile. I don&#8217;t have to expand the folders to know what it is. I don&#8217;t have to know what framework or pattern it&#8217;s using. I don&#8217;t even have to know what language it&#8217;s written in!</p>\n<p>Another way to look at it is would you rather organize drawers by just throwing everything into three drawers, or is it better to have several small well-defined and well-labeled drawers?</p>\n<p>Ok let&#8217;s move on&#8230;</p>\n<h2>The Anatomy of the Clean Architecture</h2>\n<p>There are actually many variations and flavours of the Clean Architecture. You&#8217;ve probably heard of <a href=\"https://mutualmobile.com/posts/meet-viper-fast-agile-non-lethal-ios-architecture-framework\" target=\"_blank\" rel=\"noopener\">VIPER</a> or <a href=\"https://clean-swift.com\" target=\"_blank\" rel=\"noopener\">Clean Swift</a>. When you jump into other platforms like Android or .NET, there even exists more flavours. The one I will show you in this post was <em>heavily</em> inspired by Clean Swift. I put my own spin to it after battle-testing it and maintaining it across several teams, platforms, and environments.</p>\n<p>To get started, we have to get some terminology out the way. Below are a list of components in the architecture:</p>\n<ul>\n<li><strong>View:</strong> The interface where user interactions occur, such as the <code>Storyboard</code> or <code>XIB</code>.</li>\n<li><strong>Controller:</strong> The layer which binds the view to code, this being the <code>UIViewController</code> in our case.</li>\n<li><strong>Interactor:</strong> The business logic layer where the controller must send requests through.</li>\n<li><strong>Presenter:</strong> The layer that formats the response from the Interactor and sends it back to the controller.</li>\n<li><strong>Router:</strong> The layer that transports the user to another use case scene, usually an event that occurs in the controller.</li>\n</ul>\n<p>The core pieces of the architecture is the <em>Controller, Interactor, and Presenter</em>. The important thing to notice is that it has a uni-directional flow! This tremendously reduces complexity and makes it easy to manage. Since a picture is worth a thousand words, I have summed up the entire architecture in a single diagram:</p>\n<p><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/04/Clean-Architecture-Cycle-2-500x518.png\" alt=\"\" width=\"500\" height=\"518\" class=\"aligncenter wp-image-41346 size-medium\" /></p>\n<p>Follow the flow below to understand how the architecture works:</p>\n<ol>\n<li>User interacts with <strong><em>View</em></strong></li>\n<li><strong><em>Controller</em></strong> event fires, builds a request model, and calls the <strong><em>Interactor</em></strong></li>\n<li>The <strong><em>Interactor</em></strong> calls the underlying core library with all your workers to access the data (could even subscribe to an observable here if needed)</li>\n<li>The <strong><em>Interactor</em></strong> receives data from the worker and wraps it in a response model to send to the <strong><em>Presenter</em></strong></li>\n<li>The <strong><em>Presenter</em></strong> calls app-level helpers if needed to format or localize the response and builds a view model to send to the <strong><em>Controller</em></strong></li>\n<li>The <strong><em>Controller</em></strong> receives the view model in a function and binds it to the <strong><em>View</em></strong></li>\n<li>Repeat the cycle&#8230;</li>\n</ol>\n<p>Also notice the architecture is cross-platform. It doesn&#8217;t care that the view is served by an iOS app, Android app, web browser, or even a REST API endpoint. Once it gets past the view, everything should be identical across platforms. In fact, an iOS and Android app can be eerily similar with just the <code>Storyboard</code> vs <code>Layout</code> being the difference. Even the iOS <code>UIViewController</code> and Android <code>Activity</code> code would almost be identical except for the binding logic. This makes collaboration and bug fixing tight between teams!</p>\n<h2>The Details</h2>\n<p><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/04/show_me_the_code.jpg\" alt=\"\" width=\"306\" height=\"165\" class=\"aligncenter size-full wp-image-41304\" /></p>\n<p>It&#8217;s time to see how this plays out in code. We can do this by first examining the protocols that is the blueprint for a use case; this is important so the boundaries are defined and components are decoupled:</p>\n<pre class=\"lang:swift decode:true\">protocol ListProductsDisplayable: class { // View Controller\r\n    func displayFetchedProducts(with viewModel: ListProductsModels.ViewModel)\r\n    func display(error: AppModels.Error)\r\n}\r\n\r\nprotocol ListProductsBusinessLogic { // Interactor\r\n    func fetchProducts(with request: ListProductsModels.FetchRequest)\r\n}\r\n\r\nprotocol ListProductsPresentable { // Presenter\r\n    func presentFetchedProducts(for response: ListProductsModels.Response)\r\n    func presentFetchedProducts(error: DataError)\r\n}\r\n\r\nprotocol ListProductsRoutable: AppRoutable { // Router\r\n    func showProduct(for id: Int)\r\n}</pre>\n<p>Here&#8217;s what happens when the controller loads via <code>viewDidLoad</code>: <em>interactor.fetchProducts &gt; presenter.presentFetchedProducts &gt; controller.displayFetchedProducts</em>. Do you see it yet? The cycle is there. Let&#8217;s take another look&#8230;</p>\n<p><em>Controller:</em></p>\n<pre class=\"lang:swift decode:true\">class ListProductsViewController: UIViewController {\r\n\r\n    private lazy var interactor: ListProductsBusinessLogic = ListProductsInteractor(\r\n        presenter: ListProductsPresenter(viewController: self),\r\n        productsWorker: ProductsWorker(store: ProductsMemoryStore())\r\n    )\r\n    \r\n    private lazy var router: ListProductsRoutable = ListProductsRouter(\r\n        viewController: self\r\n    )\r\n\r\n    private var viewModel: ListProductsModels.ViewModel?\r\n\r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n\r\n        interactor.fetchProducts(\r\n            with: ListProductsModels.FetchRequest()\r\n        )\r\n    }\r\n}\r\n\r\nextension ListProductsViewController: ListProductsDisplayable {\r\n    \r\n    func displayFetchedProducts(with viewModel: ListProductsModels.ViewModel) {\r\n        self.viewModel = viewModel\r\n        tableView.reloadData()\r\n    }    \r\n\r\n    func display(error: AppModels.Error) {\r\n        let alertController = UIAlertController(\r\n            title: error.title,\r\n            message: error.message,\r\n            preferredStyle: .alert\r\n        )\r\n        \r\n        alertController.addAction(\r\n            UIAlertAction(title: \"OK\", style: .default, handler: nil)\r\n        )\r\n        \r\n        present(alertController, animated: true, completion: nil)\r\n    }\r\n}\r\n\r\nextension ListProductsViewController: UITableViewDelegate {\r\n    \r\n    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\r\n        guard let model = viewModel?.products[indexPath.row] else { return }\r\n        router.showProduct(for: model.id)\r\n    }\r\n}</pre>\n<p>The controller creates the instances to the interactor, injects the presenter, and also creates the router. When loaded, it creates a request model and calls the interactor:</p>\n<pre class=\"lang:swift decode:true\">struct ListProductsInteractor {\r\n    private let presenter: ListProductsPresentable\r\n    private let productsWorker: ProductsWorkerType\r\n    \r\n    init(presenter: ListProductsPresentable, productsWorker: ProductsWorkerType) {\r\n        self.presenter = presenter\r\n        self.productsWorker = productsWorker\r\n    }\r\n}\r\n\r\nextension ListProductsInteractor: ListProductsBusinessLogic {\r\n    \r\n    func fetchProducts(with request: ListProductsModels.FetchRequest) {\r\n        productsWorker.fetch {\r\n            guard let value = $0.value, $0.isSuccess else {\r\n                return self.presenter.presentFetchedProducts(error: $0.error ?? .unknownReason(nil))\r\n            }\r\n            \r\n            self.presenter.presentFetchedProducts(\r\n                for: ListProductsModels.Response(products: value)\r\n            )\r\n        }\r\n    }\r\n}\r\n</pre>\n<p>The <code>fetchProducts</code> function in the interactor calls the injected <code>productsWorker</code> (DI was left out for clarity, see my other post <a href=\"http://staging1.basememara.com/swift-protocol-oriented-dependency-injection/\" target=\"_blank\" rel=\"noopener\">Swifty Dependency Injection</a> for that topic). Underneath, it will call the appropriate storage, whether it be Core Data, Realm, or even a file system&#8230; the architecture doesn&#8217;t care and could be swapped out without affecting the cycle! When the data returns from the data storage asynchronously, it will wrap it in a response model and send it to the presenter:</p>\n<pre class=\"lang:swift decode:true \">struct ListProductsPresenter: ListProductsPresentable {\r\n    private weak var viewController: ListProductsDisplayable?\r\n    private let currencyFormatter: NumberFormatter\r\n    \r\n    init(viewController: ListProductsDisplayable?) {\r\n        self.viewController = viewController\r\n        self.currencyFormatter = NumberFormatter()\r\n        self.currencyFormatter.numberStyle = .currency\r\n    }\r\n}\r\n\r\nextension ListProductsPresenter {\r\n    \r\n    func presentFetchedProducts(for response: ListProductsModels.Response) {\r\n        let viewModel = ListProductsModels.ViewModel(\r\n            products: response.products.map {\r\n                ListProductsModels.ProductViewModel(\r\n                    id: $0.id,\r\n                    name: $0.name,\r\n                    content: $0.content,\r\n                    price: currencyFormatter.string(from: NSNumber(value: Float($0.priceCents) / 100)) ?? \"\\($0.priceCents / 100)\"\r\n                )\r\n            }\r\n        )\r\n        \r\n        viewController?.displayFetchedProducts(with: viewModel)\r\n    }\r\n    \r\n    func presentFetchedProducts(error: DataError) {\r\n        // Handle and parse error\r\n        let viewModel = AppModels.Error(\r\n            title: NSLocalizedString(\"products.error.title\", \"Title for product error\"),\r\n            message: String(format: NSLocalizedString(\"products.error.message\", \"Message for product error\"), error)\r\n        )\r\n        \r\n        viewController?.display(error: viewModel)\r\n    }\r\n}</pre>\n<p>The presenter will convert the response into a view model, applying any formatting and localization, and call the controller function to display it. The view model properties are almost always strings because the view will just display. If the interactor gave the presenter an error, it will even create a view model out of the error and let the controller display it.</p>\n<p>The models are encapsulated in an enum and are only relevant to its own use case. You do not cross boundaries without being wrapped in one of the models:</p>\n<pre class=\"lang:swift decode:true \">enum ListProductsModels {\r\n    \r\n    struct FetchRequest {\r\n        \r\n    }\r\n    \r\n    struct SearchRequest {\r\n        let text: String\r\n    }\r\n    \r\n    struct Response {\r\n        let products: [ProductType]\r\n    }\r\n    \r\n    struct ViewModel {\r\n        let products: [ProductViewModel]\r\n    }\r\n    \r\n    struct ProductViewModel {\r\n        let id: Int\r\n        let name: String\r\n        let content: String\r\n        let price: String\r\n    }\r\n}</pre>\n<p>Finally the router in case the controller has to send the user to another use case:</p>\n<pre class=\"lang:swift decode:true\">struct ListProductsRouter {\r\n    weak var viewController: UIViewController?\r\n    \r\n    init(viewController: UIViewController?) {\r\n        self.viewController = viewController\r\n    }\r\n}\r\n\r\nextension ListProductsRouter: ListProductsRoutable {\r\n    \r\n    func showProduct(for id: Int) {\r\n        let storyboard = UIStoryboard(name: \"ShowProduct\", bundle: nil)\r\n        \r\n        guard let controller = storyboard.instantiateInitialViewController()) as? ShowProductViewController\r\n            else { return assertionFailure(\"Invalid controller for storyboard \\(storyboard).\") }\r\n\r\n        controller.productID = id\r\n\r\n        viewController?.present(controller, animated: true)\r\n    }\r\n}</pre>\n<p>This way, the the controller is decoupled from the routing decisions and can be used from the controller as: <code>router.showProduct(for: productID)</code>.</p>\n<h2>Conclusion</h2>\n<p>The Clean Architecture is flexible, scalable, and maintainable. Although it is more verbose than other architecture designs, it is necessary so components are not tightly coupled. That means everything must reference each other by its protocol, not its concrete types. And when crossing boundaries, data must be wrapped in request / response models, or again components will be coupled. In a future post, I will discuss how to unit test the whole stack.</p>\n<p>See a <a href=\"https://github.com/iosmentor-io/Swift-Clean-Architecture\" target=\"_blank\" rel=\"noopener\">working example of this Clean Architecture</a> to try it out for yourself.</p>\n<p><em><strong>HAPPY CODING!!</strong></em></p>\n<hr />\r\n<h2 style=\"text-align: center;\">FREE Masterclass Webinar: Creating Cross-Platform Swift Frameworks for iOS, watchOS, &amp; tvOS!</h2>\r\n<p>An essential part of creating scalable apps is code organization. Watch my updated \"Creating Cross-Platform Swift Frameworks\" webinar; it will change the way you build iOS apps! <a href=\"https://iosmentor.io/webinars/swift-frameworks/\" target=\"_blank\" rel=\"noopener\"><img src=\"http://staging1.basememara.com/wp-content/uploads/2018/04/swift-framework-webinar.png\" alt=\"\" width=\"406\" height=\"257\" class=\"aligncenter size-full wp-image-41351\" /></a></p>\n")
        XCTAssertEqual(model.posts.last?.commentCount, 10)
        XCTAssertEqual(model.posts.last?.link, "https://staging1.basememara.com/swift-clean-architecture/")
        XCTAssertEqual(model.posts.last?.authorID, 2)
        XCTAssertEqual(model.posts.last?.mediaID, 41346)
        XCTAssertEqual(model.posts.last?.meta["_series_part"], "1")
        XCTAssertEqual(model.posts.last?.terms, [80, 79, 53, 14, 62, 50, 55])
        XCTAssertEqual(model.posts.last?.createdAt, DateFormatter.iso8601.date(from: "2018-04-22T22:03:20"))
        XCTAssertEqual(model.posts.last?.modifiedAt, DateFormatter.iso8601.date(from: "2018-09-30T11:47:51"))
        
        XCTAssertEqual(model.authors[0].id, 2)
        XCTAssertEqual(model.authors[0].name, "Basem Emara")
        XCTAssertEqual(model.authors[0].link, "https://staging1.basememara.com")
        XCTAssertEqual(model.authors[0].avatar, "https://secure.gravatar.com/avatar/8def0d36f56d3e6720a44e41bf6f9a71?s=96&d=mm&r=g")
        XCTAssertEqual(model.authors[0].content, "Basem is a mobile and software IT professional with over 12 years of experience as an architect, developer, and consultant for dozens of projects that span over various industries for Fortune 500 enterprises, government agencies, and startups. In 2014, Basem brought his vast knowledge and experiences to Swift and helped pioneer the language to build scalable enterprise iOS &amp; watchOS apps, later providing mentorship courses at <a href=\"https://iosmentor.io\">https://iosmentor.io</a>.")
        XCTAssertEqual(model.authors[0].createdAt, DateFormatter.iso8601.date(from: "2015-02-02T03:39:52"))
        XCTAssertEqual(model.authors[0].modifiedAt, DateFormatter.iso8601.date(from: "2018-10-06T14:43:53"))
        
        XCTAssertEqual(model.media[0].id, 41287)
        XCTAssertEqual(model.media[0].link, "https://staging1.basememara.com/wp-content/uploads/2018/04/swift-dependency-injection.jpg")
        XCTAssertEqual(model.media[0].width, 3569)
        XCTAssertEqual(model.media[0].height, 2899)
        XCTAssertEqual(model.media[0].thumbnailLink, "https://staging1.basememara.com/wp-content/uploads/2018/04/swift-dependency-injection-500x406.jpg")
        XCTAssertEqual(model.media[0].thumbnailWidth, 500)
        XCTAssertEqual(model.media[0].thumbnailHeight, 406)
        
        XCTAssertEqual(model.media[1].id, 41397)
        XCTAssertEqual(model.media[1].link, "https://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot.png")
        XCTAssertEqual(model.media[1].width, 2194)
        XCTAssertEqual(model.media[1].height, 1554)
        XCTAssertEqual(model.media[1].thumbnailLink, "https://staging1.basememara.com/wp-content/uploads/2018/09/Theme-Screenshot-500x354.png")
        XCTAssertEqual(model.media[1].thumbnailWidth, 500)
        XCTAssertEqual(model.media[1].thumbnailHeight, 354)
        
        XCTAssertEqual(model.media.last?.id, 41346)
        XCTAssertEqual(model.media.last?.link, "https://staging1.basememara.com/wp-content/uploads/2018/04/Clean-Architecture-Cycle-2.png")
        XCTAssertEqual(model.media.last?.width, 500)
        XCTAssertEqual(model.media.last?.height, 518)
        XCTAssertEqual(model.media.last?.thumbnailLink, "https://staging1.basememara.com/wp-content/uploads/2018/04/Clean-Architecture-Cycle-2-500x518.png")
        XCTAssertEqual(model.media.last?.thumbnailWidth, 500)
        XCTAssertEqual(model.media.last?.thumbnailHeight, 518)
        
        XCTAssertEqual(model.terms[0].id, 80)
        XCTAssertEqual(model.terms[0].parentID, 0)
        XCTAssertEqual(model.terms[0].name, "Building a Scalable App")
        XCTAssertEqual(model.terms[0].slug, "build-scalable-app")
        XCTAssertEqual(model.terms[0].taxonomy, .other("series"))
        XCTAssertEqual(model.terms[0].count, 8)
        
        XCTAssertEqual(model.terms[1].id, 62)
        XCTAssertEqual(model.terms[1].parentID, 0)
        XCTAssertEqual(model.terms[1].name, "protocol-oriented-programming")
        XCTAssertEqual(model.terms[1].slug, "protocol-oriented-programming")
        XCTAssertEqual(model.terms[1].taxonomy, .tag)
        XCTAssertEqual(model.terms[1].count, 9)
        
        XCTAssertEqual(model.terms[3].id, 55)
        XCTAssertEqual(model.terms[3].parentID, 0)
        XCTAssertEqual(model.terms[3].name, "Swift")
        XCTAssertEqual(model.terms[3].slug, "swift")
        XCTAssertEqual(model.terms[3].taxonomy, .category)
        XCTAssertEqual(model.terms[3].count, 29)
        
        XCTAssertEqual(model.terms[4].id, 53)
        XCTAssertEqual(model.terms[4].parentID, 0)
        XCTAssertEqual(model.terms[4].name, "ios")
        XCTAssertEqual(model.terms[4].slug, "ios")
        XCTAssertEqual(model.terms[4].taxonomy, .tag)
        XCTAssertEqual(model.terms[4].count, 19)
        
        XCTAssertEqual(model.terms[5].id, 81)
        XCTAssertEqual(model.terms[5].parentID, 0)
        XCTAssertEqual(model.terms[5].name, "uikit")
        XCTAssertEqual(model.terms[5].slug, "uikit")
        XCTAssertEqual(model.terms[5].taxonomy, .tag)
        XCTAssertEqual(model.terms[5].count, 1)
        
        XCTAssertEqual(model.terms[6].id, 77)
        XCTAssertEqual(model.terms[6].parentID, 0)
        XCTAssertEqual(model.terms[6].name, "localization")
        XCTAssertEqual(model.terms[6].slug, "localization")
        XCTAssertEqual(model.terms[6].taxonomy, .tag)
        XCTAssertEqual(model.terms[6].count, 1)
        
        XCTAssertEqual(model.terms[7].id, 47)
        XCTAssertEqual(model.terms[7].parentID, 0)
        XCTAssertEqual(model.terms[7].name, "xcode")
        XCTAssertEqual(model.terms[7].slug, "xcode")
        XCTAssertEqual(model.terms[7].taxonomy, .tag)
        XCTAssertEqual(model.terms[7].count, 18)
    }
}
#endif
