Functional programming might be a strange beast for seasoned Cocoa veterans. It is a completely different approach to what’s contained in Apple code samples. It requires practice to structure the code in a functional way, but it has some very nice benefits attached to it:

So, what is functional programming?

Our little fella, provided a current date, can give us a recipe to say whether another date is in future or not. It has a pretty odd signature, though. How should we use it? Let’s have a test case to illustrate how to call the function:

We are not used to call functions this way in object-oriented world. Instead of calling the function twice passing single date each time we would just pass 2 arguments directly. What's the difference?

Function composition

Functional programming is all about processing the data using a set of very small composable units. Having a (Date) -> (Date) -> Boolsignature would not make any sense, if we already had a date and would like to check whether it is in future or not. But instead, let’s imagine that all we have is a timestamp.

Looking at the signatures, the output type from the 1st function matches the input type on a 2nd function which means we could chain them together to get our desired (TimeInterval) -> Boolsignature.

Such chaining is called composition and it’s a universal maths law. Given 2 functions with matching output to input type, we can always compose them into a function that goes from the 1st function input to 2nd function output:

Having composed the new function, we can now answer our original question. What benefit did (Date) -> (Date) -> Boolshape of isInFuturefunction had?

It turns out that it enabled us to separate configuration from the processed data. It’s a functional analogy to the dependency injection pattern. In our case, the current date was just a configuration that we could partially apply and answer the question: is the input date in future from now:

let isInFutureFromNow: (Date) -> Bool = isInFuture(Date())

Meanwhile the second Dateargument was an actual data that we have been processing. Different dates would yield us different results with the same configuration.

Operator composition

Having to type:

comp(Date.init(timeIntervalSince1970:), isInFuture(Date()))

to compose 2 functions might not be particularly convenient. First, we have a lot of brackets to scan through with our eyes. It’s hard to visually pair the last closing bracket with the opening one located near the comp function name. Second, splitting the code into multiple lines does not make it very beautiful either:

The composition reads very nice right now. Composed parts are visually distinct. Splitting the composition into separate lines looks very nice.

Composing model transformations

That’s a lot of words already and you might be wondering:

Why should I even bother?

That’s a valid question! So far we have only defined isInFuture function that’s very straightforward. We’ve also composed another one (isFutureTimestamp) that’s not too complicated either. At best we could do the following:

Let’s rebuild the code into free functions for more composability and testability. We will start the analysis from the innermost bracket - !isInFuture(now)($0). It turns out it’s very simple to negate a function using the function composition operator:

let isNotInFuture: (Date) -> Bool = isInFuture(now) >>> (!)

! operator is just a function with (Bool) -> Bool signature and we are free to compose it.

Now, we’ll analyse the inner filter part in which we determine whether a product is expired or not. First, let’s build a function that can extract a value from any object given a key path:

reusing our isInFuture function and also boosting our confidence in unit tests along the way.

The final step is to re-run our initial tests and prove that everything is still green after the refactoring. Hooray!

Conclusions

In this post we’ve proven that it’s possible to build a complex data transformation using free, generic & very small composable methods. Thanks to the function composition we can boost the test confidence, remove the boilerplate coming from chaining some operators[1] and drop unnamed $0 arguments referring to different data types on every nest level. Function composition also helped us reuse the already defined functions (like isInFuture) beyond what seemed readable without it.

Credits

The post is inspired by the great content available at pointfree.co. Brandon & Stephen are doing a great job. Don't hesitate, subscribe yourself & unleash the functional beast!

See how we had to wrap the whole filter body in brackets due to the! operator. ↩︎

UICollectionView is one of the most flexible and powerful, but also mysterious and tricky components in UIKit toolbelt. I've learned it the hard way when trying to build a simple, Facebook-like feed. Today, I'll share my lessons learned and show how to do it yourself with as little overhead as possible.

The feed has following requirements:

It should scroll smoothly.

It has to nicely animate updates.

It needs to support pagination when fetching data from the API.

The outcome looks as follows:

The fully implemented feed with animated updates and pagination

Collection view is a natural candidate for that kind of requirements. It implements reusing components for maximum performance and it can animate the updates nicely.

Note: although the tutorial relies on RxCocoa and RxSwift, it should still be valuable for all non-reactive folks out there.

Building blocks

The feed does not require building a custom collection view layout. UICollectionViewFlowLayout does all the heavy work to handle it perfectly.

UICollectionView supports batch updates. It allows to animate the changes to the data source, like adding or removing items, with ease. Let's see how it looks in practice:

UICollectionView batch updates

Since the feed screen is endlessly paginated, the animations will come in very handy to add new items on the fly. However, unlike in the demo presented above, the feed items are certainly not of the same size:

the bottom text has a variable length and it is wrapped to fit the cell size,

the header might be different depending on author's name length.

Fortunately, UICollectionView supports the self-sizing cells. It's as easy as implementing size-constrained UICollectionViewCell and setting the estimatedItemSize property on the UICollectionViewFlowLayout. The outcome might look like this:

Self-sizing cells on UICollectionView

The problem

The tricky part comes when combining the animated updates together with self-sizing cells. Let's try it ourselves:

Animating self-sizing cells on UICollectionView looks really bad

It looks really bad. What's more, when collection view is scrolled down the content offset messes up during the animation, too. It results in badly looking jump when adding new items.

The slow animations mode comes in very handy to figure out what's wrong:

Animating self-sizing cells does not use their auto-calculated sizes

It turns out that during the animation UICollectionViewFlowLayoutforgets previously calculated sizes of the cells and reverts to whatever is set as estimatedItemSize. This took me quite a while to figure out, but I've learned that there's a pending radar opened since iOS 8 that's still not fixed.

A quick workaround for the issue is to manually calculate and cache the sizes. It's sounds complicated, but is way easier than one can think. Especially when there's only a single cell type in play.

First, we'll need a cell view. The one presented in animations above is a simple label embedded in a content view:

We need to derive from UICollectionViewDelegateFlowLayout and implement a method to calculate each item size (collectionView(_:layout:sizeForItemAt:)).

The complete cell presentation code is extracted to a private method and reused between cell creation and size calculation.

A single cell instance is stored that's not for reusing. It's used to calculate item size and is created lazily (lazy var layoutCell = FeedCell(frame: .zero) ) to make sure we don't have to deal with optionals.

We're caching cell sizes in a dictionary (var items: [Int: CGSize]) that maps item identifier to a size of a cell. This way, we need to calculate the size only once per every identifier.

We're using systemLayoutSizeFitting(UILayoutFittingCompressedSize) method to determine the cell size from auto-layout.

For the tutorial purposes this will generate fake data with randomized delay, but the interface would likely not change when used with production API.

Now, let's figure out how to create a data source for UICollectionView. We want the changes to be animated, including removing, updating and adding the items. If we were to implement it without 3rd party components, every time the update comes we would need to calculate the diff between previous array of items and the updated one. Having the diff calculated, we could invoke performBatchUpdates calling the suitable update methods manually.

Defining the data source

Fortunately, there's a great tool called RxDataSourceswhich greatly simplifies the task. Provided you have a model that is:

identifiable (has unique, hashable identifier),

equatable (can determine whether the item has changed)

RxDataSources can animate the changes for you. Let's modify the FeedItem slightly to meet the criteria:

Swift 4.1 can generate Equatable conformance automatically, so there's only a tiny amount of overhead to make the model RxDataSources-compatible.

Next, we'll bind the model to a collection view. In order to do so, we need to create an instance of RxCollectionViewSectionedAnimatedDataSource, which works kinda like UICollectionViewDataSource. It specifies how to configure the cells based on the model.

Notice that RxCollectionViewSectionedAnimatedDataSource is generalised with an odd generic type AnimatableSectionModel<String, FeedItem>. The data source can also animate section updates, that's why it needs to operate on a section model, not an item model. We won't use it in a single section tutorial, but it's mandatory to satisfy the data sources API.

The quickest way to work around that is to use predefined AnimatableSectionModel which requires us to specify:

The section model that needs to be identifiable. It's straightforward to use it in a conjunction with a simple value type like a string, integer or floating point because those conform to IdentifiableType in RxDataSources by default. I've picked the string type for the sake of the example.

It's worth noting how FeedCell exposes a constraint which describes the width of the content view. It could also be constrained inside a cell using UIScreen.main.bounds.width, but it's less flexible and won't allow us to change interface orientation in future. Also, you can see that images in the example are downloaded using AlamofireImage dependency.

Hence we use a constant data source for now, it's not too flashy yet. But a cute fade in animation can already be seen when items first appear in a collection view.

The empty string used as a model for the section doesn't matter at this point. We're using a single section that won't be updated, so it can be an arbitrary string.

Building the pagination

Pagination is a tricky problem to solve in reactive world. It's a very stateful piece of code that's hard to describe as a combination of event streams. The recommended way to implement a pagination by RxSwift author is to use another dependency called RxFeedback.

