Appfigurate™️
HomeDocumentation
  • Introducing Appfigurate™️ 3
  • Getting Started
    • Getting Started
    • Examples
    • Upgrade guide
      • v1.4.0 to v2.2.0
      • v2.1.1 to v2.2.0
      • v2.2.1 to v3.0.0
      • v3.2.1 to v4.0.0
    • iOS native app integration
      • iOS app extension integration
    • watchOS app integration
      • watchOS app extension integration
    • Android native app integration
    • Mobile Flutter integration
      • Flutter iOS
      • Flutter Android
    • React Native integration
      • iOS native module integration
      • Android native module integration
      • JavaScript integration
    • Third party remote configuration providers
      • Firebase Remote Config
      • Launch Darkly
      • Other third party remote configuration providers
  • Configuration subclasses
    • Supported property types
      • Boolean
      • Integer
      • Float
      • Double
      • Plain String
      • Encrypted String
    • Custom executable actions
    • Slider icon types
  • Additional reading
    • Info.plist options
    • AndroidManifest.xml options
    • Displaying overridden configuration
    • Security
      • Best practice
      • Encryption
      • Export compliance
      • App Store compliance
      • PrivacyInfo.xcprivacy
      • Rotating your private key
  • Automation testing
    • iOS native app automation testing
    • Android native automation testing
  • API
    • iOS and watchOS API
    • Android API
    • Mobile Flutter API
    • React Native API
  • Appfigurate User Guide
    • Introduction
    • Main menu
    • Select app
    • Add app
    • Import app
    • Install example apps
    • Settings
      • Passcode Lock
      • Restore
      • Backup
      • Delete all apps and Settings
      • Analytics
    • Edit app
    • Configure app
    • Permissions
  • Appfigurate SE user guide
    • Introduction
    • Manual encryption
      • ENCRYPTED_STRING macro/function
      • ENCRYPTED_STRING_IOS_WATCHOS macro/function
    • Setup iOS Simulator app
    • Setup Android Emulator app
    • Xcode source editor extension
      • Troubleshooting
    • Real device cloud testing services
      • BrowserStack
  • LEGAL
    • License Agreement
    • Privacy Policy
    • Release History
    • Third party notices
Powered by GitBook
On this page
  • Prerequisites
  • Add AppfigurateLibrary.xcframework to the iOS app target
  • Add new app into Appfigurate Simulator
  • Output source code snippets
  • Create APLConfiguration subclass
  • Edit Info.plist
  • UIApplicationDelegate
  • For apps using UIWindowSceneDelegate
  • Test your iOS app
  1. Getting Started

iOS native app integration

Integrating Appfigurate Library into iOS native apps

Previousv3.2.1 to v4.0.0NextiOS app extension integration

Last updated 5 months ago

iOS native apps can be developed in both Swift and Objective-C.

For Mobile Flutter apps, jump to . For React Native apps, jump to .

Prerequisites

You must have the following:

  • Xcode 15.2+

  • iOS SDKs and associated Simulators.

  • AppfigurateSE macOS app.

  • Appfigurate Simulator app installed into one or more iOS Simulators (use the for easy 1 click installation).

  • Your iOS app must target iOS 13.0+ in order to link Appfigurate Library.

Add AppfigurateLibrary.xcframework to the iOS app target

Choose one of the following integration methods (all of which are compatible with both Swift and Objective-C):

Add a package dependency File ‣ Add Package Dependencies with the URL https://github.com/electricbolt/appfiguratesdk

Clone the github repo:

git clone 
https://github.com/electricbolt/appfiguratesdk.git

Drag and drop AppfigurateLibrary.xcframework into your project.

Note: Cocoapods integration is deprecated and support will be removed in the upcoming Appfigurate 4 release. Swift Package Manager is the suggested replacement.

Note: Ensure you are running Cocoapods 1.9.0 or later (to provide support for distribution of XCFrameworks).

Add the following to your apps Podfile:

pod 'AppfigurateLibrary'

