Kotlin Multiplatform: testing a shared module supporting iOS and Android

🇫🇷 Parlez-vous Français ? You can read a French Version of this post on our blog at Xebia France.

Conceiving your app as modular can be greatly beneficial to your codebase’s health. In particular, designing a separation between your view and business logic can decrease the coupling between your layers and improve maintainability as well as testability.

Tests are indeed your app’s best friends, as they can, at the same time, verify the code you wrote works as intended and act as a specification for the implemented functionality.

When it comes to Multiplatform, Kotlin provides an interesting solution for testing your logic: in this configuration, every written test is executed against each one of your targeted platform.

In other words, given you target are Android and iOS (via Kotlin/Native), your tests will be compiled and launched in both the JVM and the native runtime.

The setup of unit tests for Multiplatform can be tricky, though. Let’s see how to get a working configuration.

In order to do this, we’ll proceed from where we left in our last post.

As you might recall, our module did nothing more than producing two strings, bar-android and bar-ios for Android and iOS respectively. Thanks to test in Kotlin Multiplatform we’ll be able to verify that, no matter the targeted platform, the produced value starts with bar-.

Writing our Test

The full code for this article is available in the feature/multiplatform branch of our kotlin-ios-framework repository.

So, time to create a new file. First of all, let’s create a folder holding our test: myframework/src/test/kotlin/fr/xebia/myframework/. As you would expect, the path mirrors the one containing our implementation under test. In this directory we’ll create a new test class, TestFoo, whose contents are as follows:

As you can see, Kotlin comes with a testing and assertion framework, so no need to declare another dependency to your project.

Of course, for tests to be run, we need to edit our build.gradle files. Let’s start with the common project’s: it should declare two additional dependencies: kotlin-test-common and kotlin-test-annotations.

Please note that, in Kotlin Multiplatform, since tests can be only run against a specific target platform (such as Android’s JVM), kotlin-test-common will not suffice to be running your verification logic, but acts as a placeholder for an actual testing framework such as JUnit.

As a proof, we can already try compiling the tests, which action will produce a build error, as the platform target won’t know how to interpret annotations and assertions.

build.gradle for Android

Quite unsurprisingly, we’ll have to edit the build.gradle file for the Android project as well. Similarly to the build file included in the common project, the Android’s should declare additional dependencies, needed for testing: JUnit, kotlin-test-junit and kotlin-test. Those dependencies contain the actual frameworks that will be executing during the execution of your tests.

build.gradle for Kotlin/Native

Last but not least, let’s configure the gradle file for the Kotlin/Native project used on iOS, which setup is definitely trickier.

In the current version of Kotlin/Native, in order for tests to be launched, we’ll have to create a “dummy” program that will hold both our “main” and “test” code and that will be executed when running the “test” task with gradle.

To do so, let’s then add a new program in the build.gradle file contained in our myframework-ios folder:

Second, we need to ask gradle to run the program upon launch of the “test” task. To do so we’ll have to add a new task, at the bottom of the file:

When running gradle test, our program will compile, get executed and produce the following output:

Once again, you can grab the full code for this article from the feature/multiplatform branch of our kotlin-ios-framework repository.

Going Further

A nice feature of such configuration is that we can add specific tests for each platform. For instance, in case we want to add a more detailed test for our Kotlin/Native target, we’ll just need to create a new test folder in the myframework-ios subproject – without forgetting to add such folder as srcDir inside the build.gradle file.

Wrapping Up

As seen in this post, configuring a test environment for Multiplatform tests is just a matter of adding a few lines of code. Once we get the right setup, tests will be run on all the targeted platforms with little effort.

Sharing frameworks between iOS and Android with Kotlin Multiplatform

🇫🇷 Parlez-vous Français ? You can read a French Version of this post on our blog at Xebia France.

Today we’ll see how to use Kotlin code to write a cross platform module that can be shared between an iOS and an Android app.

Since the support for building iOS frameworks, introduced with Kotlin/Native 0.5 in December 2017, it has been possible to use the same code for creating libraries for both Android (.aar) and iOS (.framework). A couple of months later, Kotlin/Native 0.6 officially supports this use case, thanks to the support of Multiplatform, a new functionality focused on sharing code across platforms, introduced in the version 1.2 of the Kotlin language.

Today’s goal will be to create two modules, one for iOS and another one for Android, sharing a common interface but providing slightly different implementations, both written in Kotlin.

