Getting Started With the Swift iOS Feature Flag

This is another post I wrote for the Rollout blog. You can find the original right here.

This post was a lot of fun to write since I hadn’t done any IOS development in a few years.


Mobile users expect more. They want their applications to be as stable as yesterday while looking and acting more and more like tomorrow. How do you keep up? How can you reliably test and push new features without risking a disastrous release?

Feature toggles (also known as feature flags) are one way. They provide app developers with a way to add new behavior to an application and then enable or disable it without deploying a new release.

So how do feature toggles work? Add some new behavior to the application, wrap it in a boolean, default it to “off,” and then flip it when it’s safe, right?

There’s more to it than that. Effectively using feature flags requires understanding feature flag strategy and tactics.

I’ll get you to your first iOS feature flag quickly, and then give you a deeper understanding of feature flags and how to avoid creating technical debt when you are using them.

This tutorial assumes familiarity with basic iOS concepts and the ability to set up and use Xcode. While I’ll use an iPhone simulator for testing the application, you can use whatever method you feel most comfortable with. I’ll be using the latest version of Xcode, which is 9.3.1 at the time of this writing, and Swift 4.1.

The source code for the completed project is available here.

A Basic Feature Toggle

Let’s start with the basic single view iOS application offered by Xcode 9.

select xcode project for feature flags

We’ll add a Label to the application’s single view like below:

Add label to Swift feature toggle application

We’ll add the label to the viewDidLoad() method of our ViewController, with the name GreetingLabe, and assign a greeting to it.

We could set the default value in the UILabel definition if we want, but we’ll define it explicitly throughout the tutorial to make the behavior easy to see.

We don’t need to make any further changes to the sample code. Let’s build and run the application.

Test Swift iOS application

 

We have a basic iOS app to work with. We’ll use feature toggles to modify the application’s greeting.

An iOS Feature Toggle

So let’s imagine we want to replace our greeting with a different one depending on the season.

A fundamental mechanism would be a boolean flag.

When we build and run this version we see the new greeting below:

Feature toggle in Swift iOS application

And we have our first feature toggle!

But this means modifying, building, and getting a release through the App Store whenever we want to change our greeting.

Modifying a configuration file would be a bit simpler and shave a little bit of time and effort off the release cycle.  Let’s create a property list and add our toggle in the form of a configuration property to it.

Feature flag in iOS plist

We have a property list named featureflag.plist. In it, there is one parameter: a boolean flag named isNewYear.

We’ll load it and use the property to set our flag. We’ll load the file in the controller, even though that’s not what we would do in production code, to keep things simple.

Now we can toggle the value of isNewYear to YES or NO via the properties file, and we’ll see the proper greeting.

The plist gets us out of modifying code when we want to toggle a feature, but we still need to build and release.

Let’s look at a better way to change, and more importantly, manage feature toggles.

Getting Started With Rollout

First, you’ll need to create a free Rollout account here.

Once that’s done, sign in to your Rollout account and create a new application.

Rollout new Feature Toggle iOS Application
Be sure to select iOS, as shown above.

Next, you’ll see instructions for adding Rollout to your application.

Install feature toggle api iOSFirst, download rox.zip, unzip it, and add the rox directory to your project’s directory tree.

Next, add RoxSdk.xcodeproj and ROXCore.framework to your project.

Then, select Add Files to… from the Project Navigator.

add files to projectNow, select the files from the RoxSdk directory in the zip file output.

select rollout files

 

You’ll see ROXCore.framework icon in the Project Navigator. Add those files.

Next, we need to remove the framework from the project’s linked frameworks. Select your project’s name at the top of Navigator tab.

Select feature flag project

 

 

And scroll down in the application information page to Linked Frameworks and Libraries.

Xcode linked frameworks

 

 

Next, select ROXCore.framework and then click the minus to remove it.

We want to add it back to embedded binaries. Click the plus in Embedded Binaries.

embedded binaries

Then, select ROXCore.framework and ROX.frameworkiOS and click Add.

Last, we need to set up a build step to strip out unneeded libraries from our production application.

First, add a script build phase:

Add script

Then locate the strip_frameworks.sh script:

Locate script

And drag it into the script target:

Drag in script

Initialize the API

The Xcode project is ready now, and we can initialize the API.

Finally, click Setup SDK back at the Rollout dashboard.

Setup Feature Toggle SDK

Add the import ROX declaration at the top of AppDelegate.swift.

ROllout assigned a unique initialization key to our application. Add ROX.setup() to didFinishLaunchingWithOptions. The top of AppDelegate.swift should look similar to this:

Now we can run the application to initialize Rollout. Click Activate App on the Rollout dashboard. After the application builds and runs, you are rewarded with this:

Feature flag success

Add a Managed Feature Flag

Let’s create a feature flag and register it with Rollout. If we look at our Rollout dashboard and check flags, we see this:
Create Spring Feature Toggle image
There are no flags, and there is no way to add one. That’s because we create them from our application, not from the dashboard.

In Swift, feature flags are RoxFlags, and are managed in RoxContainers.

First, add this class to the project:

We’ve created a single flag named isNewYear with a default value of true.

We register the container with the API before calling Rox.setup(). Make this change to AppDelegate:

We’re registering the container with Rollout. The first argument to register() is a name that rollout will associate with it.

Run the application and then go to the Flags menu item in the Rollout dashboard.

Feature Flag in Rollout DashboardThe new flag is there. We see the container name and the flag name in the dashboard.

Reading a Managed Feature Flag

Next, we need to update our code to use the RoxFlag instead of the property list.

Rollout retrieves feature flag values asynchronously and caches them. It extracts the latest value from the cache on startup while initiating a fetch from the network in parallel.

This means that the first time we run our application, we will immediately get the default value for our flag (false for toggles unless we override), and then the value set at Rollout upstream will be retrieved sometime later.

Since we want to see the value of the flag before we load our view, we need to do a little bit of extra work. This will also teach us a bit more about the Rollout API.

We’re going to add something to our call to ROX.setup().

First, we create a RoxOptions. This object holds configuration settings that we can pass to the API when we initialize it. One of those options, onConfigurationFetched, is a callback for when the latest configuration is successfully fetched from Rollout.

When our callback is executed, we use NotificationCenter to notify any interested objects that new information has been retrieved.

There are a few advantages to using NotificationCenter instead of trying to call our view directly:

  • Since this callback will be called on startup, our ViewController probably hasn’t been created yet.
  • If we add more controllers to the application, later things will start to get complicated.
  • Threading issues are delegated to listeners (as we’ll see).

Next, we need to make some changes in ViewController.swift.

ViewDidLoad() is now subscribing to update events and delegating them to a method named UpdateLabels()

We moved setting the value of our label to UpdateLabels(). In it, we get a reference to AppDelegate so we can access its copy of the flags and check them. However, we have to dispatch this task to the main thread because only the UI thread can modify the view.

We check the value of isNewYear and set the label appropriately. RolloutFlags() also has an enabled block, but since we need to set the label back if the flag is toggled from “on “to “off,” the if/else logic makes more sense.

 

Managing a Feature Flag

We manage flags by adding them to experiments. An experiment is a scheme for controlling flags (and other variables) in production.

First, click on Production in the left-hand side menu and then click Experiments. This will bring up a screen with a Create Experiment button. Click that and fill out the new experiment window appropriately.


Select Set Audience.

 

And we see a console for setting flags to true, false, or split. Leave it set to False.

If we run our application now, we see “Hello, World!”

Next, change it to True and restart the application.

Feature toggle in Swift iOS application

We see the Happy New Year greeting!

Flip it back to false and click the phone’s home button. Then tap on the application icon to open it again. It flips back to Hello World! 

We can change the behavior of the application without touching code and releasing a new version. We can even alter it while the application is running on a client’s device.

Before we move on, let’s take a look at the experiment on the console again. Flip the flag from true to split.

Split Settings for a Feature Toggle

This option allows us to distribute a change to a percentage of users, hence the term “experiment.” If you play with it now, you’ll need to completely start and stop the application to see different settings to overcome the API’s caching.

This is the power of feature flags!

Extra Credit: Configurations

Tying the contents of a label to a true/false flag is an admittedly contrived example, but it kept the tutorial code focused and simple.

Let’s take a look at another mechanism for setting a label. Rollout supports managing configuration values from the dashboard.

Let’s add a new field to Flags.

RoxConfigurationString is exactly what it sounds like.

Build and run the application again, and then go back to the Rollout dashboard.

Under Production and Configurations, we see our new value.

Feture toggle configuration

If we click on it, we can set it to a value like so:

set feature toggle value

 

Select >= for the criteria, and enter Happy New Year! for the value.

Then we need to make a small code change. Change updateLabels() to use the value of our new member:

And run the app. We see Happy New Year!

Let’s change it.

Set Feature Toggle to w00t

Close and open the application. No need to restart or rebuild: our notification mechanism with handle the change.

