We execute the fuzzy matching algorithm concurrently to reach 60 frames per second.
Episode 216 · Aug 14
We execute the fuzzy matching algorithm concurrently to reach 60 frames per second.
Episode 216 · Aug 14
We improve the performance of the fuzzy search algorithm by using better data types and avoiding unnecessary work.
Episode 215 · Aug 07
We lay the foundation for future performance improvements by refactoring our recursive algorithm to a matrix-based one.
Episode 214 · Jul 31
We switch to a recursive algorithm to perform a complete fuzzy match.
Episode 213 · Jul 24
To rank order search results, we introduce scores for matches and gaps.
Episode 212 · Jul 17
We start building a Quick Open feature by implementing a simple fuzzy matching algorithm.
Episode 211 · Jul 10
We conclude this series by fixing some minor bugs and adding member expressions to our template language.
Episode 210 · Jul 03
We implement the evaluation of for loops using tests for success and failure cases.
Episode 209 · Jun 26
We add for loops to our parser, making sure to give good error messages for syntax errors.
Episode 208 · Jun 19
We add parsing for HTML attributes and escape them properly during evaluation.
Episode 207 · Jun 12
We annotate the syntax tree with source positions, which allows us to improve the errors during evaluation.
Episode 206 · Jun 05
We start implementing the evaluation part of our template language.
Episode 205 · May 29
We add proper parse errors with source positions, making it much easier to diagnose problems.
Episode 204 · May 22
We start building an HTML template language, implementing the parser in a test-driven way.
Episode 203 · May 15
We rebuild the model layer with structs instead of classes and use bindings to provide mutable access to the views.
Episode 202 · May 08
We use published properties and property observers to clean up our model code, and we fix some issues on the iPad.
Episode 201 · May 01
We take a callback-based model API and refactor it into an observable object.
Episode 200 · Apr 24
We create a lazy wrapper for observable objects and use dynamic member lookup to ease its use.
Episode 199 · Apr 17
We wrap a UIKit alert in a SwiftUI-like API to present an alert with a text field.
Episode 198 · Apr 10
We continue working on the recording and playback screens while reusing existing model and helper classes from the MVC app.
Episode 197 · Apr 03
We start to implement the MVC sample app from our App Architecture book in SwiftUI reusing the original model.
Episode 196 · Mar 27
We wrap an MKMapView, using a diff on the annotations to properly animate insertions and removals.
Episode 195 · Mar 20
We create a view that automatically scales a text view to fill the available space.
Episode 194 · Mar 13
We add labels to the analog clock face, and we make it configurable to reuse it for counting the minutes.
Episode 193 · Mar 06
We draw an analog clock face and add moving pointers.
Episode 192 · Feb 28
We improve upon the virtual joystick for the 3D perspective, and we add basic lighting and widescreen support.
Episode 191 · Feb 21
We use the ray casting algorithm from the last episode to draw the scene in 3D for the first time.
Episode 190 · Feb 14
We prepare for drawing the scene in 3D by implementing a ray casting algorithm.
Episode 189 · Feb 07
We introduce player direction and implement a line drawing algorithm to visualize it.
Episode 188 · Jan 31
After making some improvements to the virtual joystick, we move on to collision detection and collision response.
Episode 187 · Jan 24
We load the maze, render it onscreen, and add a virtual joystick to control player movement.
Episode 186 · Jan 17
We add rudimentary play physics and decouple the world and bitmap dimensions to create smooth motion.
Episode 185 · Jan 10
Special guest Nick Lockwood guides us through his first tutorial for recreating a retro game using techniques from the 90s.
Episode 184 · Jan 03
We add lap times to the model, show them in a list, and highlight the shortest and longest laps.
Episode 183 · Dec 20 2019
We add the data model for the stopwatch to make it functional.
Episode 182 · Dec 13 2019
We enable our stopwatch buttons to self-size to fit their labels.
Episode 181 · Dec 06 2019
We use a custom button style to imitate the appearance of the stopwatch buttons on iOS.
Episode 180 · Nov 29 2019
We refactor our use of geometry readers and preferences to make our code more expressive.
Episode 179 · Nov 22 2019
We implement the drop functionality and work around several obstacles we encounter along the way.
Episode 178 · Nov 15 2019
We make our shopping cart interactive by adding drag and drop.
Episode 177 · Nov 08 2019
We use a view modifier with local state to animate views onto the screen.
Episode 176 · Nov 01 2019
We use anchors, preferences, and transitions to animate items from a grid into a cart.
Episode 175 · Oct 25 2019
We examine SwiftUI's animation curves using a custom view modifier.
Episode 174 · Oct 18 2019
We explore SwiftUI's rendering and animation model while building a shake animation.
Episode 173 · Oct 11 2019
We combine the logic for parsing 64-byte chunks from the last episode to process entire files.
Episode 172 · Oct 04 2019
We experiment with porting the low-level approach of a super-fast JSON parsing library to Swift.
Episode 171 · Sep 27 2019
We show a parsing technique that we use for many parsing tasks in our day-to-day work.
Episode 170 · Sep 20 2019
We use drag gesture recognizers to add reordering capabilities to our SwiftUI collection view.
Episode 169 · Sep 13 2019
We implement single-line and flow layouts for our SwiftUI collection view.
Episode 168 · Sep 06 2019
As a first step toward a collection view, we enable child views to communicate their sizes to a parent view.
Episode 167 · Aug 30 2019
We further refine the animation from last episode and refactor it using a geometry effect.
Episode 166 · Aug 23 2019
We start building a custom animation of a shape that moves along a path.
Episode 165 · Aug 16 2019
We experiment with paths and shapes to create a triangular preview badge.
Episode 164 · Aug 09 2019
We integrate Apple's web authentication framework to enable logging in with GitHub and then store the credentials using a keychain property wrapper.
Episode 163 · Aug 02 2019
We create a two-way binding from the play position of the video player to a bindable model object.
Episode 162 · Jul 26 2019
We integrate an AVPlayerViewController, expose its play state as a binding, and use a SwiftUI view as an overlay.
Episode 161 · Jul 17 2019
We look at different ways to load data from the network less eagerly.
Episode 160 · Jul 12 2019
We explore different approaches to passing data around in our SwiftUI app.
Episode 159 · Jul 05 2019
We start building a Swift Talk app using SwiftUI.
Episode 158 · Jun 28 2019
We integrate the tiny networking library into a SwiftUI project and wrap AppKit's progress indicator in a SwiftUI view.
Episode 157 · Jun 21 2019
We build a simple currency converter to experiment with SwiftUI's state-driven view updates.
Episode 156 · Jun 14 2019
We improve the performance of syntax highlighting to be able to work in large documents.
Episode 155 · Jun 07 2019
We use several pieces of code from earlier episodes to build a link checking extension on URLSession.
Episode 154 · May 31 2019
We discuss how Swift's type system can be used to eliminate impossible states from our code.
Episode 153 · May 24 2019
We implement fold on the CommonMark syntax tree and use it to extract links and text from a document.
Episode 152 · May 17 2019
We explore the differences between reduce and fold and how they can be implemented on any enum.
Episode 151 · May 10 2019
Wouter joins us to explore the origins of the reduce function.
Episode 150 · May 03 2019
We use SwiftSyntax to add highlighting for Swift code blocks.
Episode 149 · Apr 26 2019
We fix a couple of string-related bugs when interoperating with the cmark library and the REPL.
Episode 148 · Apr 19 2019
We launch a Swift REPL process to execute Swift code in our Markdown file.
Episode 147 · Apr 12 2019
We use CommonMark to parse the markdown string and then add attributes to highlight its syntax.
Episode 146 · Apr 05 2019
We start building our Markdown Playgrounds app from a plain command-line app package, leveraging AppKit's document architecture.
Episode 145 · Mar 29 2019
We refactor our string interpolation code to allow concatenation of multiple interpolated SQL queries.
Episode 144 · Mar 22 2019
We use Swift 5's new string interpolation API to automatically insert placeholders in SQL queries.
Episode 143 · Mar 15 2019
Using a protocol-based approach, we show how we write tests for the Swift Talk backend.
Episode 142 · Mar 08 2019
We show a refactoring of the view code in the Swift Talk backend that allows us to pass around dependencies automatically using a functional pattern.
Episode 141 · Mar 01 2019
To finish up the team member signup, we use a CSRF-validated POST request and then write a test for what we've built.
Episode 140 · Feb 22 2019
We continue working on the team member signup feature, showing how we handle sessions and perform database queries.
Episode 139 · Feb 15 2019
We show our new Swift Talk backend built on top of SwiftNIO by implementing a new team member signup feature.
Episode 138 · Feb 08 2019
We implement a test URL session that we can use to fake network responses.
Episode 137 · Feb 01 2019
We show an alternative implementation of combined resources that uses futures.
Episode 136 · Jan 25 2019
We add zip to the combined resource type, allowing us to express resources with multiple requests in parallel.
Episode 135 · Jan 18 2019
We implement an abstraction on top of our tiny networking library to express resources consisting of multiple requests.
Episode 134 · Jan 11 2019
We revisit the networking library we built in the first episode and discuss improvements we've made over the years.
Episode 133 · Jan 04 2019
We implement Dijkstra's algorithm to find the shortest path between any two points in the trail network.
Episode 132 · Dec 21 2018
We work on the efficiency of our graph-building algorithm, improving it by more than an order of magnitude.
Episode 131 · Dec 14 2018
We improve the graph-building algorithm by detecting overlaps between the tracks.
Episode 130 · Dec 07 2018
We start implementing the algorithm that transforms the GPS points into a graph, which we then visualize for debugging purposes.
Episode 129 · Nov 30 2018
We start implementing the routing logic by looking at the problem of calculating the shortest distance from a point to a line.
Episode 128 · Nov 23 2018
We enable the selection of points on our running tracks by tapping on the map, and we finish up by factoring a lot of this code out of the view controller.
Episode 127 · Nov 16 2018
We show the routing app we'll build in this series and take the first steps by rendering track polygons on a map.
Episode 126 · Nov 09 2018
We show how the layout library we've built over the past two months can be used to adapt to any font and screen size.
Episode 125 · Nov 02 2018
We implement the flexible width option for nested layouts.
Episode 124 · Oct 26 2018
We build upon the nested layout feature from last time to support layout margins, backgrounds, and more.
Episode 123 · Oct 19 2018
We build a feature that allows us to create more complex layouts by nesting layouts within each other.
Episode 122 · Oct 12 2018
We add flexible spaces to our layout library and show how elements can be shown or hidden depending on the available space.
Episode 121 · Oct 05 2018
We refactor our code to remove duplication, improve efficiency, and enable features like flexible spacing.
Episode 120 · Sep 28 2018
We add some features to our layout library — starting with horizontal and vertical spacing — along with a better syntax to define layouts.
Episode 119 · Sep 21 2018
We start building a responsive layout library that makes it easy to create layouts for all screen and font sizes.
Episode 118 · Sep 14 2018
Using a simple key path API, we add the ability to control the visibility of sections by any condition.
Episode 117 · Sep 07 2018
We add support for arrays by implementing an unkeyed decoding container and use custom decoding logic for dates and URLs.
Episode 116 · Aug 31 2018
We implement a custom XML decoder that allows us to decode responses from an XML API using Decodable.
Episode 115 · Aug 24 2018
We're using Swift's Mirror and Decodable APIs to generate database queries for structs in our Swift Talk backend project.
Episode 114 · Aug 17 2018
We return to the form library project and add several features to simplify common tasks.
Episode 113 · Aug 10 2018
We use Apple's new Network framework to simplify our own code.
Episode 112 · Aug 03 2018
We implement a JSON over TCP decoder to enable the debug client to receive data from the Mac app.
Episode 111 · Jul 27 2018
We create a class that encapsulates the complexities of sending data via an output stream.
Episode 110 · Jul 20 2018
We're building a remote view state debugger, starting with the networking code on the client.
Episode 109 · Jul 13 2018
In the last episode of this series, we factor out view code from the large view controller into a custom view class.
Episode 108 · Jul 06 2018
We use the child view controller we created last time to factor out more code from the large view controller.
Episode 107 · Jun 29 2018
We extract a child view controller to further slim down our large view controller, making sure the code keeps compiling throughout the process.
Episode 106 · Jun 22 2018
We refactor networking-related code out of the view controller, separating networking and data transformation logic from UI code in the process.
Episode 105 · Jun 15 2018
We extract Core Data-related code from the large view controller and move it into the model layer.
Episode 104 · Jun 08 2018
We begin refactoring a large view controller from the Wikipedia iOS app by pulling pieces of helper code out as pure functions.
Episode 103 · Jun 01 2018
After finishing the cleanup from the last episode, we refactor our forms API to be even more succinct and declarative.
Episode 102 · May 25 2018
We create helper functions for form cells and sections, which simplify managing references and propagating updates.
Episode 101 · May 18 2018
In our 100th episode we take questions from our viewers!
Episode 100 · May 12 2018
We extract reusable toggle switch and text field components from our forms code and do more cleaning up in the process.
Episode 99 · May 04 2018
After refactoring in past episodes, it's time for some housekeeping: we clean up our form code and make it more reusable with generics.
Episode 98 · Apr 27 2018
We refactor the form driver class to be reusable and define the entire form in a simple function.
Episode 97 · Apr 20 2018
We continue refactoring our forms code by creating a form table view controller as the first reusable component.
Episode 96 · Apr 13 2018
We begin to refactor the imperative table view code from the last episode, working toward a more declarative approach of defining our form.
Episode 95 · Apr 06 2018
This episode marks the beginning of a new series where we refactor a hand-coded settings form into a reusable, declarative form library. In this episode, we build the base version and discuss the design goals of the library.
Episode 94 · Mar 30 2018
We discuss many considerations and techniques for working with optionals.
Episode 93 · Mar 23 2018
We use Swift's pointer APIs to read a text file and split it into lines without using Swift's collection and string types.
Episode 92 · Mar 16 2018
We extend a basic Markdown library using protocol composition to add support for syntax highlighting in Swift code blocks.
Episode 91 · Mar 09 2018
We implement a concurrent version of the map method for arrays.
Episode 90 · Mar 02 2018
We show how protocol composition can be used to design extensible libraries, thereby solving the so-called "Expression Problem."
Episode 89 · Feb 23 2018
We discuss the capabilities and limitations of enums and classes when designing extensible libraries.
Episode 88 · Feb 16 2018
We continue implementing a mini player in the MVC variant of the sample app found in our App Architecture book.
Episode 87 · Feb 09 2018
We add a mini player to the MVC variant of the sample app found in our App Architecture book. We adjust our storyboard and discuss how to adapt the architecture.
Episode 86 · Feb 02 2018
We write a wrapper around the libgit2 C library to work with Git repositories from macOS and iOS apps — and for the fun of using Swift's pointer APIs!
Episode 85 · Jan 26 2018
Today we're releasing the early access edition of our new App Architecture book. We explain how it came about, what's in it, and how early access works.
Episode 84 · Jan 19 2018
We look at different techniques for wrapping analytics APIs in Swift and discuss their advantages and disadvantages.
Episode 83 · Jan 12 2018
We refactor a simple flow layout to have a functional interface, disentangling the layout code from UIKit code.
Episode 82 · Jan 05 2018
We use Xcode's memory debugger to resolve all the reference cycles in our glitch-free reactive code and introduce a proper ownership model.
Episode 81 · Dec 22 2017
We look at how to work with ranges in a mixed Swift String/NSString environment.
Episode 80 · Dec 15 2017
We benchmark the CSV parsing code from the previous episode and refactor it to become an order of magnitude faster.
Episode 79 · Dec 08 2017
We write a simple CSV parser as an example demonstrating how to work with Swift's String and Substring types.
Episode 78 · Dec 01 2017
We refactor the simple reactive library from the last episode using topological sorting to avoid any temporarily wrong values.
Episode 77 · Nov 24 2017
We look at an example of a reactive pipeline with surprising behavior, discuss why it occurs, and how it could be improved.
Episode 76 · Nov 17 2017
We clean up our layout code by introducing helper functions that leverage Swift's key paths.
Episode 75 · Nov 10 2017
We continue to expand our experimental view binding mechanism to implement dark mode in our app.
Episode 74 · Nov 03 2017
We experiment with reactive view bindings that don't rely on runtime programming.
Episode 73 · Oct 27 2017
We introduce a project we're going to work on over a few episodes. To get familiar with the code, we build a new feature using the app's view-state driven approach.
Episode 72 · Oct 20 2017
Brandon Kase joins us to show how Swift's type system can be leveraged to check file paths at compile time.
Episode 71 · Oct 13 2017
We use the reactive array type from episodes #67 and #69 to back a table view. This allows us to correctly animate changes in the underlying data, even with filter and sort transformations applied.
Episode 70 · Oct 06 2017
We build a reactive array type on top of the reactive list from episode #67 and implement a filter method.
Episode 69 · Sep 29 2017
We extend our Elm-style app with a more dynamic view hierarchy by adding a navigation controller and a table view.
Episode 68 · Sep 22 2017
We build a reactive linked list on top of reactive programming primitives. We implement a reduce method on this type, which does the minimum amount of work when the underlying data changes.
Episode 67 · Sep 15 2017
We refactor our reducer-based project from episode #62 to use The Elm Architecture. Instead of interacting with UIKit directly, we build a virtual view hierarchy and let our Elm framework do the rest.
Episode 66 · Sep 08 2017
We create a custom Quick Look extension to visualize binary tree structures in playgrounds.
Episode 65 · Sep 01 2017
We build a component similar to NSFetchedResultsController to decouple our view data and to drive table view animations.
Episode 64 · Aug 25 2017
We refine the observation capabilities of our new data type.
Episode 63 · Aug 18 2017
We show the reducer pattern to simplify state management and to make typical view controller code more testable.
Episode 62 · Aug 11 2017
We recap the tradeoffs between classes and structs and start implementation of our new type, leveraging Swift 4's keypaths.
Episode 61 · Aug 04 2017
We show some of our favorite new productivity features in Xcode 9.
Episode 60 · Jul 28 2017
We take a look at features like renaming, extracting expressions, extracting methods, and more.
Episode 59 · Jul 21 2017
Building on the binary search tree code from episode #56, we implement red-black trees as self-balancing tree data structures and benchmark their performance.
Episode 58 · Jul 14 2017
Today we're joined by Rob Napier, who explains why and how to add certificate pinning to your app.
Episode 57 · Jul 07 2017
We look at binary search trees as an alternative to last episode's sorted array implementation. We benchmark the performance of insertion and lookup in both data structures, with some surprising results.
Episode 56 · Jun 30 2017
Together with Károly, we improve our sorted array implementation using binary search. We benchmark both implementations to learn about their real-world performance.
Episode 55 · Jun 23 2017
We write a dedicated target-action to make it easier to augment existing UI controls with callbacks.
Episode 54 · Jun 16 2017
Lisa from Kickstarter shows us their test-driven development process to reactive programming.
Episode 53 · Jun 09 2017
Swift 4's new features lets us delete code we've written in previous episodes.
Episode 52 · Jun 02 2017
Brandon from Kickstarter demos how the company uses playgrounds to prototype and style individual view controllers.
Episode 51 · May 26 2017
We extend our libpq wrapper to handle queries with properly escaped parameters. To achieve this, we have to dive deep into Swift's unsafe pointer APIs.
Episode 50 · May 19 2017
Brandon from Kickstarter shows their approach of unifying all potential entry points into an iOS app using a common route enum, both in a simple demo implementaion and in their open source code base.
Episode 49 · May 12 2017
We implement a lightweight wrapper around the libpq C library.
Episode 48 · May 05 2017
Brandon from Kickstarter shows us how they write highly testable code with view models. We integrate Apple Pay payments and look at their open-source codebase.
Episode 47 · Apr 28 2017
We look at multiple ways to create variables that have a class type but also conform to a protocol.
Episode 46 · Apr 21 2017
We implement a type safe and Swift-like routing infrastructure that's pretty different from the common approach of most web frameworks.
Episode 45 · Apr 14 2017
We set up our development environment using the Swift package manager and Docker.
Episode 44 · Apr 07 2017
Instead of letting multiple view controllers manage the navigation bar's state individually, we pull this code out and unify the logic in one place.
Episode 43 · Mar 31 2017
We make our Signal implementation thread-safe by safeguarding the access to shared resources.
Episode 42 · Mar 24 2017
To conform IndexSet to the Collection protocol we implement a custom index type along the way.
Episode 41 · Mar 17 2017
We add the ability to map over signals and control subscriptions in a more fine-grained manner. Along the way, we improve the signal ownership model and implement the concept of disposables.
Episode 40 · Mar 10 2017
We extend the Future type of a previous episode to a simple reactive library. Along the way, we dive into debugging a reference cycle in our implementation.
Episode 39 · Mar 03 2017
Conforming to the Sequence protocol allows us to efficiently iterate over the elements, and we gain all of its useful functionality.
Episode 38 · Feb 24 2017
We build the basics for a custom index set collection type.
Episode 37 · Feb 17 2017
We implement a Futures type that we can use instead of callbacks as a first step towards a reactive library.
Episode 36 · Feb 10 2017
We build a sorted array type on top of Swift's native array and make it conform to the Collection protocol.
Episode 35 · Feb 03 2017
We take a look at how reactive programming challenges us to think differently.
Episode 34 · Jan 27 2017
We make our collection extension even more generic by implementing it on the Sequence protocol.
Episode 33 · Jan 20 2017
We show how to use the Collection protocol to make an extension available not just on array, but on all collections.
Episode 32 · Jan 13 2017
Mutating a nested untyped dictionary can be a challenge. To solve it we discuss the mutability of value types and the concept of l-values.
Episode 31 · Jan 06 2017
We talk about the importance of types and interfaces as tools to express your intent precisely and to set the proper boundaries.
Episode 30 · Dec 30 2016
We refactor a class hierarchy using a protocol and discuss the differences between both approaches.
Episode 29 · Dec 16 2016
We extend our notification wrapper from episode #27 and discuss an alternative protocol-based approach.
Episode 28 · Dec 09 2016
A lightweight generic wrapper around Foundation's notification API lets us avoid boilerplate code and provides a type-safe API.
Episode 27 · Dec 02 2016
We build a generic, type-safe table view controller that can handle multiple cell classes.
Episode 26 · Nov 25 2016
We add support for caching network requests without altering our original networking abstraction.
Episode 25 · Nov 18 2016
We discuss the pros and cons of delegates versus callback functions and why delegate protocols are always class only.
Episode 24 · Nov 11 2016
We talk about a familiar but surprisingly tricky problem: splitting an array into groups of elements. We discuss the pros and cons of our own solutions along with the solutions people sent us via Twitter!
Episode 23 · Nov 04 2016
We show how we build simple command line tools leveraging the Cocoa frameworks. We use the Swift Package manager to include dependencies in our project.
Episode 22 · Oct 28 2016
We can change structs by mutation, functional chaining, and inout parameters. We discuss how they differ at the call site and why they’re all equivalent.
Episode 21 · Oct 21 2016
We use copy-on-write to write an efficient struct wrapper around NSMutableData and discuss how the standard library uses the same approach.
Episode 20 · Oct 14 2016
We build a flexible sort descriptor abstraction on top of Swift's native sort methods, which is dynamic and type safe.
Episode 19 · Oct 07 2016
We leverage the existing infrastructure of our app to add a search field with very little code.
Episode 18 · Sep 30 2016
We connect multiple view controllers using a coordinator and callback functions. We simplify the control flow by refactoring the UI state into its own struct.
Episode 17 · Sep 23 2016
We implement some of the more challenging parts of parser combinators.
Episode 16 · Sep 16 2016
Join us in the functional programming gym to stretch your object-oriented comfort zone while we lay the groundwork for a parser combinator library.
Episode 15 · Sep 09 2016
We build a tree structure from an array of Ledger account names. We first implement the tree using a class, and then we refactor it to a struct and discuss the differences and tradeoffs involved.
Episode 14 · Sep 02 2016
We look at two different techniques to parse a simple expression language: handwritten parsers and parser combinators.
Episode 13 · Aug 26 2016
Writing the code for evaluating transactions required continuous refactoring to keep our code simple and clean.
Episode 12 · Aug 19 2016
Expressions are at the heart of Ledger. We write an evaluator for this expression language in a test-driven way.
Episode 11 · Aug 12 2016
We give a quick introduction to Ledger itself and to the Mac app we're going to build.
Episode 10 · Aug 12 2016
In this episode, we answer some of the questions we've received over the past few weeks. We cover networking, table views, stack views, our App class, and testing.
Episode 9 · Aug 05 2016
We add POST support to a simple networking layer, using Swift's enums with associated values and generics.
Episode 8 · Jul 29 2016
We create an abstraction around stack views using enums to specify UI elements in a declarative style.
Episode 7 · Jul 22 2016
We leverage Swift's generics to keep our table view controller code clean.
Episode 6 · Jul 15 2016
We refactor our code by moving the app's flow from the storyboard into a separate coordinator class. This avoids view controllers having implicit knowledge of their context.
Episode 5 · Jul 08 2016
We add customizable styles to our CommonMark renderer from episode #2.
Episode 4 · Jul 01 2016
We explore different approaches to factor out asynchronous loading code from view controllers, using protocols, container view controllers, and generics.
Episode 3 · Jun 24 2016
We create attributed strings from CommonMark. We continually refactor our code to make the central logic short and understandable.
Episode 2 · Jun 17 2016
We make use of Swift's generics and structs to build a simple network layer with great testability.
Episode 1 · Jun 17 2016