Multiplatform supports a DSL bringing two new kinds of modules:

  • “Common”: they contain code that is not specific to any platform, and unimplemented (“apxpect”) placeholder declarations that need to rely on a platform-specific implementation
  • “Platform”: they contain platform-specific code that implement the placeholder declarations in the common module. Platform modules can also contain other platform-dependent code.
  • “Regular”: they regroup those modules which are neither “Common” nor “Platform”.

A good example for this need is File I/O: as expected, any implementation of file access or networking is beyond the scope of Kotlin Standard Library. So, in case our commons module wants to use the file system, it’ll have to rely on two different underlying implementations which are platform dependent. For instance, to access files on Android, we would be using the Java.io.File while on iOS we would rather use NSFileManager.

So, let’s begin where we left in our previous post about the creation of iOS frameworks with Kotlin/Native.

Our module didn’t do anything except returning a string value. So, we’ll modify this behaviour by making our function return a different value depending on the system our module runs on. Our two implementations will be packaged under two different forms: an Android Archive (.aar) for Android and a Framework for iOS.

In order to do this we have to slightly change our project structure by adding two new folders corresponding to the Platform modules (myframework-ios and myframework-android), and create a directory tree containing “src/main/kotlin/fr/xebia/myframework” in both of them.

The resulting file tree should now be as follows:

 

The common project

Settings.gradle

Now, we have to make sure Gradle recognises myrframework-android as part of our project. To do this, we need to edit our settings.gradle file and, in the second line, add :myframework-android and :myframework-ios.

The complete file contents are:

We can now run

to double check your new configuration does not output any error.

build.gradle

Time to modify our build tasks: in our main build.gradle, we’ll have to change the kotlin version to 1.2.30. This is needed in order to use the Multiplatform feature on Android.

The new, complete build.gradle is as follows:

Back to the code

Let’s get back to our Foo class. We’d like to provide an extremely basic implementation, in which the bar() function will return a different string, depending on the OS. On Android, the returned string will be "bar-android", while, on iOS, "bar-ios".

Now, it’s the time to introduce a new keyword: expect. By the means of this we can tell the compiler that this declaration is nothing more than a placeholder – but that we’ll be expecting a concrete, actual, implementation from one of our platform-dependent projects.

So, we’ll modify the Foo.kt file inside the myframework subproject as follows:

 

Also, we need to declare that this project supports Multiplatform: in order to do this, we’ll have to modify the build.gradle at myframework/build.gradle as follows:

The actual implementation

So, it’s now time to get to the platform-specific implementations, starting with Android.

We’ll now add a new build.gradle just inside the  myframework-android, holding the configuration for this subproject.

build.gradle (Android)

In the new build gradle we’re going to declare that myframework-android provides an implementation that is expected by another project, namely myframework. We do this by using the expectedBy scope.

Also, and foremost, let’s not forget we’re building an Android library here, so we’ll have to add all the settings required by such context, under the ‘android’ property.

Here’s how the build.gradle file looks like for the myframework-android subproject:

AndroidManifest

Since we’re building an .aar, we also need for an AndroidManifest.xml, which is required by the targets.

In this project, we’ll add, inside the myframework-android/src/main folder, a simple manifest file.

Code

It is the time to provide the platform-specific implementation. In this extremely basic implementation, the bar() function will return a different string, depending on the OS. On Android, the returned string will be "bar-android".

In order to do this, we have to make sure our “actual” implementation:

  • Belongs to the same package as the base (or “expect”) implementation
  • Uses the keywords “actual”, both before class (and optionally before its constructor) and before the actual function implementation.

The result is as follows:

 

iOS

Creating the iOS counterpart doesn’t differ much from what we learned in our previous article.

First of all, we have to add a new build.gradle file containing the konan (i.e., the Kotlin/Native compiler) definitions. As mentioned, the build.gradle file should look quite familiar now, with the exception of the enableMultiplatform true directive, enabling the Multiplatform support in this subproject.

As we did in the Android counterpart, the expectedBy directive under dependencies tells gradle that our project contains the “actual” implementation of myframework.

 

Code

The code is once again a matter of few lines. We’ll be adding a Foo.kt class inside myframework-ios/src/main/kotlin/fr/xebia/myframework

In this case, the “actual” implementation of the Foo class will return the string bar-ios. Once again, in order for the class to match the “expected” one, we must remember to declare the package this file lives in.

And here is the full implementation:

 