Feature toggle developers say w00t!

We can change our application config with Rollout!

Conclusion

This guide demonstrates how to get started with Rollout with iOS and Swift. The API supports any iOS platform that runs Swift, including Apple TV. Rollout’s documentation has details on how you can do a great deal more with flags, configuration settings, experiments, versions, and grouping users.

You now have an understanding of feature flag management and how it can improve your iOS code.  You’ve seen how it can help you manage projects and eliminate unnecessary releases. Get to work!

The Spring Feature Toggle: Your Guide to Getting Started Quickly

This is a post I wrote for Rollout, a tech company that has a system for managing feature toggles in enterprise applications. The original post is here.

When it comes to agile development and “moving fast and breaking stuff,” many people think of REST APIs. Decomposing services into manageable building blocks with clearly defined interfaces is a good step in designing any large system. Even if one doesn’t necessarily wish to be “agile,” REST microservices are an effective design pattern.

But wouldn’t it be nice to separate “move fast and break stuff” into two parts and throw the second one away?

Feature toggles (also known as feature flags) can help with that. They provide us with a way to add new behavior to an application and then enable or disable the new behavior without deploying a different version. Toggles give us immediate advantages when implementing a REST microservice. We can toggle new behavior for a subset of users or only enable it after deploying a new client application.

So we add a feature toggle to our configuration file or the command line, default it to “off,” and wait until later to flip it, right?

Does that describe a complete solution? Not really. Updating a configuration file isn’t always more straightforward than deploying a new release and adding a boolean flag for each new feature seems like a bit of a hack.

There is a better way. There’s feature flag management. Instead of using conditionals that will inevitably turn into technical debt, you can include these toggles as part of a strategy for improving your code and your ability to support it.

Let’s explore feature toggles in a REST service written with Spring Boot. We’ll start with a simple flag and build it into a fully managed feature flag with Rollout’s secure feature management system.

This tutorial assumes familiarity with basic Spring concepts and the ability to set up a development environment. While we will look at several Spring components, we’ll leave whether you run your application from Gradle, Maven, and IDE, etc. up to you.

The source code for the completed project is available here.

A Basic Feature Toggle

Let’s start with a straightforward Boot application.

We have an interface that supplies a greeting.

And a handler class that implements it.

We’ll create a controller with a single request mapping.

Finally, there is the main class to run the service.

We can use Curl to test this service, but any test client will do.

Above, we see our response with the standard HTTP headers.

A Spring Feature Toggle

So let’s imagine we want to replace this greeting with a different one depending on the season.

Spring already has tools for solving this problem. After all, dependency injection and programmatic configuration are two of the main reasons Spring has gained a lot of traction in the Java development community.

First, we’ll add a property to our configuration. We’ll use application.properties for the sake of simplicity and add a new parameter to the file.

Next, we create a new implementation of our GreetingHandler.

Then we’ll modify our controller to accept a handler via dependency injection.

Lastly, we add configuration code to the main class.

If holidaySeason is true, Spring overrides the primary bean, StandardGreetingHandler, with HolidayGreetingHandler.

If we run this version with the current configuration, everything looks the same.

But when we set feature.toggle.holidaySeason=true and restart the application, we see the new greeting.

We’ve added our first feature flag. The value of feature.toggle.holidaySeason controls our application’s behavior. We can load the desired controller by modifying application configuration without deploying new code.

Managing Spring Feature Toggles Centrally

Spring Properties are, at best, a limited version of feature flag management. They require modifying and distributing configuration files to toggle features. Many organizations manage their configurations like software with version control, packaging, and testing. Changing configuration requires a release cycle and it should.

Let’s look at a better way to manage feature toggles.

Getting Started With Rollout

First, you’ll need to create a free Rollout account here.

Once that’s done, sign in to your Rollout account and create a new application.

Create New App dialog on Rollout.io
Be sure to select Java and Java Server, as shown above.

Next, you’ll see instructions for adding Rollout to your application. Use the dropdowns to select Java and Java Server to see instructions like these:

Rollout Feature Toggle Installation Instructions

Your application will be assigned a unique initialization key.

Add the Rollout library to your dependencies. At the time of this writing, the current version of the rox-java-server library is 2.0.3. Here are my Gradle build dependencies for both Spring Boot and Rollout:

Initialize the API

Now we need to add the call to Rox.setup() to initialize the SDK with the application key. This requires some additional thought in a Spring application, though.

