iOS SDK Reference

Updated 4 months ago by Archana Singh

This topic explains how to use the Harness Feature Flag SDK in your iOS application. To learn more about using a Feature Flag SDK with an iOS application, clone and run a sample application from the iOS SDK Github repository.

Before You Begin

Prerequisites

  1. Create a feature flag in Harness. Feature flags wrap your code and allow you to manage the feature release in a controlled way. See Create a Feature Flag.
  2. Ensure that you have created your SDK Key. See Create an SDK Key.
  3. Download Harness Feature Flag iOS Client SDK.
  4. An iOS application to test your feature flag. If you do not have your iOS Application, you can download a sample application from the iOS SDK Github repository.

Use Harness Feature Flag SDKs with iOS Applications

Perform the following steps to get started with using the Feature Flags SDK in your iOS application:

Step 1: Install the iOS Feature Flag Client SDK Dependencies

The first step is to install the Feature Flag SDK as a dependency in your application. You can use any of the following methods to install the SDK in your application.

  • Swift Package Manager (SPM)
  • CocoaPods
  • Carthage
Swift Package Manager

The Swift Package Manager is a dependency manager integrated into the swift compiler and Xcode. A dependency consists of a relative or absolute URL to the source of the package and a set of requirements for the version of the package that can be used.

You can install the SDK through Xcode or include it as a dependency in your Package.swift file.

Using Xcode:

To add a package dependency to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the iOS SDK repository clone URL, then select your desired version constraints.

Using Package.swift File:

To include SDK as a dependency in a Package.swift file, add ff-ios-client-sdk to the dependencies section of your Package.swift file.

dependencies: [
.package(url: "https://github.com/drone/ff-ios-client-sdk.git", .upToNextMinor(from: "0.0.5"))
]

Cocoapods

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. CocoaPods is built with Ruby and it will be installable with the default Ruby available on macOS. You can use a Ruby Version manager, however, we recommend that you use the standard Ruby available on macOS.

Perform the following steps to install the dependencies:

  1. If you are using the default Ruby, you need to use sudo when installing the gems.
    $ sudo gem install cocoapods
  2. Once Cocoapods is installed, create a Podfile in your root project folder.
    $ pod init
  3. Import ff-ios-client-sdk to your .xcproject. To do so,  simply addff-ios-client-sdkto your newly created Podfile and save the Podfile changes.
    platform :ios, '10.0'
    use_frameworks!

    target 'MyApp' do
    pod 'ff-ios-client-sdk'
    end
  4.  Install the packages.
    $ pod install

    Ensure that you are using .xcworkspace  instead of your .xcodeproj  to utilize the imported Pods.
Carthage

Carthage is intended to be the simplest way to add frameworks to your Cocoa application. Perform the following steps to integrate ff-ios-client-sdk into your application.

  1. Navigate to the root folder of your project and create a Cartfile. This is the file where you would input all of the dependencies that you plan to use with Carthage.
    $ touch Cartfile
  2. Add the following line to your Cartfile.
    github "drone/ff-ios-client-sdk"
  3. Fetch the source for ff-ios-client-sdk from the repository specified in the Cartfile.
    $ carthage update --no-build

    A new folder Carthage is created at the same location as of Cartfile and  .xcodeproj. In the Carthage folder, Checkout folder is created which has the source code.
  4. Create a project for ff-ios-client-sdk dependency.
    1. Run the following command from your project's root folder:
      //From your project's root folder
      $ cd Carthage/Checkouts/ff-ios-client-sdk
    2. After that, run the following command:
      $ swift package generate-xcodeproj
    3. Or, you can enter it all on the same line.
      //From your project's root folder
      $ cd Carthage/Checkouts/ff-ios-client-sdk && swift package generate-xcodeproj
  5. Build the project and place it in the Build folder next to Checkouts. Run the following command from your project's root folder:
    $ carthage build --use-xcframeworks --platform iOS
  6. In your application targets’ General tab, in the Frameworks, Libraries, and Embedded Content, drag and drop the .xcframework file from the Carthage/Build folder.
  7. In Embed, select Embed & Sign.
  8. Import the ff_ios_client_sdk.
  9. (Optional) When a new version of ff-ios-client-sdk is available and you wish to update this dependency, run:
    $ carthage update --use-xcframeworks --platform iOS

Step 2: Import the Feature Flag Client in Your Application Code

Import the client using the following command:

import ff_ios_client_sdk

Step 3: Initialize the SDK

Now that the SDK is imported, you can configure and initialize it. You should enter your SDK keys when configuring the SDK so that your application is authorized to connect to Harness Feature Flags and retrieve flags for your environment.