Building

And that’s all. By running

we should now be able to get all the iOS (e.g. konanCompile) and Android tasks.

We can build both iOS and Android at the same time by running, from our project folder.

The artefacts will be created in the myframework-ios/build and myframework-android/build folders.

You can get a complete example of the code above from the feature/multiplatform branch of this repo.

Wrapping Up

As we’ve seen, the workflow introduced by Kotlin multiplatform is pretty straightforward and has been quickly implemented in Kotlin/Native. I can say I am quite surprised to see so many features getting implemented into Kotlin and Kotlin/Native and I’m really looking forward to seeing the reception of mobile developers in respect to such tools.

Credits

Once again, I particularly wish to thank my fellow colleagues at Xebia, Bastien Bonnet, Sergio Dos Santos and Benjamin Lacroix, for thoroughly reviewing this article.

Creating an iOS framework with… Kotlin

🇫🇷 Parlez-vous Français ? You can read a French Version of this post on our blog at Xebia France.
Kotlin/Native is a new Kotlin dialect which supports compiling code in an executable form that can be run on the targeted system, without needing for a JVM. The Kotlin/Native compiler, named Konan, interfaces with the LLVM compiler infrastructure in order to support a number of targets, such as Linux, macOS, iOS, Web Assembly and others.
First announced in April, Kotlin/Native has now reached v0.6, published in February 2018. Since its version 0.5 Kotlin/Native introduces a new target, which can particularly be useful for iOS projects, that is iOS frameworks.
In this article, we’ll see how to create an iOS framework using Kotlin code. Our library will actually do nothing too fancy, but it’ll be a great starting point for future evolutions.
Please note that to complete this tutorial you will need a machine running macOS and Xcode 9.2.

How Konan works

As mentioned above, Konan interfaces with the LLVM backend compiler in order to support a number of targets, such as Linux, macOS, iOS, Web Assembly and others. The LLVM compiler takes as input an intermediate representation (IR, or LLVM-IR) and generates machine code (or, better, object code) for a number of supported CPU architectures (such as ARM, x86 and many others).
In other words, Konan will compile Kotlin code to LLVM-IR and LLVM will take care of the rest, by compiling LLVM-IR down to ARM (or other CPUs).
Kotlin and LLVM

Before we start: Gradle

In order to complete this tutorial, you’ll need to install Gradle first. If you’ve never stumbled on it, Gradle is the main build tool in the JVM environment and it is used by the vast majority of Android projects. With Gradle, we’ll be able to define dependencies, and define tasks that will take care of compiling our project. Also, and foremost, gradle is easily extendable via plugins, and we’ll actually use one of them to help us creating the tasks we need to create our framework.
The easiest way to install Gradle is via Homebrew:

Project Setup

We then create a new project folder, for instance “MyProject”.
We can now open the shell inside “MyProject” and run

This operation will create the basic configuration for our project.

Now, we’ll need to add the following resources to “MyProject”:
  • An empty gradle.properties file
  • A folder, named “myframework”, which will contain code and properties for our library
  • Inside the “myframework” folder, we’ll be adding:
    • A tree of folders as follows: src/main/kotlin/fr/xebia/myframework
    • Another empty build.gradle file
The result should now be as follows:

This structure follows the conventions of most Java and Kotlin projects and allows us to prepare our project to host other subprojects in the future in case we need it (and we sure will in a further post).

Configuring the environment

Now we’ll be setting the basic properties of our environment.
The settings.gradle file should reference reference the modules of the project we’re building. In our case, it’s “myframework”, so we’ll add to the file the following line:

The root build.gradle file will contain the main configuration used throughout our project and subproject. In particular, we’ll set the kotlin_version to be used (1.2.21) and the version of the compiler (0.6). We also set which repositories will be used by our build script, i.e. jCenter.

Configuring the “myframework” subproject

Let’s open the build.gradle contained in the “myframework” subproject. This file instructs Konan on what and how it will need to handle the compilation.
In particular, via the apply plugin directive, we’ll define the plugin to be used in our context: ‘konan’, which is of course, the plugin used for easily interfacing with the Kotlin/Native compiler.
Also, we’ll instruct our script about its repository: i.e., maven, and its dependency, the kotlin-native-gradle-plugin.