RxFeedback is a simplistic architecture based on RxSwift library. It consists of:

state - a structure that describes current state of the system,

mutations - formal description of events that can modify the state,

feedback loops - mapping between state updates and mutations.

We can also try to describe them in type system notation:

struct State { // ... data } - fields represent the current state of the system.

First, we need to describe a state of our pagination subsystem. We need to store fetched items, an index of the next page and a flag to indicate whether we should already trigger the next page loading:

UI feedback consists of data bindings (used for presentation) and events invoked by user interactions. First, let's cover the presentation. We'll use the RxCollectionViewAnimatedDataSource defined earlier to bind the state items to a collection view:

Using the react method, we specify that each occurrence of loadPageIndex value in the state should fetch the page at returned index. If page is successfully loaded, .pageLoaded signal is emitted. If error happens, we emit the .error event.

Having the feedback loops defined, the last missing part is to glue everything together using Driver.system method:

Conclusion

That's it! Using a set of 3rd parties built on top of RxSwift, we've managed to implement a performant feed with animated updates with as little code as possible. The complete source for the tutorial is hosted at turekj/RxFeedExample GitHub. Happy feeding!

Imperative shell, functional core is one of the concepts that influenced my programming career the most. It perfectly formulates how to write clean, easily testable code and always keeps you wondering whether you did enough to extract the functional pieces.

During my preparations for the Mobile Warsaw #62 talk I was looking for a really concise and powerful example of applying the technique to refactoring an existing code and simplifying the tests. After long hours of wandering I finally came across a great example. And oh, boys! How ironic that I found the example in the code of mine.

Disclaimer: the article implies that you are familiar with imperative shell, functional core concept. If not, please do not hesitate and watch this great Gary Bernhardt's talk named Boundaries. Although the strategy is applied in Ruby, it should be accessible enough for an iOS developer. In case it is not, there are also some other resources listed in the end of the article.

The problem

The code in question is a simple UIScrollView delegate that snaps user scroll to pages:

The pages are indicated with distinct background colors. When the view is no longer dragged, it stops scrolling at the nearest page. You can tell that the scroll view never stops in between the pages.

In order to do so you need to implement the following method of UIScrollViewDelegate:

The idea is that a value under the pointer passed as an argument indicates the scrolling stoppage point. You can alter the stoppage point by mutating the pointee's value. This means the code above will make the scrolling stop at 100pts no matter what.

Original implementation

My original implementation was divided into two parts. First, the delegate object:

The argument of the ScrollPosition type indicates which page (relative to the UIScrollView viewport) we should scroll to. It can be located either on the left, on the right or in the middle of the scroll view.

enum SnapPosition {
case left
case center
case right
}

The second piece is an extension on the UIScrollView class that does all the necessary maths:

The code is neither really good or very bad. It is separated into a bunch of short methods with descriptive names, so it was okay enough to pass the review. However, it violates imperative shell, functional core design. To prove that, let's throw a bunch of unit tests for the delegate:

Despite introducing a new dependency, we do not have to stub it at all. Since the calculator is purely functional, it also executes really fast and is 100% deterministic.

Summary

Imperative shell, functional core proved to be a really effective technique for structuring a short codebase behind a snapping scroll view. However, the benefits of using it are way superior when applied to a system-wide problems like routing or presenting modal controllers.

Imperative shell, functional core should be viewed as one of the most important patterns for writing clean, testable code, right next to the likes of SOLID and dependency injection.

Do not forget to isolate the business logic and never let it mix up with a stateful world! 🔥

Recently, I came across a couple of real-world examples that illustrate functional programming usage in Swift. All those examples have a single thing in common - they have been initially written in an imperative manner, which made them harder to read and extend.

The article provides an in-depth description of the use cases, shows the process of transitioning from an imperative to a functional paradigm and highlights the benefits of using functional programming tools.

Human readable strings

Building human readable strings is a perfect real-life use case for functional programming. This is also one of the most painful to overlook. Suppose we have a User model defined as:

Our goal is to build a human-readable string in a Name Surname, "Nickname" format. The example output would be Jakub Turek, "Brogrammer". It seems to be trivial at first, but there are a couple of challenges:

Each of the components can possibly be nil.

Each of the components can possibly be a blank string.

Nickname must be wrapped inside double quotes.

There are 8 different formatting permutations in total. It is easy to miss a couple of them when implementing a formatter by hand:

To make it easier to understand, we will examine all of the functional calls separately:

The flatMap method invokes a closure on every element of the array. The closure transforms a value to another (possibly nil) value. The result is the array containing transformed, non-nil values. In the example above no transformation is applied, which means that the flatMap will:

Filter out all the nil values.

Promote the array type from Array<String?> (input) to Array<String> (output).

The filter method invokes a closure on every element of the array. The closure takes an element and returns a boolean value indicating whether the element should be a part of a resulting list or not. In the example above filter { !$0.isEmpty } will drop empty strings from the array.

The joined method creates a string out of the array, joining all of the elements with given separator string.

Comparing a naive implementation using if-else statements with the functional approach:

Functional approach is less error-prone. It is harder to omit a formatting case.

Functional approach is way more extensible. Imagine adding an optional middle name field to the user structure. To get the Jakub Jan Turek, "Brogrammer" output one would have to:

Add 8 additional if statements for the naive approach.

Add a new element to an array in fullName property for the functional approach.

Functional approach requires knowledge about a couple of built-in functions: two versions of flatMap, filter and also joined. It is not obvious, nor natural for functional programming beginners.

Processing data

Functional programming is great for processing data contained in structures meant for presentation and/or storage. Recently, I have been reviewing a piece of code that extracts a bounding box from a sequence of MKPolygons:

Upon closer examination, it is clear what coordinatesRange method does. However, the classic imperative approach was not in my taste:

There are four optional variables defined: minLatitude, maxLatitude, minLongitude, maxLongitude. The code does not express they are tightly coupled to the same CoordinatesRange domain model instance.

If one of the four variables is nil while the others have values assigned, this is a developers mistake. The code should crash immediately. Such condition is allowed, but not asserted.

There is a lot of juggling with the optionals. Especially the quadruple if let assignment is not pleasant to read.

The are two exit paths to test (separate return statements) for the property.

Can we do any better? The code iterates over a two-dimensional array and calculates a single value based on that. There is a functional programming method called reduce that does exactly that.

reduce takes a closure that is applied to every element of the array. The closure accumulates partial result and the element into a new partial result. It might sound complicated, so let's see how one can add up a couple of integers using reduce:

The initial value passed to reduce method is 0. The reduce method takes the initial value and the first element of the array and adds them up. Then, it takes the result and adds it to the second element. And so on...

Back to the polygons example, we have identified that we reduce an array to a single value. But what is getting reduced? Our goal is to calculate the bounding box for the coordinates contained inside polygons. For a single coordinate we instantly know its bounding box:

What is interesting about this approach is how a nested array of coordinates is transformed into a single-dimensional array of CoordinatesRange:

For every polygon, the coordinates property is mapped with CoordinatesRange initializer that takes a CLLocationCoordinate2D as an argument. This returns [CoordinatesRange] array for a single polygon.

The flatMap method is called on a whole sequence of polygons. This is yet another implementation of flatMap method. It is accessible for sequences only and it accepts a closure that takes a single element and transforms it into a sequence. All of the sequences that are returned by transformations are merged into a single resulting sequence. You may also know this operation by the name of flattening an array.

We operate on a domain model only. There is no way to build incorrect partial outputs by mistake and silently ignore it.

There are almost no optionals left. There is a single quotation mark and no if let unwrapping, compared to four quotation marks, four conditional let statements and four ?? optional variable substitutions. What is more, although the result variable inside closure is optional, it is guaranteed to have a value if the closure gets called.

There is only a single exit point from the method.

Grouping

Another use case for reduce method is grouping. Let's suppose we are building an index for a table view. For the sake of example, we will use User structure previously defined in the Human readable strings section. Let's assume that we need to group users by the first character of a surname.

First, let's define a computed variable for the User structure that returns a group name. The grouping key should be either a first, uppercased letter of the surname (if the surname begins with a letter) or #.

Now, let's implement the grouping function. It will receive a single argument - partitioning method - that takes a sequence element and returns generic partition code that conforms to Hashable protocol. The grouping function will return a dictionary where a key is the output of partitioning method and a value is the list of objects with the same partition key.

The partition method uses reduce to convert a sequence into a grouped dictionary. For every element of a sequence, it computes a partition key, fetches elements for that key and appends current item. Let's see partition method in action:

Summary

The article presented a few use cases of functional programming in Swift. It proves how useful functional programming is for everyday development. It also shows that for certain use cases functional programming can greatly improve code readability and quality.

I hope that one day we can see a much wider application of functional paradigm pattern for iOS development.

Continuous delivery is a key to a healthy communication with your customer. However, it is not a common practice for iOS developers to set up a continuous delivery pipeline. It is likely caused by the inferior tooling provided by the Apple itself.

This tutorial aims to present a painless way to set up the continuous delivery for your project. It also describes common pitfalls encountered during the process and how to avoid them.

The tutorial is based on a continuous delivery implementation for EL Debate open source project. In case anything goes wrong, you can always check out the sources and see for yourself. 😊

The goals

The aim of this tutorial is to have a new version of the application uploaded to TestFlight beta every time pull request is merged into a master branch of the git repository.

Since we always merge pull requests through Github, the tutorial takes a significant shortcut. The merges are detected by Merge pull request #{no.} from #{branch} pattern lookup in the last commit message.

Prerequisites

Following preliminary steps are required to follow the tutorial:

Github repository containing project's sources.

Travis CI integration configured to build the project on every branch push. The simplest .travis.yml will suffice.

Bundler should be installed on your machine. Just run gem install bundler command.

Unfortunately, at the time of writing the article you cannot enable two-factor authentication on the Apple Developer's account. There is an unresolved issue that prevents using it on Travis CI specifically. If it was fixed, you would have to set two additional environment variables to usie two-factor authentication:

Creates encoded .autodeployment.sh.enc file that you can safely commit to the repository.

Adds a new before_install step to your .travis.yml that decrypts the file contents before running actual build.

Define two additional before_install steps in .travis.yml:

- chmod +x .autodeployment.sh
- . ./.autodeployment.sh

The steps must be preceded by decrypting the script file.

The script execution command (./.autodeployment.sh) is prefixed with additional .. It sources the script, executing all the instructions in the same shell as the command itself. Otherwise, the script would be executed in a child process and the export results would not be visible to the Travis shell.

Let's break down what .autodeployment.sh script does:

It modifies SSH configuration by appending two lines to ~/.ssh/config:

Host *
StrictHostKeyChecking no

This disables an interactive prompt that asks to add server fingerprint to known_hosts. If you have ever used SSH, you have probably seen this prompt:

The authenticity of host '192.168.0.169 (192.168.0.169)' can't be established.
ECDSA key fingerprint is 74:39:3b:09:43:57:ea:fb:12:18:45:0e:c6:55:bf:58.
Are you sure you want to continue connecting (yes/no)?

It needs to be disabled in order to perform a SSH git clone in a non-interactive environment such as Travis CI. This is exactly what StrictHostKeyChecking no takes care of.

It copies private (id_rsa) and public (id_rsa.pub) keys used to authenticate to match repository. You need to paste in the actual key contents that you have generated when setting up the Github account earlier.

It adds the key to SSH agent (ssh-add ~/.ssh/id_rsa).

It sets up the credentials used by fastlane to access Apple Developer Center. Those are exported FASTLANE_USER and FASTLANE_PASSWORD environment variables.

It sets up the credentials to download certificates from match repository (MATCH_PASSWORD variable).

Why not provide environment variables directly?

Instead of exporting environment variables in a script file I could simply define them in Travis build settings. I like this approach better. However, Travis has a length limit of 128 bytes per variable and also requires variables to be bash-escaped for double quote input. After encountering those issues on a couple of occasions, I decided to go with the script approach instead.

Creating auto deployment lane

Having all the secrets in place, we can proceed to creating a fastlane script for auto deployment. Let's start by invoking fastlane init command in the project root directory. After answering a couple of simple questions, the script will generate the Fastfile located under fastlane directory.

As described in the goals section, we want the script that is executed only upon merging a pull request. Fastlane does not provide such a check out of the box. Fortunately, it is really easy to implement this action by hand. Let's create a new action by calling fastlane new_action and call it merges_pull_request. Now, open fastlane/actions/merges_pull_request.rb file and paste in following contents:

No one likes to be blamed for the mistakes. This is especially true for software engineers. Over the years they came up with countless ideas which make software development less fragile and error-prone. It is safe to say that ever growing number of precaution steps taken to maximize the quality of the product is what defines the best developers in the business.

In today's article, I will share a great and relatively easy way to verify whether an app works and looks as expected from the end user's perspective. We will learn how to automatically prove that all the features work and that the app's looks were not broken during the development.

Motivation

Let's try to answer an example question to show what UI testing is and what are the motivations behind it.

Do we really need UI tests? If so, why? We already have unit tests...

UI testing serves a completely different purpose than unit testing. UI testing focuses heavily on the end-user. It verifies that the presentation is correct and that app's features are reachable and render correct output.

In comparison, unit testing focuses solely on what is visible to developers. It aims to prove that small chunks of source code work as intended and also verify whether their API is good enough. This means that unit and UI tests are complementary, not mutually exclusive.

Unfortunately, UI tests are commonly downplayed compared to unit tests[1] due to several reasons:

They have a significantly slower feedback loop.

They might not be 100% reliable. UI testing is commonly considered to be fragile and associated with a lot of false positives.

UI tests are viewed as painful to implement (cumbersome and repetitive code).

With that many issues, is UI testing even worth considering?

In my opinion, yes. UI testing is critical in customer-facing environments, which mobile apps market certainly represents. All in all, UI testing proves that the application works from your prospect's perspective.

Fortunately for us, iOS devs, UI testing is completely different from what it used to be. During the last couple of months, a lot of great 3rd party tools emerged that make UI testing fun. This article will briefly explore these tools and show how to use them for maximum productivity.

Xcode's UI testing

XCUITest is a black-box testing utility. This means there is no way to communicate with application sources during testing. XCUITest requires creating a separate testing target. It exposes a special set of APIs dedicated for querying UI elements. Example test might look as follows:

Moreover, XCUITest offers test recording utility, which is a code generator based on user interactions. The feature works quite nicely, but it lacks the ability to specify assertions.

Unfortunately, XCUITest has a couple of really serious pain points:

Every asynchronous action has to be verified using expectations (as shown in the example code). The testing code explicitly waits for a condition to be met with a specified timeout. This approach has some serious issues:

writing cumbersome code using aging, string-based predicates API,

too short timeouts may cause unexpected failures,

further changes to source code (like chaining more asynchronous actions or converting a synchronous action to an asynchronous one) may break the test when it shouldn't.

There is no easy way to inject a test specific behavior. Let's suppose you need to display some specific UI elements for French users only. How do you inject French data? You need to pass launch arguments and parse them inside main application source code.

The tests seem to be really slow. Two separate app containers are deployed to a simulator:

the main application,

the test application that executes automated script on the main application.

Deployment takes time, the app switching takes time and the navigation state is lost between tests.

There is no way to assert view layouts.

The issues listed above make XCUITest completely unsuitable for writing lightweight, maintainable UI tests during the development process.

Fortunately, testing the views' layout is easier than you might think. It can be done in no time with the help of snapshot tests.

Snapshot testing

Snapshot testing is a technique in which two rendered views are compared pixel by pixel. The test fails if an examined snapshot differs from the reference one.

Secondly, the developer asks framework to take a reference snapshot of the view.

From now on, every test pass validates a target view against the reference image.

The easiest option to get snapshot testing for iOS applications is to use FBSnapshotTestCase. When using Cocoapods, integrating the framework is as easy as adding a single dependency to the test target:

Notice how we define recordMode = true to create a reference image. If we run the tests now, they will fail:

As error message states, this is the expected behavior. We should disable the recording now. This can be done by setting recordMode = false. The tests will pass now.

If at any point in the future the view gets broken:

unit tests will fail,

an image containing the visual diff will be generated for you.

The image is especially useful when trying to figure out what went wrong. Let's see the example:

On the left-hand side, the expected view is presented. On the right-hand side - received view. In the middle, there is a visual diff between the two.

Reference images are an integral part of the snapshot test. It means that you have to commit them to the repository alongside the test sources.

Device agnostic snapshots

As you might have noticed, in our snapshot test we have set view's frame to screen size using:

viewController.view.frame = UIScreen.main.bounds

Obviously, such test will fail when executed on a device with different point screen size and/or pixel per point density. To fix that issue, you can tell FBSnapshotTestCase to record device agnostic snapshots. This means that the library will record and verify a single snapshot per <test, device type> pair.

To use device agnostic snapshots, simply add isDeviceAgnostic = true line to the setUp method of the snapshot test case:

After recording the initial snapshot the test passes. But what does it check? The question can be answered by examining ReferenceImages directory:

Obviously, the snapshot test doesn't assert too much. It only tests initial layout, completely ignoring the animation. No matter how badly the animation gets screwed, the test is guaranteed to pass.

The brute force approach to fixing this problem is to change the view controller's API. We could either introduce the method that skips the animation or that invokes a completion block when the animation is finished. However, adding a new feature that is used only for testing purposes is not the brightest idea.

Functional tests

To assert the animations' results without modifying sources, a functional testing framework can be used. Having already eliminated XCUITest as a not viable option, I had to browse through available third parties. The one that really stands out for me is EarlGrey - the red-hot iOS UI testing framework from Google. What makes it different than other functional testing frameworks is the approach:

White-box testing. By allowing to interact with the application code, one can use stubbing and mocking to prove correctness.

No time-based and condition-based wait clauses. EarlGrey automatically synchronizes with network calls, animations, operation queues and delayed dispatches so that it can automatically detect a stable view state.

Quick start with EarlGrey is covered in installation & running docs, so I will omit the setup and jump straight to the testing code. Let's analize the colors example again:

Step zero is to make cells with animated colors distinguishable. We'll map their names to Animated {colorName}.

Our goal is to write a test that triggers the Animated Cyan cell tap, waits for the animation to complete and asserts whether Animation has finished label is visible:

.using(searchAction: grey_scrollInDirection(.down, 50.0), onElementWithMatcher: grey_kindOfClass(UITableView.self)) - since we look for a cell inside the table view, we might need to scroll down to find it. The clause tells EarlGrey to search the given UI element by scrolling down the first table view that can be found on the screen.

.perform(grey_tap()) - invokes tap action on the matched element.

.assert(grey_sufficientlyVisible()) - make sure that the element is visible. This call might seem useless, but calling .assert activates synchronization chain. We want this behavior, because we want to synchronize on next animation finished event.

Here is where the EarlGrey magic happens. Upon the tap:

A new view controller is pushed onto the navigation stack.

The animation is triggered.

Using typical UI testing framework, you would have to manually implement expect/wait combo that asserts Animation has finished text has appeared. EarlGrey automatically delays the matching until a target view is in a stable state. This means that the check:

will fire as soon as (but not until) the transition and the animation are finished, regardless of how much time it takes. The framework automatically takes over when the animations are finished, so there is no time delay for sleep/polling.

Snapshot interaction testing

Up to this point, we have proven that the label is shown as a sign of animation being completed. But we still can't be sure whether the animated view looks exactly as expected. Is the rectangle visible? Does it have a correct shape? What is its background color?

Essentially, we are back to a problem that we have already solved with snapshots. Although EarlGrey has a built-in view snapshot feature, it is not something we can reuse easily. In order to do that, one would have to reimplement FBSnapshotTestCase's snapshot comparison logic.

Wouldn't it be amazing if we could somehow join FBSnapshotTest and EarlGrey together? I have got a great news for you! I have implemented a set of EarlGrey assertions which does that precisely. It is called EarlGreySnapshots.

From now on, the code asserts if AnimatedRectangleView passes the snapshot test. Let's double check whether the reference image is truly produced in a stable post-animation state:

It is clear that the view state after the animation is asserted now.

Further considerations

EarlGrey together with EarlGreySnapshots can handle a plethora of scenarios that were not covered in this example post:

User-interactions: taps, long presses, swipes, pinches and so on.

Network calls (for integration testing).

Delayed actions/operations triggered by NSOperationQueue or by using dispatchAfter.

It is a great toolset to enforce correct behavior of the app. As opposed to traditional tooling, it is much easier to use and way less cumbersome to write:

You'll never have to worry again about asserting against multiple properties of numerous subviews in the same stable state.

There is no need to assign dummy accessibility labels[3] or setting the application up for UI testing in any special way.

The tests does not rely on volatile expect conditions and are much harder to break.

You can easily prove that your UI edge case handling hasn't broken.

I really recommend you to check it out now! 😉

It is worth noting that even though unit tests are undoubtedly more popular than UI tests, they are often overlooked themselves. ↩︎

Unfortunately, this also means that doing TDD routine is not possible with snapshot testing. ↩︎

Although you should definitely try to assign meaningful accessibility labels for visually impaired users. ↩︎

]]>As you might already know, I deliberately chose not to use storyboards for my Swift code. Instead, I build all of the views programmatically and inject them through initializers into suitable controllers. Although this approach works really nice, it has drawbacks when it comes to unit testing.