initialize(apiKey:configuration:cache:onCompletion:)
let configuration = CfConfiguration.builder().setStreamEnabled(true).build()
let target = CfTarget.builder().setIdentifier("YOUR_ACCOUNT_IDENTIFIER").build()
CfClient.sharedInstance.initialize(apiKey: "YOUR_API_KEY", configuration: configuration, target: target) { (result) in
switch result {
case .failure(let error):
//Do something to gracefully handle initialization/authorization failure
case .success:
//Continue to the next step after successful initialization/authorization
}
}

Step 4: Evaluate Target for Your Feature Flag

Once you have initialized the CF client for a target, evaluate it for your feature flag. A feature flag is evaluated for a particular target.

Evaluation is performed based on the variation types. In case there is no evaluation with the provided ID, the default value is returned. Use the appropriate method to fetch the desired evaluation of a certain type.

String Variation

CfClient.sharedInstance.stringVariation("your_evaluation_id", defaultValue: String?) { (evaluation) in
//Make use of the fetched `String` Evaluation
}

Boolean Variation

CfClient.sharedInstance.boolVariation("your_evaluation_id", defaultValue: Bool?) { (evaluation) in
//Make use of the fetched `Bool` Evaluation
}

Number Variation
CfClient.sharedInstance.numberVariation("your_evaluation_id", defaultValue: Int?) { (evaluation) in
//Make use of the fetched `Int` Evaluation
}

JSON Variation
CfClient.sharedInstance.jsonVariation("your_evaluation_id", defaultValue: [String:ValueType]?) { (evaluation) in
//Make use of the fetched `[String:ValueType]` Evaluation
}

ValueType can be one of the following:

  • ValueType.bool(Bool)
  • ValueType.string(String)
  • ValueType.int(Int)
  • ValueType.object([String:ValueType])

Step 5: Add Method to Register the Events

This method provides a way to register a listener for different events that might be triggered by SDK, indicating a specific change in the SDK.

CfClient.sharedInstance.registerEventsListener() { (result) in
switch result {
case .failure(let error):
//Gracefully handle error
case .success(let eventType):
switch eventType {
case .onPolling(let evaluations):
//Received all evaluation flags -> [Evaluation]
case .onEventListener(let evaluation):
//Received an evaluation flag -> Evaluation
case .onComplete:
//Received a completion event, meaning that the
//SSE has been disconnected
case .onOpen(_):
//SSE connection has been established and is active
case .onMessage(let messageObj):
//An empty Message object has been received
}
}
}
}

Step 6: Shut Down the SDK

When SDK is not needed, for example, when the app is not running, you can shut down the SDK. This can avoid potential memory leaks.

Also, you need to call this method when changing accounts through CfTarget object, in order to re-initialize and fetch Evaluations for the right account.

CfClient.sharedInstance.destroy() 

Step 7: Verify Your Feature Flag

Run the application from your IDE and verify whether the flag variation value displayed on your application page is consistent with the feature flag you created.

Toggle the flag on and off to verify if your application is getting updated.

Public API Methods

You can also use the public API methods to initialize and implement the Feature Flag iOS SDKs. The Public API exposes the following methods that you can utilize:

public func initialize(apiKey:configuration:target:cache:onCompletion:)

public func stringVariation(evaluationId:defaultValue:completion:)

public func boolVariation(evaluationId:defaultValue:completion:)

public func numberVariation(evaluationId:defaultValue:completion:)

public func jsonVariation(evaluationId:defaultValue:completion:)

public func registerEventsListener(events:onCompletion:)

public func destroy()

Sample Code for iOS Application

Here is a sample code for using Harness Feature Flag SDKs with the iOS application. To learn more about using the sample iOS application, see the iOS SDK Github repository.

import UIKit
import ff_ios_client_sdk
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSLog("Start")
let config = CfConfiguration.builder()
.setStreamEnabled(true)
.build()
let target = CfTarget.builder().setIdentifier("Harness").build()
CfClient.sharedInstance.initialize(
apiKey: "YOUR_API_KEY,
configuration:config,
target: target
) { [weak self] result in
switch result {
case .failure(let error):
NSLog("End: Error \(error)")
case .success():
NSLog("Init: Ok")
CfClient.sharedInstance.boolVariation(evaluationId: "EVALUATION_ID", { (eval) in
print("Value: \(eval!)")
})
CfClient.sharedInstance.registerEventsListener() { (result) in
switch result {
case .failure(let error):
print(error)
case .success(let eventType):
switch eventType {
case .onPolling:
print("Event: Received all evaluation flags")
case .onEventListener(let evaluation):
print("Event: Received an evaluation flag, \(evaluation!)")
case .onComplete:
print("Event: SSE stream has completed")
case .onOpen:
print("Event: SSE stream has been opened")
case .onMessage(let messageObj):
print(messageObj?.event ?? "Event: Message received")
}
}
}
}
}
}
override func viewWillDisappear(_ animated: Bool) {
CfClient.sharedInstance.destroy()
NSLog("End: Ok")
super.viewWillDisappear(animated)
}
}


Please Provide Feedback