Finally, we’ll add to the same build.gradle file the directives for creating the iOS framework. We’ll be targeting iPhone and the iPhone Simulator, which are based on two different architectures, namely ARM for the iPhone and x86 for the Simulator. We’re also setting, in the framework parameters, the output file name of our task: ‘MyKotlinFramework’.

Here, we’ll also indicate which folder contains our source code, in our case src/main/kotlin.
Not much else to see here, apart from enabling the debugging mode, via the enableDebug true line.

Adding some source code

Now it’s finally the time to add some Kotlin code.

As you clearly understand, this code doesn’t do much, but it’s enough to try out the basic functionalities of Kotlin/Native.

Compiling

That’s pretty much all. We just need to compile our project by running grade.
Before doing this, let’s just run

This should output a number of tasks preconfigured by Gradle. Among them, the compileKonan task, compileKonanMyKotlinFrameworkIphone, compileKonanMyKotlinFrameworkIphone_sim are automatically created by the konan plugin applied in the build.gradle file: as the names say, they will compile code and produce frameworks for iPhone and iPhone simulator.

We can now run

and wait for the project to compile. Please note that Gradle will also take care of automatically downloading the Kotlin/Native compiler for us – even though this’ll take a while.

When the compilation is finished (it may take a little while at the time of writing), verify the contents of the folder myframework/build/konan/bin/iphone_sim: they should contain three files:
  • MyKotlinFramework.framework
  • MyKotlinFramework.framework.dSYM
  • MyKotlinFramework.kt.bc
What are those three files?
The first one is, of course the framework we’ve just produced. The second file, having the dSYM extension, contains the information needed to debug our framework with an lldb debugger, such as the one provided by Xcode. Last, the .kt.bc file is the bitcode file of our program. In other words, it is the binary form of the LLVM Intermediate Representation of our code.

Integrating in an iOS application

In order to try how the framework runs in our iOS app, let’s add it to the “Embedded Binaries” section of our target.
Embedded Binaries Section
Then, in our Swift code, we’ll just need to import the library and use the bar() method of our Foo class. As you’ll see, please note that Konan prefixes all your classes with the trigram of your framework output name. In our case, MyKotlinFramework. In our case, the Foo class will become visible in Objective-C and Swift as MKFFoo.

The complete code of this tutorial is available at this GitHub repo.

Where to go from here?

Needless to say, this is just the beginning. Thanks to Kotlin/Native 0.6 it is now easy to share code between iOS and Android, by using the Multiplatform DSL. This will allow for a more effective reuse of your business logic between your mobile apps, no matter the platform.

Credits

Huge thanks to my colleagues at Xebia France for reviewing this article, in particular Sergio Dos Santos, Benjamin Lacroix, Michaël Ohayon and Julien Datour.

Kotlin/Native 0.5 and iOS

Kotlin Native interoperability is rapidly evolving and the latest iteration, version 0.5, brings support for calling Kotlin code from Swift and Objective-C.

Also, iPhone Simulator is now supported out of the box. Just run

to compile the Kotlin bridge for the iOS Simulator platform libs and runtime. The command will take about 1 hour to complete on a recent MacBook Pro.

Also, the samples have been adapted and you will now be able to try out the features straight on your simulator.

And that’s pretty neat.

Running a Kotlin/Native iOS app in the Simulator

Update: since Kotlin/Native 0.5, the following article is now outdated. I’ll be keeping its content for reference.


Kotlin Native 0.4 is out since the beginning of November and, with it, some nice sample iOS demo apps to be run into your favourite iOS device. That sounds amazing, even for some hardcore Swift fans like me. Yet, there’s a catch: the sample apps can only run on a real iOS device but not in the Simulator. Sure, that’s just an unsignificant drawback compared to what the Kotlin Native team achieved so far. Still, I’m a huge fan of the iOS Simulator, as it’s by far the fastest way to do some quick testing of an app while doing a pretty good job in mimicking the behaviour of an app on a real device.

So, as a way to understand the Kotlin Native project, I decided to try supporting the Simulator on a Kotln Native iOS app.

In order to do this, I started from the UIKit project sample found in the samples dir of the main repo and tried to make it run in the sim.

Continue reading Running a Kotlin/Native iOS app in the Simulator

Leveraging Swift Code Coverage with Xcode 7

French speakers: the original version of this article is actually French, and you can read it on Xebia’s excellent blog.

Also, this article is the text version of the talk “Leveraging Xcode Code Coverage”, presented at the Mobile Optimized conference in Minsk, whose slides are available here.