As you might already know, I deliberately chose not to use storyboards for my Swift code. Instead, I build all of the views programmatically and inject them through initializers into suitable controllers. Although this approach works really nice, it has drawbacks when it comes to unit testing.

Imagine having a user profile view implemented in vanilla UIKit. A really basic one: a picture, a full name label, a single text view for some notes and a switch which manages notification settings. Does it sound complicated? Not at all. Now, add a label for every field and layout fields vertically. You will get UserPictureView, UserNameView, UserNotesView and UserNotificationsView classes. Each one will get at least two dependencies: field's label and control (view) to manage the actual data. All of them will be grouped together in a parent view which, in turn, will be framed inside a scroll view.

The view (let's call it UserProfileView) is still pretty basic, but the number of lines of code needed to initialize it has grown rapidly. The top of the view controller's test case is occupied by dependency initialization and you have to scroll down to see the actual test definitions. Here are a couple ideas to fix that:

Refactor to a helper view class with all the dependencies pre-initialized.

Quit using initializer injection for views and make them aware of the initialization code.

Import & attach view's factory method from the target app.

None of the presented solutions is good. First of all, they require building a full view to test a view controller. Moreover, the first one violates DRY[1] (the helper class is almost the same as a full view created by a factory method) and the second one is against SRP[2] (view manages both initialization and layout). There must be a better solution...

View controller awareness

To find out a root cause of our problem, let's take a few steps back to the example mentioned in the introduction:

Despite using the same set of subviews in both cases, the latter is much more manageable. Only meaningful views that carry business logic behaviours are published in the interface. Let's try to do the same for a programmatically built view:

That is an interesting effort. It has all the benefits of the storyboard approach. Moreover, it says no to optional chaining dance and is nicely separated as a dependency, not cluttering UIViewController itself. The problem is that it is not explicitly a UIView, so it cannot be assigned to a var view: UIView directly. Let's try to come up with a work-around:

That is a terrible design. We have specified that UserProfileViewController relies on UserProfileViewType dependency, but the implementation secretly expects it to be a UIView subclass. This should never be the case in a real codebase.

Since UserProfileViewType provides the UserProfileViewController with meaningful subviews, what prevents it from delivering the whole view? Absolutely nothing. Let's rename it to UserProfileViewProvider then!

The trick with that design is that we erase the concrete UIView type. We made UserProfileViewController aware of the fact that there is a view to manage, which provides five meaningful subviews. The controller does not know (and does not care) how the view is built and what is the layout.

The biggest win in that architecture is testability. Unless subview-related business logic (?) needs to be tested, the stub is so easy to build:

Despite being a really lightweight implementation, UserProfileViewProviderMock allows testing behaviours the same way a full instance of UserProfileView would.

Flow controller / coordinator pattern

Providers play nicely with UIViewControllers too. Imagine the app is using flow controller or coordinators architecture. The flow controller's responsibility is to resolve a full instance of a view controller, configure it and push onto the navigation stack. It works seamlessly with storyboards because the storyboards are like factories of UIViewControllers. Unfortunately, it is not the case when manually building view controllers. The flow controller has to rely on a factory method which returns a complete instance of a concrete view controller. Again, this is not that great for the sake of unit tests.

Fortunately, you can define a provider for a UIViewController like this:

Now, the view controller has even less information about the view's implementation. It expects a single component that can publish and receive text updates, but it does not know whether it is a UITextField or UITextView. With such an approach it is possible to write unit tests for controllers without creating UIKit controls at all!

Summary

Providers are like the adapters designed specifically to wrap around UIKit library. They allow to "type-erase" views or view controllers to make them easily instantiable in unit tests. Personally, I find this is the clearest approach to testing controllers (and flow controllers) I have come up with so far. You should definitely check providers out!

]]>Functional reactive programming (FRP) is probably the hottest 🔥 topic in mobile apps development world right now. GitHub trending repositories list is packed with reactive frameworks (RxSwift, ReactiveCocoa and RxJava to name just a few). But is the pattern's usability limited to iOS and Android only?