Run either the pod install or pod update from the terminal to download and build the AppfigurateLibrary pod.

Note: Cathage integration is deprecated and support will be removed in the upcoming Appfigurate 4 release. Swift Package Manager is the suggested replacement.

Add the following to your apps Cartfile:

github "electricbolt/appfiguratesdk"

Run the carthage update from the terminal to download the appfiguratesdk repository into your apps Carthage/Checkouts directory.

Note: Carthage will output the following error:

*** Skipped building appfiguratesdk due to the error:
Dependency "appfiguratesdk" has no shared framework schemes

If you believe this to be an error, please file an issue with the maintainers at https://github.com/electricbolt/appfiguratesdk/issues/new

You can ignore this error as we will be using the Carthage/Checkouts directory (instead of Carthage/Build).

Drag and drop AppfigurateLibrary.xcframework from the Carthage/Checkouts/ directory into your project.

Add new app into Appfigurate Simulator

Run Appfigurate in the iOS Simulator.

Tap ≡ Add app.

Select app type iOS.

Enter a URL scheme that will be used by Appfigurate to launch your app in order to read or apply configuration. The URL scheme must be 4-64 ASCII characters in length and must be unique to your app. e.g. YOUR-APP-URLSCHEME

Tap Add app.

Output source code snippets

Tap ≡ YOUR-APP-URLSCHEME.

The Edit app screen will be displayed.

Under the SWIFT/IOS LIBRARY INTEGRATION section:

Tap Output implementation then tap Clipboard.

Open the macOS Console.app. Select the iOS Simulator device in the left hand pane. Type process:appfigurate in the search box in the top right.

In Appfiguate Simulator app, under the OBJ-C/IOS LIBRARY INTEGRATION section:

Tap Output header then tap Console.

Tap Output implementation then tap Console.

Create APLConfiguration subclass

In Xcode, tap File ‣ New ‣ New "Configuration.swift" file from Clipboard.

Swift Configuration example

import Foundation
import AppfigurateLibrary

@objcMembers class Configuration: APLConfiguration {

    @BoolProperty(description: "Log debug output to console", restart: false)
    var debugLogging: Bool

    @StringPropertyListEdit(regex: #"https://[\w\.-]+\.yourappserver.com/.*"#, description: "Application server url", restart: false, values: ["Dev":"https://dev.yourappserver.com/api", "Prod":"https://www.yourappserver.com/api"])
    var serverURL: String

    override func allowInvalidSignatures() -> Bool {
        return !ENCRYPTED()
    }

    override func publicKey() -> String {
        // 41 36 87 71 0D 05
        return "-----BEGIN PUBLIC KEY-----\n" +
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4TZnKfGeXttN7Rr3eiAZ\n" +
            ...
            "ywIDAQAB\n" +
            "-----END PUBLIC KEY-----\n";
    }

    override func reset() {
        debugLogging = true
        serverURL = "https://www.yourappserver.com/api"
    }

}

@_cdecl("APLConfigurationClass")
func APLConfigurationClass() -> AnyClass {
    return Configuration.self
}

Objective-C Configuration header example

@import Foundation;
@import AppfigurateLibrary;

@interface Configuration : APLConfiguration

@property(nonatomic, strong) NSString* serverURL;
@property(nonatomic, assign) BOOL debugLogging;

@end

Objective-C Configuration implementation example

#import "Configuration.h"

@implementation Configuration

BOOL_PROPERTY(debugLogging, @"Log debug output to console", NO)
STRING_PROPERTY_LIST_EDIT(serverURL, @"https:\\/\\/[\\w\\.-]+\\.yourappserver.com/.*", @"URL of app server", NO, @{@"Dev":@"https://dev.yourappserver.com/api", @"Prod":@"https://www.yourappserver.com/api"});

- (BOOL) allowInvalidSignatures {
#if DEBUG
    return YES;
#else
    return NO;
#endif
}

- (NSString*) publicKey {
    // E4 8B B6 25 EE 01
    return @"-----BEGIN PUBLIC KEY-----\n" \
        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnD67fMex1KkP7kltlNaO\n" \
        ...
        "EQIDAQAB\n" \
        "-----END PUBLIC KEY-----\n";
}

- (void) reset {
    self.debugLogging = NO;
    self.serverURL = @"https://www.yourappserver.com/api";
}

@end

Class APLConfigurationClass(void) {
    return [Configuration class];
}

Edit Info.plist

Info.plist example

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>appfigurate.YOUR-APP-URLSCHEME</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>YOUR-APP-URLSCHEME</string>
        </array>
    </dict>
</array>

If you already have an existing CFBundleURLTypes array in your Info.plist file, then insert just the <dict> ... </dict> portion.

UIApplicationDelegate

Swift UIApplicationDelegate example

import AppfigurateLibrary

...

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // When your app opens a URL while running or suspended in memory.
    return APLApplicationOpenURL(url)
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // After launch.
    APLApplicationDidFinishLaunchingWithOptions(launchOptions)
    return true
}