Rollout’s API is asynchronous. It uses okHttp to make REST requests for application information, including the feature toggles that we’ll add later. If we attempt to access our feature toggles before initialization has been completed, we may get an incorrect value. We need to make sure that Rollout is completely initialized and our feature toggles have been updated before Spring uses them to decide how to set up our application.

A Spring Feature Toggle Class

Let’s create a new component and use it to initialize Rollout. It will have code to wait until the Rollout initialization is complete before the application finishes loading.

Then we’ll continue to set the class up for managing flags.

This class adds two bits of functionality to our application.

Rox.setup() accepts an optional RoxOptions class. We built one that installs Rollout API’s ConfigurationFetchedHandler callback, which is called after Rollout’s configuration is retrieved.

The callback sets a CountDownLatch after the Rollout is fully initialized. We also wrapped the call to initializeRox() in a static AtomicBoolean in case the condition is instantiated in more than one place.

Second, we’re implementing the getMatchOutcome() method in SpringBootCondition. We’ve hard-coded it to return false for now. This SpringBootCondition class will be loaded when it is referenced in a @Conditional annotation. This class isn’t complete yet, but it’s good enough for this first step. We’ll point our application at it so Spring loads it and initializes the API.

Our previous revision uses the @ConditionalOnProperty to read Spring properties to decide which handler to load. We need to change to an annotation that can look at code instead of configuration. @Conditional does this. A new instance of RolloutCondition is created for each annotation that refers to it, which is why we set up the AtomicBoolean to ensure that initialization is only done once.

Selecting a Spring Controller From a Feature Toggle

Replace the @ConditionalOnProperty annotation on getGreetingHandler() and move the @Primary bean annotation to this method.

On getStandardGreetingHandler(), replace @ConditionalOnProperty with @ConditionalOnMissingbean. If the HolidayGreetingHandler is not created, we’ll fall through to the standard implementation.

Back on the Rollout website, click Next for the prompt to build and run your application.

Build and Run Dialog to initialize Spring Feature Toggle

Build and run it, and after a few moments you’ll see this message:
Feature Toggle Application Initialized for Spring Feature Toggle

Implementing a Managed Spring Feature Toggle

With the return value of getMatchOutcome() set to false, we see the standard greeting when we run our app. Now, let’s turn that return value into a managed feature flag.

If we look at our Rollout dashboard and check flags, we see this:
Create Spring Feature Toggle image

There are no flags and there is no way to create one. That’s because we create them from our application, not from the dashboard.

In Java, managed flags are RoxFlags. These flags are members of a RoxContainer, which is registered with the Rollout API.

Let’s make a few changes to RolloutCondition.

First, add a variable declaration toward the top and an implements qualification to the class definition.

Next, add a call to Rox.register() to iniitalizeRox():

Finally, change matchOutcome() to use the feature toggle.

RoxContainer is an interface with no methods. By having RolloutCondition implement it, we can pass it to Rox.register() inside initializeRox(). The call to register() accepts a String that acts as a namespace. We used Flags.

Then we added a single RoxFlag member named holidaySeason. Managed flags must be public so Rollout can see them.

Last, we modified getMatchOutcome() to return the result of holidaySeason.isEnabled(), which is a boolean value.

Run the application again and then look for your feature toggle in the Rollout dashboard.

Spring Feature Toggle Dashboard on Rollout.io

Flags.holidaySeason is there!

We’re ready to start using our flag from the management console.

Managing a Feature Flag

We manage flags by adding them to experiments. An experiment is a scheme for controlling flags (and other variables) in production.

Click on Production in the left-hand side menu and then click Experiments. This will bring up a screen with a Create Experiment button. Click that and then fill out the new experiment window appropriately.

New Experiment Dialog on Rollout.io
Select Set Audience.

Experiment Dashboard

And we see a console for setting flags to true, false, or split.

If we run our tests now, we see that holidaySeason is false.

Let’s change it to true and restart the service.

When we run our tests again, the results are different!

We can change the behavior of our application without touching code or configuration files.

Before we wrap up, let’s take a look at the experiment on the console again. Flip the flag from true to split.

Split Settings for a Feature Toggle

We don’t just have the ability to change the application behavior from the console; we can also experiment (hence the name) with how often the application loads the different greeting handler.

This is the power of feature flags.

Conclusion

This guide demonstrates how to get started with Rollout in a Java project. Rollout’s documentation has details on how you can do a great deal more with flags, experiments, and groupings.

You now have an understanding of feature flag management and how it can improve your Java code.  You’ve seen how it can help you manage projects and eliminate unnecessary deployments. Get to it!

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