Functional reactive programming (FRP) is probably the hottest 🔥 topic in mobile apps development world right now. GitHub trending repositories list is packed with reactive frameworks (RxSwift, ReactiveCocoa and RxJava to name just a few). But is the pattern's usability limited to iOS and Android only?

For the past couple of months, I was responsible for implementing webhooks to extend functionalities provided by my company's proprietary CMS platform. The code was packed with a variety of integrations, but a general concept was always the same: a RESTful service receiving a JSON input, which was processed using a set of different APIs and transformed back to the other JSON response. During that period I fell in love ❤️ with funcy, a functional tool belt for Python. Initially, I wanted to write an article describing the library, but that would be too straightforward, wouldn't it?

The idea has quickly evolved when I bumped into RxPY repository. I have never tried using FRP outside of mobile apps, but I have tried to chain a bunch of API calls together and was never fully satisfied with a result. Having a tool to try out and a day off I have started scraping together a small playground project.

Playground scenario

Let's imagine you have to hire a co-programmer for the upcoming project. GitHub would be an awesome place to start headhunting:

there are a lot of developers having experience with almost any technology stack,

you can verify candidates' skills instantly.

The problem is that selecting a couple of candidates is not that easy when there are over 20,000,000 accounts to choose from. Let's come up with a naive algorithm to pick potential co-workers:

As a software developer you probably bookmark repositories that are relevant to your work. Your co-worker should be familiar with the same technology stack as you are. Going through contributors of your favourite (starred) repositories might be a good idea.

We will definitely have a better shot picking accounts flagged as available for hire.

The diagram above shows how to implement the algorithm using GitHub API:

The first step is to find repositories starred by the selected user (in this case, our own account).

GET https://api.github.com/users/{username}/starred

For every repository, download a list of contributors.

GET https://api.github.com/repos/{full_repo_path}/contributors

Perform contributors filtering:

own contributions have to be removed,

duplicated contributors have to be merged,

contributors not available for hire should be dropped.

To find out whether a user is available for hire, we have to fetch user details from GitHub API. The hireable boolean flag can be read at:

GET https://api.github.com/users/{username}

Contributors should be sorted by a number of starred repositories they are contributing to. We are interested the most in the people who are experts in a majority of our favourite technology stack.

Dependencies

Apart from the aforementioned funcy and RxPY, we are also going to use requests - probably the most beautiful networking library I have ever come across. It will help us to seamlessly integrate with GitHub API. Let's create requirements.txt file:

funcy==1.7.1
requests==2.11.1
Rx==1.5.2

... and install the dependencies with pip install -r requirements.txt.

ReactiveX

RxPY is a part of the ReactiveX project. As the docs state, the ReactiveX is an extension to the observer design pattern. For the sake of this tutorial, all you need to know is that it provides three building bricks:

Observable is a component that produces the data. It can emit multiple values over the time (data stream). An Observable starts emitting data as soon as another object subscribes to it.

Observable API

With this short theoretical introduction, we can start building utility methods to provide Observable API calls. First of all, we are going to wrap requests.request(method, url, **kwargs) method into the Observable. To do that, we implement subscribe method which defines what kind of data and in which point of time is transmitted to an observer:

When a new observer subscribes, we fire a network request with all of the arguments of the enclosing rx_request method.

After the response is received, we need to validate its status code using raise_for_status() method. It throws HTTPError if the request was not successful.

Having validated the status code, we simply return a response to the observer with on_next(response). Since the observer has finished producing the data, on_completed() method is called afterwards.

When HTTPError is raised (status code validation failed), we should inform the observer of the error by calling on_error(e).

The subscribe method returns something strange: a function which does nothing (lambda: None). Why is that? It is a shortcut for generating an empty Disposable object. Disposable is a component that provides instructions for freeing resources allocated by the observable. Imagine our observable starts a threading.Thread. When the observable completes its job or reports an error, we no longer need this thread to run. The disposable should be able to stop such a thread (i.e. by calling stop() on StoppableThread). The disposable is automatically executed by the library when needed.

For anyone working with asynchronous networking code on a daily basis, empty disposable for such a code will look like a bug. However, in Python networking requests are synchronous by default, so by the time that disposable is returned from subscribe method, the request is always finished.

There is one more thing to note. We do not have to explicitly wrap raise_for_status() in a try-except block. RxPY's observable catches all the exceptions on subscribe by default, so any exception thrown out of observable will be reported back as an error to the observer. The try-except block is there for demonstration purposes only.

JSON

We have wrapped an arbitrary networking request into an observable. Since GitHub API returns the data in JSON format, we can go a step further and implement rx_json method:

As you can see, all of those methods simply invoke rx_get_json wrapper with a properly constructed URL.

Finding hireable users

All the basics are covered. What is left is to implement the algorithm itself. This is a fun part which enables us to unleash a functional beast. 😈 Let's start with a final version of the code. Next, we will analyse every line.

starred_repo_names(u) finds full names of repositories starred by a user.

contributor_logins(r) finds logins of users, who contributed to a given list of repositories.

funcy.rpartial(funcy.without, u) removes a given user login from the list.

contributors_sorted...(c) removes duplicate entries and sorts contributors by a number of times they were present in the list.

filter_hireable_users(u) filters users which are hireable only.

As you can see, some of the methods are triggered with a map call and others use flat_map instead. What is the difference?

map / flat_map

Let's denote observable of X type as an Observable<X>, so that an observable str stream becomes Observable<str>:

The map method specifies how to transform an object contained inside a wrapper (Observable), leaving a wrapper aside. For example, having an Observable<str> as strings you can find a length of those strings by strings.map(lambda s: len(s)). The map describes str -> int transformation.

The flat_map method describes how to transform a wrapping container into another container, so it has a type of Observable<X> -> Observable<Y>. In ReactiveX world it means there is some additional work to be done by the observable, like a network request or a database query.

In our case, the flat_map method is used for the data transformations that require additional network requests (fetching contributors list by a repository name, filtering hireable users). On the other hand, map is used for no-additional-work data transforms, such as filtering out a name from the list or removing duplicates.

rx_find_hireable relies on funcy to drop a static user name from a list of users. without method takes a sequence and drops all of the items specified in a call. For example:

Partial appliance

For a map method we need to pass a function that takes a single parameter only (list of items). On the other hand, without needs two parameters (1. list of items and 2. values to remove). Since we know the element to remove upfront, we have a couple possibilities to transform this function:

Using lambda expression: lambda l: funcy.without(l, 'user'),

Using partial parameter appliance. Partials convert a function to a special object, which invokes a method in question with some of the parameters "hardcoded". There are two variants of partials in funcy: partial applies parameters from the left side and rpartial does the same from the right side.

As you can see, starred_repo_names method from the HireableFinder uses lpluck method instead of pluck. Starting with Python 3 functional operators (filter, map) return generators instead of real data structures. Using generators when possible improves performance a lot. The tradeoff is that to get a filtered list it has to be manually constructed:

funcy adopts the approach of returning generators only. However, to make data structure construction less verbose, it provides two variants for almost every method operating on a sequence:

non-prefixed - returns a generator,

prefixed with l - returns a real object.

So lpluck('f', l) is just a shortcut for list(pluck('f', l)).

Concatenating observables

Here comes (probably) the hardest part of the code. The contributor_logins(repos) receives a list of repository names and transforms it into a list of users who contribute to that repositories. Single observable has to be transformed into a chain of observables and merged back.

First of all, we have to create a list of Observables, one for each repository. We do this using funcy.lmap method (which is like a standard list(map(...)) in this case). The reason we need a list instead of a generator is that the concat method we are going to use later is not compatible with generators.

Now, we have to merge all of the observables into a single one. Let's examine how concat method works:

So, the concat method emits all of the values from the first observable, then from the second, third and so on... It is good, but not ideal for our case. We need to get all of the contributors in a single emission, not partitioned by the repositories.

Fortunately, there is a buffer method which groups emissions together. In our case buffering is really simple. We know how many emitted values should be chained together - that is a count of repositories (there is a single list of contributors emitted for every repository). Hence, we can use buffer_with_count() method:

Processing of contributors is not finished yet. First of all, the buffering operation will emit a list of values. In our case every value is a list itself, so a list of lists will be emitted. To get a flat list of contributors, the flatten method can be used. Its functionality is presented below:

Since we are interested in logins only, the lpluck comes to the rescue once again.

Sorting by repositories contributed to

By the time contributors_sorted_by_repos_contributed_in method is invoked, we already have a list of contributors (minus the initial user). However, those contributors will probably be duplicated because the same person can push code to multiple repositories. Moreover, one of the requirements is to put users with most repositories contributed to in front of the list, so we have to implement sorting.

Funcy has a method called count_by. It executes a mapping method on every element of the sequence and returns a dictionary which maps each result to a number of times it appeared. Example:

The last missing piece of the puzzle is lpluck(0, _) which drops redundant counts leaving logins only.

Filtering hireable users

Filtering hireable users is almost the same as fetching contributor lists. The only difference is that instead of flattening the list (this time we get one result per one emission) we have to remove entries with hireable != True. Since the input is a list of dictionaries, we can use where method to do that:

Bonus: In this example, you can see how Python (as a dynamic language) allows building really beautiful APIs. Since arguments can be parsed by a function as a name-value mapping, you do not have to specify a dictionary of filters and you can pass them to a function directly. Otherwise, the API would have to look alongside below lines:

# This is not that beautiful
funcy.where(sequence, conditions={'position':'developer'})

Running the application

The last step remaining is to test run the HireableFinder. Let's do it!

Aaaaaaand... Ladies and gentlemen, nothing happens! Why? Because we have not subscribed to the observable yet. By the laws of observer pattern, none of the declared data processing operations will execute until someone subscribes. So, the test run should look like this:

Conclusions

Reactive functional programming in Python is a lot of fun. The resulting code is concise and has no side effects, which makes it easy to test. If you are a Python programmer and have never tried it, I recommend you to do so! On the other hand, I really doubt this code makes any sense to a functional world's newcomer...