Objective-C UIApplicationDelegate example

@import AppfigurateLibrary;

...

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    // When your app opens a URL while running or suspended in memory.
    return APLApplicationOpenURL(url);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // After launch.
    APLApplicationDidFinishLaunchingWithOptions(launchOptions);
    return YES;
}

For apps using UIWindowSceneDelegate

Swift UIWindowSceneDelegate example

import AppfigurateLibrary

...

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    // When your app opens a URL while running or suspended in memory.
    if let url = URLContexts.first?.url {
        APLApplicationOpenURL(url)
    }
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // After launch.
    if let url = connectionOptions.urlContexts.first?.url {
        APLApplicationOpenURL(url)            
    }
}

Objective-C UIWindowSceneDelegate example

@import AppfigurateLibrary;

...

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    // When your app opens a URL while running or suspended in memory.
    NSURL *url = [[[URLContexts allObjects] firstObject] URL];
    APLApplicationOpenURL(url);
}

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // After launch.
    NSURL *url = [[[connectionOptions.URLContexts allObjects] firstObject] URL];
    APLApplicationOpenURL(url);
}

Test your iOS app

To test that you've successfully updated your app to use Appfigurate:

  • Compile and run your app to the Simulator instance.

  • Launch the Appfigurate Simulator app.

  • Tap your applications row. The app will be run and made visible, it's configuration read, and then swap back to Appfigurate.

Note: your public key copied into the clipboard in the section above will be different to the public key in the following example.

The function with C calling convention must be implemented in your app otherwise a linker error will be issued. The recommended place to implement is at the bottom of your subclass.

In Xcode, add a new Cocoa Touch class, subclassing , e.g. Configuration

In your apps Configuration.h file, paste the .h header file output to the Console in the section above.

In your apps Configuration.m file, paste the .m implementation file output to the Console in the section above.

Note: your public key copied into the clipboard in the section above will be different to the public key in the following example.

The function must be implemented in your app otherwise a linker error will be issued. The recommended place to implement is at the bottom of your subclass.

In your apps Info.plist file (right click, Open As ‣ Source Code) include the following. Replace the text YOUR-APP-URLSCHEME with your own app's URL Scheme - the same value you added in the section above.

In your apps AppDelegate.swift/.m file, include calls to and . Create any missing delegate methods as appropriate.

If your app has a UIWindowSceneDelegate, in your apps SceneDelegate.swift/m file, include calls to . Create any missing delegate methods as appropriate.

Appfigurate's screen will now be displayed. You can now change the debugLogging and serverURL properties. Tap Apply⌄ to apply the configuration to your app.

Now jump to .

Mobile Flutter integration
React Native integration
AppfigurateSE macOS app
APLConfigurationClass
APLConfiguration
APLConfiguration
APLConfigurationClass
APLConfiguration
APLApplicationOpenURL
APLDidFinishLaunchingWithOptions
APLApplicationOpenURL
Configure app
Supported property types
Output source code snippets
Output source code snippets
Output source code snippets
Output source code snippets
Add new app into Appfigurate Simulator