One of the WWDC 2015 announcements that surprised interested us the most has definitely been the support for code coverage for the Swift language.
In this article we will understand the advantages of the new code coverage functionality introduced in Xcode 7 and how to integrate such KPI in our daily work.


Code coverage is a metric that measures the value of our tests by identifying what code is executed when running them and, above all, what portions of our project are untested.

How it works?

The production of code coverage information is done in two passes:

  1. At compile time, the compiler prepares the files for analysis
  2. At runtime, the lines of code affected by the tests are annotated in a specific file

Xcode code coverage before June 2015

Before WWDC 2015, only the Objective-C code coverage was supported by Apple’s tools, while Swift had been left behind. Also, the Objective-C support was sometimes inconsistent and required a few tricks to get the information.

How did it work?

The procedure necessary to retrieve the information was a variant of the one used by gcov, included in the gcc tools. Two settings had to be added to the Build Settings:

  1. Generate test coverage files, which corresponds to the -ftest-coverage gcc flag
  2. Instrument program flow, corresponding to -fprofile-arcs

The former allows the creation of the .gcno files, which contain the information needed to build the execution graph and reconstruct the line numbers.

The latter, Instrument program flow, deals with the creation oft the .gcda files, which contain the number of transitions on different arcs of the graph and other summary information.

In order to force the generation of these command line data, it was possible to use the following command:

Exploiting the data

A number of tools for reading and exporting reports exist, but in particular, we used the following:

  • Coverstory, a GUI tool to read files “.gcda” and “.gcno”
  • gcovr translates these files Cobertura XML format
  • lcov generates a visual report in a navigable HTML
  • and, especially, Slather.

Slather

Slather, developed by the SF-based company Venmo, exports the code coverage data in a number of different formats, including Gutter JSON, Cobertura XML, HTML and plain text. In addition, it integrates easily with other platforms, such as Jenkins, Travis CI, Circle CI and coveralls.

As said, one of the major assets of Slather is its ease of configuration and integration within a continuous integration system. Slather is open source, and available here at Venmo’s GitHub repo.

Swiftcov

A recent tool for collecting Swift coverage information is Swiftcov, developed by the guys at Realm. Swiftcov makes heavy use of LLDB breakpoints to detect which lines are affected by the execution of our tests.

Code coverage after June 2015

During the WWDC 2015 keynote, Apple announced that Xcode 7 would introduce support of code coverage for our beloved Swift.

How does it work?

A completely new format has been introduced, named profdata, thus making
gcov legacy – at least for what concerns projects developed with Apple’s development tools.

In other words, starting from the very first beta of Xcode 7, profdata is intended to replace completely gcov for both Swift and Objective-C.

In order to enable the setting, from Xcode 7, you will need to access the “scheme” setting and, in the “Test” tab, to tick the “Gather coverage data” checkbox.

Access the scheme editor, select the "Test" tab and enable the "Gather coverage data" checkbox

As for the command line, xcodebuild now ships with a new parameter, -enableCodeCoverage, which can be used as follows:

Once the tests run, coverage information is immediately available in Xcode, on the right side of the code editor (see image below) and, in particular, in the “Report Navigator”.

Inline code coverage information
Inline code coverage information
Code coverage information in the Report Navigator
The new Report Navigator

The Report Navigator shows in detail which classes are covered by our tests and, by expanding the selection, which methods are actually used.

Exploiting the data

Apple’s work hasn’t only consisted in enhancing Xcode but, also, in extending the features of the   llvm-cov command line tool, which allows working with .profdata format.

The llvm-cov show command, for instance, allows exporting plain text coverage information and outputs annotated source code files, which can be easily read and processed.

Slather (returns)

A recent Pull Request allows Slather to work with profdata files and convert them to other formats, thus enabling the integration with the other platforms supported by the tool.

Xcode Server

If you are thinking about setting up an automated integration system, aside from the excellent Jenkins, Travis or Circle CI, it is perhaps time to start taking into consideration Xcode Server, which is part of the OS X Server bundle, distributed free of charge by Apple.

With the new version of Xcode bots and Xcode Server, it is now possible to support code coverage values ​​and to display the results in a Web browser. The reports are also available in the “Big Screen” presentation, useful for presenting your content in a simplified yet effective overview.