My final recommendation: if your team is eager for a new challenge and has a bit of spare time for experimenting, then think about giving reactive a try. On the contrary, if your team consists of developers with no previous experience in functional programming and the deadline is coming shortly, you should definitely avoid functional reactive programming. The advantages of that approach (especially for purely synchronous flow) are not big enough to outweigh numerous problems it can cause for others to even understand the code.

]]>So you already have an app and you are trying to engage users even more... What is a better way to do that than using one of the coolest iOS 10 features - iMessage integration?

This Tuesday Apple rolled out iOS 10 together with Messages framework. It provides building blocks

So you already have an app and you are trying to engage users even more... What is a better way to do that than using one of the coolest iOS 10 features - iMessage integration?

This Tuesday Apple rolled out iOS 10 together with Messages framework. It provides building blocks for creating iMessage extensions, which can be either self-contained apps or shipped inside a parent app. To get acquainted with the topic you can watch videos from WWDC 2016 (#1, #2) or follow this tutorial in which I will try to explain how to build such an extension.

ReactiveTODO

In a previous entry about UI bindings I have introduced an application called ReactiveTODO. It is my playground to improve coding skills and test some new ideas. After iOS 10 debut I came to a conclusion that the application is certainly missing a share with a friend feature. And I decided to build that. The final effect is presented below:

The design goal was to introduce a new integration with as little code as possible. The reasoning is that an indie developer would not like to spend weeks on implementing any extensions. In order to achieve the goal, I decided to reuse a todo note list, the main view controller of the application.

Make it build

The "zero step" to introduce iMessage integration for existing project is to make this project build under Xcode 8 with iOS 10 SDK. Having a code base in Swift 2.2, I decided that transitioning to Swift 2.3 is a better idea than Swift 3 for now:

Not a lot of libraries support Swift 3 yet.

No code changes are required to make the app work under Swift 2.3.

Xcode handles Swift 2.3 transition surprisingly well.

How to transition to Swift 2.3?

Download Xcode 8, install it and open existing project with it.

Select Edit > Convert > To Current Swift Syntax... from upper menu.

Select Convert to Swift 2.3 option and finish the dialog.

Xcode will automatically set Use Legacy Swift Language Version to Yes under build setting for the project.

Wait, is that everything? Not really. All third party frameworks have to be rebuilt with Swift 2.3 too. I am using Carthage to build those frameworks, so the first step is to update the application to the latest version for Xcode 8 support. Having latest Carthage on board, it is time to update the dependencies:

Usually I do not use --platform ios setting. This time I had to because of Cartography dependency, which does not compile Mac target for the time being. The --toolchain com.apple.dt.toolchain.Swift_2_3 switch tells Xcode to build dependencies with Swift 2.3 compiler. Otherwise, libraries that support both Swift 2.3 and Swift 3 could build with the latter, which is not compatible with the former.

As expected, the dependencies for the project will still not build correctly:

Realm uses prebuilt 1.0.2 framework, which was generated by Swift 2.2 compiler. Fortunately, the master branch is compatible with Swift 2.3 (and Swift 3!) already, so there is an easy way out - update Cartfile to fetch from latest master revision.

github "https://github.com/realm/realm-cocoa" "master"

ReactiveKit decided to port directly to Swift 3 (not ready yet), without Swift 2.3 transitioning period. To circumvent that issue I decided to fork both ReactiveKit & ReactiveUIKit and create swift-23 branches for both, which are Swift 2.3 compatible[1]. It also forced me to adjust Cartfile slightly:

Voila! Dependencies now build properly and the updated app runs as smooth as silk.

Create iMessage extension

To create an empty iMessage extension, select File > New > Target.. and pick iMessage Extension option from a dialog window. It will create a new group (named after your extension) which contains a storyboard, property list and a view controller source stub.

If you examine the view controller stub closely, you will notice that it is not your usual UIViewController instance, but rather the MSMessagesAppViewController class which derives from the former. This means that:

You cannot directly use your existing UIViewController, because it is not an instance of a required MSMessagesAppViewController class.

Since MSMessagesAppViewController is a UIViewController subclass, full view controller API is available. This opens a possibility to attach a child view controller and it is the best way to reuse existing code.

To reuse existing view controller in an extension it has to be available for the extension target. By default, it is not. There are a few ways to achieve that:

The easiest is to highlight a view controller's source file in a project explorer, open Utilities pane and select your extension under Target Membership section. It is necessary to do the same for all controller dependent classes.

The much better (and slightly harder) way is to create a framework and bundle all of the shared classes inside. Then you link the framework to your extension and reuse all the sources.

If you are serious about maintaining your application, then the first option is basically a no go. Soon, you will find yourself repeating that all over again when doing some changes or implementing the next extension. Build time will skyrocket and the code quality will plummet. We will proceed with a framework approach then.

Creating a framework

To create a framework use File > New > Target... menu option again, this time picking Cocoa Touch Framework from a dialog window.

There are a couple of facts that you need to know about frameworks, extensions, and tests setup before we can proceed:

A target can use classes and protocols defined in a framework as long as the framework is linked to the target.

Frameworks are dynamic, which means that they have to be accessible for a target that links against them in a runtime. System frameworks (like UIKit) are embedded in the iOS itself, but any custom framework has to be copied to a device alongside the target app.

iOS extensions are containers embedded inside a parent application.

Unit test schemes are executed within containing application.

By combining those four rules we can come up with a setup for our application:

iOS extension should be embedded in the main target (see Embedded Binaries under target settings).

Any third party dependencies in form of dynamic frameworks should be both linked (see Linked Frameworks and Libraries) and embedded inside the main target.

Our shared framework should link any third party frameworks needed, but should not embed them. The shared framework will be copied to the main target, alongside any third party dependencies.

Our extensions should link our shared framework (and any third party frameworks needed), but should not embed them. It will be already copied to a parent container (the main target).

Unit tests are executed inside the main target, so they do not have to either link or embed any framework directly. On the other hand, they should both link and embed test-only dependencies (an example could be a Quick library). It can be done by setting Framework Search Paths under Build Settings (linking) and Copy Files under Build Phases (embedding) in test target settings.

Considering above, to extract a framework from the main target we have to do the following:

Move all shared classes (in my case everything, minus AppDelegate and main definition) to both the framework project group and the project target. The easiest way is to use Finder to move directories. Then, back in the Xcode app, delete recently moved files from the main target group and re-add them to the framework target group. This ensures that the target membership is set properly for all of the files.

Create a new workspace with File > New > Workspace.... The name can be exactly the same as your .xcodeproj. From now on, you should only open .xcworkspace file to use the project.

In project navigator, under Products group there will be a .framework file for the framework target. Drag and drop this file to both Embedded Binaries and Linked Frameworks and Libraries sections in the main target settings.

Add all necessary third party dependencies to Linked Frameworks and Libraries for the shared framework target.

Drag and drop the shared framework product to Linked Frameworks and Libraries for the extension target. If you are using any third party dependencies directly in the extension, you should also link them in here.

The project should build now. You should be able to use classes and protocols defined in shared framework by simply adding an import SharedFrameworkTargetName on top of the source file. Also, do not forget to set public modifier for every class / protocol / method from the shared framework that you want to use. Otherwise it will not be visible in other module.

Sharing data between the app and the extension

Since we want to show exactly the same notes in the app and the extension, we need to share our Realm database contents. Out of the box, both of the targets use different file space, so separate databases are created. The result is that the todo notes created inside the application are not visible to iMessage extension.

Fortunately, there is an easy fix for that. First, we need to enable app group capability for both the app and the extension. This can be done by flipping the on-off switch in App Groups section under Capabilities tab in target settings. Then, a group has to be created with a + button. Name the group as group.<your_application_bundle_identifier>.

Once again, remember to do the same for both the main target and the extension target.

Implement iMessage interaction

We are ready to implement the extension itself. Right now we have following building blocks at our disposal:

Todo note list view controller. Every entry has a title, priority (represented by an image) and a date. Example entry is shown below (marked with the red rectangle).

An empty MSMessagesAppViewController from iMessage extension.

Todo note list has two capabilities:

adding a new entry,

marking an existing entry as completed upon cell selection (effectively removing a note from the list).

Probably the most effortless idea to integrate iMessages with that list is to create send a note feature. We can listen to an existing selection event, convert the note to a message and insert into a message box. Let's examine how to do the insertion part first.

MSMessagesAppViewController has a self-explaining activeConversation property of type MSConversation. By going one level deeper, one can find out that MSConversation class exposes insert(_:completionHandler:) method, which allows inserting an instance of MSMessage object to a message field. This means that we are good to go if we find a way to convert our model (TODONote) to a MSMessage. Let's look at an extract from MSMessage docs:

Before using an MSMessage object, you must set both its url and layout properties:

Encode app-specific data in the message’s url property. Use the NSURLComponents class to easily access, set, or modify a URL’s component parts.

Define the message’s appearance using the message’s layout property. Use the MSMessageTemplateLayout class to set an image, video, or audio file for the message. This class also defines a number of text elements, such as the message’s title, subtitle, caption, and subcaption.

We do not want to send any app-specific data, but we definitely want a layout so that our friends can see the note. The docs ask us to create an instance of MSMessageTemplateLayout, which looks like this:

Create a new message layout in form of MSMessageTemplateLayout instance.

Set a couple of the layout's properties (image, caption, subcaption).

Assign that layout to a new message instance.

Insert that message to a message text field of the active conversation by using insert(_:completionHandler:) method.

Let's start by creating a MSMessage. Since our selection event handler receives a note identifier instead of a full todo note instance, we need a data access object to get a full instance (hyperlinked only to make this post more concise). Having the DAO instance, we can implement MessageFactory as follows.

Notice the @available annotation. It is needed since we are working on a legacy project with the iOS 9 deployment target.

Now that we have a MSMessage factory, we have to attach it to a cell selection event. It is a high time for a small off-topic. ;-)