In order to enable this workflow, you could follow the steps below:

  1. Install OS X server
  2. Enable “Xcode” and “Websites” services
  3. Create a new project and assign a Source Control Manager to it (such as git)
  4. In Xcode, create an Xcode bot under “Product > Create Bot”
  5. Select the frequency of integration and enable code coverage (see image below) next to the caption “Code Coverage”.
  6. Launch an integration
  7. Open the web browser at the host indicated by your instance of Mac OS.
Xcode Bot creation panel
Xcode Bot creation panel

Conclusion

Code coverage is very useful to keep under control your code base health status. Although it can not replace your developer confidence in well designed, well structured apps, this metric can help write better code by encouraging you to give yourself concrete goals day by day.

Also, and finally, the new tools offered by Apple can now allow you to keep under control these values ​​in minutes, with a simple and immediate configuration.

Some opinions about Calabash-iOS

For what concerns iOS my colleagues and I have been using Calabash-iOS for a year now, with mixed feelings.
Here is a totally subjective opinion about Pros and Cons of Calabash-iOS

Pros:

  • Conciseness of the Gherkin language
  • Capability of querying webviews with CSS selectors
  • Access to all the object property values via Ruby
  • built-in Jenkins-Ready output (xml and HTML test reports, mainly)
  • Performance (on <= iOS 6)
  • It does not uniquely rely on accessibilityIdentifiers (as KIF does)
  • Actively mantained

Cons:

  • It’s not an Apple-backed project : functionalities change significantly from OS to OS
  • Test fail randomly under certain circumstances and, in particular, when dealing with repeated scrolling on a UIScrollView (due to a poor implementation of the scroll/swipe functions)
  • On iOS 7, it relies on UIAutomation, thus…
  • …terrible performance on iOS 7 (see above)
  • Once again, quite a Pain-in-the-ass to make it work on iOS 7
  • Finding the good query for your element usually requires much trial-and-error via the calabash-ios console (Frank provides a nice UI tool for that task, but it’s not merged into Calabash-iOS yet)

Truth to be told, at this stage, the performance impact of relying on UIAutomation is deal breaker for me, so, on the next project we’ll be using KIF, which appears to be also used in some Google projects.

How to resolve “Unable to start status bar server” when launching GHUnit Tests from command line after upgrading to XCode 5

After upgrading to XCode 5 my Jenkins Continuous Integration machine over at Xebia stopped executing command-line GHUnit tests under some apparently random conditions. The console output was as follows:

The reason of the exception looks pretty much the same I had to deal with some months ago (and solved in a previous post).

Well, it turns out that after the XCode upgrade, after quitting an iOS 5.x or iOS 6.x simulator instance, the SpringBoard daemon (along with many others) does not get removed, thus preventing our test target to instantiate a status bar. Interestingly enough, this behaviour does not occur when quitting an iOS 7.0 simulator.

That said, in order to fix the issue, I added the following line to the RunTests.sh script:

The complete RunTests.sh script is available at this public gist.

Introducing SMWheelControl

Today I am proud to announce the availability of a new Pod for iOS which will be included in my forthcoming app.

SMWheelControl

SMWheelControl is an iOS control allowing the selection of an item from a 360° spinning wheel with a smooth inertial rotation.

The code, released under the BSD 3-clause license, is loosely based on the tutorial “How To Create a Rotating Wheel Control with UIKit” published on this Ray Wenderlich’s post by Cesare Rocchi

As usual, you can insert it into your podfile by adding

Some howto follows.

Usage

Initialization and data source

Instantiate the control with a classical - (id)initWithFrame:(CGRect)rect and add a target as you usually do with a control, e.g.:

Then add a dataSource:

and implement the following methods (the dataSource should conform to the SMWheelControlDataSource):

For instance:

When the wheel ends snapping to the closest slice, if you added a target, then it will receive the event UIControlEventValueChanged, and the selector you specified will be executed.

About the Builder Pattern in Objective-C

When dealing with complex object creation in an iOS application you may feel the need for a cleaner and more fluent approach.

During my latest development my colleague @alexiskinsella set up a pattern based on providers in order to mimic the factory behaviour we often find in languages such as Java.

Recently, in the occasion of a side project, I am studying a slightly different approach, based on this article by Matthias Wessendorf.

What I am willing to do is an image builder which creates UIImages on which a GPUImageFilter is applied.

The result I came to is as follows:

The Builder itself (implementation)

The Configuration object (header)

 Using a Builder with an inline Configuration

This should make for a quite readable code with a reduced number of lines of code in the method that invokes the builder.