Reusing view controllers

We arrived at the point where a single view controller class is used both by the application and also the extension. In a view controller centric world we have to introduce a new flag to determine the cell selection logic. Let's call it isInvokedFromMessageExtension for now:

If isInvokedFromMessageExtension is set to true, we should invoke a MessageFactory and insert a new message into an active conversation. We should also hide a button which creates a todo, because adding new notes is not supported in the extension.

If isInvokedFromMessageExtension is set to false, we should mark the note as completed.

The other option would be to subclass the view controller and override some parts of the source code to achieve same effect. Either solution is not perfect.

There is a third solution which involves using a FlowController pattern. If you are not familiar with the term, I strongly advise you to read the hyperlinked article and use the pattern in future. For now, it is enough to understand that in a flow controller approach you have to conform a view controller to a protocol like this:

Then, instead of performing any logic upon customizable actions (in our case: cell selection) you only invoke a closure:

let guid = // selected note guid
self.onSelectTODO?(guid)

Then, you roll out a master object which configures the business logic attached to closures. It is called flow controller, because the common scenario is to navigate between view controllers, but the approach is not limited to that. Thanks to this architecture, reusing a view controller is as simple as having two different flow controller objects.

Fortunately, I decided to go with a flow controller pattern from the very beginning. Let's implement a new flow controller to reuse a todo note list:

And... this is it! After the application is installed, you will be able to send a todo note via iMessage:

Final words

This tutorial explained how to add an iMessage extension to an existing application. I hope that this piece is the only thing you will ever need to do this yourself (even when you are starting an app from scratch).

I also hope that using this example I have convinced you that once you get the architecture and setup of your application right, you can implement a fully featured extension in less than 50 lines of code. That is impressive!

]]>UITableView is truly a heart of iOS user interface. It does not matter whether you are changing settings, going through unread emails or sending messages. Provided that you have used your iOS device recently, it is almost certain that you have stumbled upon a table view.

UITableView is truly a heart of iOS user interface. It does not matter whether you are changing settings, going through unread emails or sending messages. Provided that you have used your iOS device recently, it is almost certain that you have stumbled upon a table view.

Rendering a table with arbitrary data is a really simple task. You just conform a class to UITableViewDataSource protocol by implementing two required functions. So far, so easy. The next step is to make this table represent some actual data from your app. This is where things are getting complicated. Some typical requirements are:

The data is stored in a local database, filtered and sorted according to a query.

Results of the query can be updated at any time, even by a table itself (marking TODO notes as completed, deleting favorite recipes and so on).

The data is synchronized with a backend service, either on demand or automatically (in the background).

What is more, the points above are not mutually exclusive. In fact, it is typical to have all of them at once in a single view controller. How do you handle UI updates for that? Wiring a synchronizer and a view controller to the notification center seems to do a trick. However, calculating table updates based on a queryset changes is not a trivia. Yes, it is possible to reloadData() everytime, but this won't cut it for marking a single object deleted.

Is there any other option? Yes, it is called NSFetchedResultsController and comes shipped with CoreData. It reports any changes made to a queryset so that you can map them directly to table view updates. Is it convenient to use? Well, just a quick look at the CoreData docs and I am already intimidated by a number of delegate methods that I need to implement. How about you?

You may wonder whether this article is to complain about how much code dedicated to UI updates is needed for every table view. No, it is not. In fact, I am going to show the opposite.

You do not need any dedicated code to handle UI updates for a table view.

What kind of magic is that?

Sample TODO app

Please, bear in mind that this article is up to date as of Xcode 7.3, Swift 2.2 and ReactiveKit v2. It is going to be updated for Swift 3 after it is out of beta.

To illustrate the idea, I have created a sample TODO note application. You can clone its source code from Github. The screencast from the app is presented below.

3rd party libraries

The first step for updateless table views is to attach necessary dependencies to a project. To accomplish the result we will need:

Realm Swift - a Swift version of a great object database for mobile devices,

ReactiveKit - a library that supports reactive programming along with ReactiveUIKit which provides bindings for UIKit controls.

Why Realm? There is at least a couple of different reasons to use Realm. For the project it is the best choice because it can notify about queryset updates similar to CoreData, but the API is much more concise.

Why ReactiveKit and not any other reactive programming library? There is no particular reason other than my familiarity with a framework. You can achieve the same result using RxSwift, ReactiveCocoa or any other (F)RP library that you feel comfortable with.

Carthage

Despite using only CocoaPods for dependency management in the past, I decided to change my approach. This decision was based on two factors:

I wanted to give Carthage a try for a long time,

the painful experience of using CocoaPods on my previous Swift project.

The problem with CocoaPods is that it rebuilds the whole workspace every time a target is changed or DerivedData/ directory is emptied. Having over 15 dependencies attached and being a victim of frequent Xcode syntax highlighting problems and crashes I spent a considerable amount of time observing a build progress bar. Since it was not entertaining, I have switched to Carthage for the time being.

Installing project dependencies requires a couple of steps. Firstly, you need to create a Cartfile:

Secondly, you need to run carthage update command. It is noticeably slower than pod install counterpart, but it results in much shorter average build time.

After a build process is completed, frameworks need to be attached to a project. Carthage readme documents that really well, so it is a matter of following steps mentioned there.

Reactive programming

ReactiveKit is a library that supports Functional Reactive Programming (FRP). If you are familiar with the term you can skip this section. Otherwise, do not worry. It is there to describe a pretty simple concept of building a software.

Reactive Programming (RP) focuses on a data flow. The idea is that there is an input data that changes constantly and the code should specify how to transform it to an output. Let's assume that there are 5 people reading my blog right now, two of them being female. Or, expressed in a programming manner:

male = 3
female = 2
total = male + female // 5

Now, a next female hits the page. It changes the input data:

female = 3

In an imperative programming world, a total value would not change. It was calculated once and it will stay this way until it is explicitly changed. In that case total == 5 still evaluates to true, but it certainly is not valid, since I already have six visitors!

If I wanted to show a total number of visitors, reactive paradigm would be a much better fit. The total value (output) would be updated every time that either male or female values (input) are changed.

The only difference is that array of notes is additionally wrapped inside a CollectionProperty. Thanks to CollectionProperty, every time an array is changed, a subscriber gets notified about it. A simple example can be found in ReactiveKit readme.

Upon running an application you should see a list of two entries. You might have noticed that the code is a little bit shorter than the delegate counterpart. But the biggest advantage of that approach is yet to be discovered. Now, add a new button to the view controller. It can invoke any of the three action types below:

insertion (example: notes.append(TODONote(note: "Third"))) ,

deletion (example: notes.removeLast()),

modification (notes[0].note = "Not a first note anymore").

Test run the application. Yes, that is right. The changes made to a notes array are automatically reflected in a table view now.

Using ReactiveKit with Realm

We are halfway there. Our table view is refreshed automatically, but we still have to wire up a database query to a CollectionProperty. It is high time to switch to an actual implementation of TODONote model:

It is a lazy loading collection. Objects are fetched from a database only when they are needed.

It is updated automatically to reflect a query state.

It conforms to a RealmCollectionType, which derives from CollectionType.

The last point is especially useful for us. Since ReactiveKit's CollectionProperty wraps around CollectionType we can instantiate that with Realm's Results directly:

let notes = CollectionProperty(realm.objects(TODONote.self))

The bad news is that binding such a property directly to a table view would result in a crash or no updates at all. It is because ReactiveKit provides standard protocol extensions for Array type, which triggers an update event upon invoking any method that can modify this array. Such overloads for Results are non-existing in standard ReactiveKit library, since it does not come bundled with Realm.

The good news is that Realm supports collection notifications which is exactly what we need to implement a CollectionProperty. Even better news is that Realm's notifications use almost the same data format to denote collection changes as ReactiveKit does. Having that knowledge, we can easily implement a bridge between the two:

From now on every change in a database that modifies notCompletedNotes query will automatically trigger UI updates. There are numerous advantages of that approach:

There is no need to worry about manually exchanging notifications anymore. It does not matter which action/object triggered the change. Whether it is a button inside the same view controller or a synchronizer class managed in the AppDelegate, all the data changes are handled in exactly the same fashion.

There is no need to worry about managing threads. ReactiveKit's data bindings are always updating UI on the main thread, so it does not matter whether the database was modified in a background or not.

Single source of truth - the database. There is no need to duplicate data structures and so there is no risk to have any discrepancies between them.

I strongly advise you to try this approach yourself. I was really surprised about how easy and reliable that was.

Please note, that the code presented in snippets is for presentation purposes only and contains shortcuts, like creating notes in init(), that you should never ever use in a production code.

]]>Storyboards are known to "divide" iOS developers since their introduction in iOS 5. Almost five years have passed and the consensus about when to (not) use them still remains. It is probably because of the fact that using storyboards has as many benefits as drawbacks[1] so it]]>https://jakubturek.com/to-storyboard-or-not-to-storyboard/597a3c2c5d59c21b3619cd03Fri, 05 Aug 2016 18:46:33 GMT

Storyboards are known to "divide" iOS developers since their introduction in iOS 5. Almost five years have passed and the consensus about when to (not) use them still remains. It is probably because of the fact that using storyboards has as many benefits as drawbacks[1] so it is more about personal preference than anything else.

Since there is no undoubtful choice here, it is likely that soon you are going to face the same problem as I did a couple of weeks ago: which path do I go with in a new project? I hope that by presenting my thought process I will make it easier for you to make your choice.

Note: all of the considerations below are valid for Swift projects only.

Swift core concepts

Swift is built around two concepts that strengthen compile-time safety:

constants against variables,

required values against optionals.

Let's quickly recap both of those.

Constants / variables

Constants are the values that cannot be changed once they are set. They are declared using let keyword. They are an opposite to variables, which values can be modified (declared with var).

Swift language docs made it obvious that you are supposed to use let over var whenever this is possible.

If a stored value in your code is not going to change, always declare it as a constant with the let keyword. Use variables only for storing values that need to be able to change.

Extract from The Swift Programming Language (Swift 2.2).

Optional / required values

As opposed to other popular objective oriented programming languages, Swift compiler does not allow to assign a nil value to a constant / variable by default. Swift introduces so called optional values which are allowed to be nullable.

your code should not use optionals unless absence of a value is possible,

you should always handle nil cases when handling optional values.

Swift protocols

Another concept introduced by Swift programming language is a protocol. Protocol defines a set of properties and methods that need to be implemented for a particular piece of functionality. Protocols should always be used instead of concrete types for specifying object dependencies.

A small change and now it is possible to replace FileStorage with any other object that conforms to StorageProtocol. Guess what? You can replace it with a mock object in unit tests too.

So much better! Such wow!

Injecting dependencies

ImagePersistenceService was a simple example of Dependency Injection pattern. And because of how Swift works it also happens to be a really beautiful piece of dependency injection:

It is impossible to construct the object without needed dependencies, since constructor parameters are not optional.

It is impossible to replace dependencies after instantiation (possibly leading to invalid object state), since they are marked as let constants.

Having above in mind I made a protocol-let-init a go to pattern for instantiating all of my Swift classes. I have also picked Swinject as a dependency container to support assembling my instances. So far, so good!

Storyboard view assembly

Here is where a problem with Storyboards kicks in. A protocol-let-init pattern is obviously limited to the places where you have a direct control over assembling object instances. Unfortunately, it is not the case with Storyboards. When instantiating views or controllers Storyboard calls init(coder: NSCoder) method. While it is totally acceptable for views (they should not contain any logic anyway ), it is a real problem when it comes to controllers.

Let's suppose we want to implement SendEmailViewController which prompts user to enter his/her e-mail. It always a good idea to validate the input, so implementation of EmailAddressValidatorProtocol has to be injected into a controller. Using protocol-let-init it is an obvious task.

But what to do with init?(coder aDecoder: NSCoder) initializer? Let's recap some points about Swift's constants and initializers:

Constant objects have to be created before super initializer is called.

By the time initializer is finished, super initializer has to be called.

This means that there is no way to injectemailAddressValidatorin Storyboard init! Well, that is a huge disappointment. But surely there is another way to do it, isn't there? Now we are back to a drawing board and our DI pattern article to look for an inspiration. Oh yes, we can use setter injection! Let's do that[2].

Not only did we make emailAddressValidator mutable, but also optional. And there is no other option. This is really, really bad. With protocol-let-init it was impossible to create an object in an invalid state. Now it is definitely possible and as easy as not setting a single view controller's property.

I can hear you asking: why is it so bad? I have just implemented this view controller, so now I am going to instantiate it and there is no way in hell I could forget to set all of the properties to be injected. You are right, provided that there are no changes to be made to that controller. And we both know that there will be some in future. So let's go ahead and add a name that needs to be validated, too.

The protocol-let-init version will refuse to compile at this point, because NameValidatorProtocol requirement is missing where view controller is instantiated.

The Storyboard version will continue to compile just fine. You will not get any reminder to set nameValidator in every place SendEmailViewController is created (hopefully you got it right and there is just one).

Forgetting to set an injected property has just got much more likely, hasn't it? To workaround that issue it might be tempting to try to convert those injected properties to implicitly unwrapped optionals instead. Now, if nameValidator is not set the application will crash as soon as the property is referenced.

This gives a false belief that everything is wired up properly as soon as you are able to navigate through such a view controller. You might be wondering why this is so misleading. Let's get back to our SendEmailViewController example. Name and e-mail are sensitive data, therefore we should hide/clear them before app snapshot is taken when going into background.

You should already get the point I am trying to make here - not every dependency is used in the simplest flow of the application. Moving application to a background on the particular view controller is an example of such an uncommon flow in development. By unwrapping dependencies implicitly you give your user immediate feedback that something went wrong. But definitely not in the way you would like to.

Conclusions

Storyboards are sexy, but they are not that Swifty.

Are Storyboards worth it? The short answer is no. I came to the conclusion that trading off a lot of Swift's compile-time safety for Storyboards is simply not worth it. Yes, protocol-let-init can still be used in other parts of the application, but taking into account that any iOS application is somewhat view controller centric it is important to take every precaution step possible while implementing them. Swift language gives a lot of powerful tools to enforce that safety, but Storyboard does not build up on them.

iDev recipes is a series of short articles that present ways of dealing with common problems while developing apps for Apple devices.

One of the most frustrating things about Xcode is that project layout does not have to reflect directory structure. It seems like a powerful feature at first, but soon you find yourself fighting with directory bindings every time you add a new source file.

In the past I have tried two approaches to circumvent the problem:

Creating blank files on a filesystem with touch command.

Using sticky notes to remind myself that I always have to bind a new group to a directory first.

Both of them require additional hassle and fall short when it comes to refactoring. Does it mean that we are stuck to have all the projects look like this?

Typical result of using Xcode groups to structure project without binding directories manually.

Fortunately, there is a tool called synx which can align directory structure with project layout using a single terminal command. It also sorts files in groups, so you are guaranteed that both Xcode and Finder will look the same. Examine result of running synx Project.xcodeproj on a project above:

The same project after synxing.

It is so much tidier now. Could it get any better? The problem is that running a terminal command every once in a while to fix a project layout is not convenient. But do not worry. Provided that you use git repository for your project, you can configure it to tidy up the project every time you commit anything. Say goodbye to manual directory juggling!

Installing ruby

Since synx is written in Ruby, the first step is to install proper Ruby interpreter. You could use OS X built-in, but it is always a better idea to go with the latest software. To make Ruby version management easier, we will use rbenv for the task. To install rbenv using Homebrew run following commands:

To confirm that everything is working as expected, make any changes to your sources and try to commit them. You should see the output from synx application before commit message input prompt:

git add -A
git commit

Additionally, you can add -q flag to synx in pre-commit to silence all output. However, since synx operates on a project file directly you should always examine error logs in case something goes wrong.

The final step

Having completed configuring a synx hook, it is time for one final step. Which is to write some high quality code, commit it and admire how the computer automatically keeps your Xcode project tidy.

]]>Warm welcome everyone!

It has been almost a year since I posted an article to my devlog. It has been such a long time that I have decided to introduce a brand new iteration of the page. Now, with a dynamic blogging platform and real comments section it is time

It has been almost a year since I posted an article to my devlog. It has been such a long time that I have decided to introduce a brand new iteration of the page. Now, with a dynamic blogging platform and real comments section it is time to say hello to my readers for a second time.

posts about various software and tools that you should have installed on your development Mac.

Since I have already invested much time to get this site up and running, you can expect me to be much more dedicated to regular updates than previously. However, in the end it is you my Dear Reader who decides about a future of this devlog. If you find the content to be of high quality, share it with others and hit me up on Twitter with a feedback about it then you are 100% guaranteed to see a lot more in future. It is time to make a choice!