Skip to content

Integration

Electric Bolt edited this page Jul 16, 2022 · 11 revisions

Documentation

HOME

UPGRADE 1.4.0 to 2.2.0
UPGRADE 2.1.1 to 2.2.0
UPGRADE 2.2.1 to 3.0.0

INTEGRATION

EXAMPLES
    AppfigurateExample
    ActionExample Extension
    WatchExample
    WatchExample Intent Extension

CONFIGURATION
    APLConfiguration subclass
        Custom executable actions
        Supported property types
            BOOL
            NSInteger
            float
            double
            plain NSString
            encrypted NSString
               Best practice
               String Encryption util
                  Troubleshooting
        UISlider icon types
        Overrides
    Advanced configuration
        App Startup
        Info.plist
        AndroidManifest.xml
        WCSession
    Additional functions
    Display overridden config

SECURITY
    Export compliance
    Best practice
    App Store compliance

TESTING
    Automation testing

Clone this wiki locally

The Appfigurate library can be embedded into your own app in a few easy steps. In this guide, replace any references to quickstart with your own apps target name.

Integrating Appfigurate Library using Objective-C
Integrating Appfigurate Library using Swift

Integrating Appfigurate Library using Objective-C

Step 1: Add new app into Appfigurate Simulator.

Using Xcode, run Appfigurate Simulator.

  • Tap Add app.
  • Select app type iOS.
  • Enter the URL scheme quickstart 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.

Under the OBJ-C LIBRARY INTEGRATION section:

  • Tap Output header then tap Console.
  • Tap Output implementation then tap Console.
  • Tap Output Info.plist snippet then tap Console.

The output will appear in the Xcode console:

Step 2: Add AppfigurateLibrary.xcframework

Note: Appfigurate Library requires Swift to be linked to your app. If your app doesn't already link Swift, the easiest way to do this is to include an empty .swift file.

Choose one of the following integration methods:

Manual integration
Cocoapods integration
Carthage integration
Swift Package Manager integration

Step 2.1 Manual integration

Drag and drop AppfigurateLibrary.xcframework into your project.

Step 2.2 Cocoapods integration

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.

Step 2.3 Carthage integration

  • 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 that 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.

Step 2.4 Swift Package Manager integration

  • Swift Package Manager support requires Xcode 12.0+
  • Add a package dependency File ‣ Swift Packages ‣ Add Package Dependency with the URL https://github.com/electricbolt/appfiguratesdk

Step 3: Create APLConfiguration subclass

In your app, add a new Cocoa Touch class, subclassing APLConfiguration, called Configuration.

In your apps Configuration.h file, paste the .h header file output to the Console in step 1.

@import Foundation;
@import AppfigurateLibrary;

@interface Configuration : APLConfiguration

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

@end

In your apps Configuration.m file, paste the .m implementation file output to the Console in step 1.

#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" \
		"wncfzWUuWIH7C6xMPczJMPpmTNLkq1LhAhGfJMXByHHR4m9dqHO/pQZ1pFqtTSti\n" \
		"ZBw81DQqOHAINQEf1vhJw1b7EMOFUAsS98X32imT9mNC9ya8n8AB2b5giQpef9YJ\n" \
		"PHV0IPUo9t6DUQIOtMG5YLNqrFmp40HpW7r2vGmi8Vh7fCZHFwWS3QvsUqj4tYsr\n" \
		"S3IyVOGfiQXxrEVtfKM/ABtj7oxqe6rr/UYyFfVasqYxnUrL+RgnLieAO88dhtOh\n" \
		"dAHDAZiVMPnJ8CN42XShGNC6i1vQb0tg6op0KpoBCd94tVqB55wa+WpXAc86qF+t\n" \
		"EQIDAQAB\n" \
		"-----END PUBLIC KEY-----\n";
}

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

@end

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

See also subclassing.

Step 4: Edit Info.plist

In your apps Info.plist file (right click, Open As ‣ Source Code). Paste the Info.plist snippet output to the Console in step 1.

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleURLName</key>
		<string>appfigurate.quickstart</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>quickstart</string>
		</array>
	</dict>
</array>

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

See also Advanced configuration - iOS apps without Flutter.

Step 5: Update UIApplicationDelegate

In your apps AppDelegate.m file, include calls to APLApplicationOpenURL and APLDidFinishLaunchingWithOptions

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
	return APLApplicationOpenURL(url);
}

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

See also Advanced configuration - iOS apps without Flutter.

Step 6: Update UIWindowSceneDelegate

If your app targets iPadOS 13+, in your apps SceneDelegate.m file, include a call to APLApplicationOpenURL

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
	NSURL* url = [[[URLContexts allObjects] firstObject] URL];
	if (url != nil) {
		APLApplicationOpenURL(url);
	}
}

See also Advanced configuration - iOS apps without Flutter.

Step 7: Test your configuration subclass

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

  • Compile and run Quickstart to the same Simulator instance that Appfigurate Simulator was run from previously.
  • Press Shift-Cmd-H to get back to the Simulator home screen.
  • Tap the Appfigurate app icon.
  • Tap the Quickstart row. The Simulator screen will briefly flicker as it swaps to the Quickstart app, reads its configuration and swaps back to Appfigurate.
  • Appfigurate will now be displayed and showing the following screen:
  • Since we added a BOOL_PROPERTY for debugLogging and STRING_PROPERTY_LIST_EDIT for serverURL, you can now change these configuration items at runtime. Tap (or long tap for additional options) Apply⌄ to apply the configuration to the Quickstart app.

Integrating Appfigurate Library using Swift

Step 1: Add app using Appfigurate Simulator.

Using Xcode, run Appfigurate Simulator.

  • Tap Add app.
  • Select app type iOS.
  • Enter the URL scheme quickstart 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.

Under the SWIFT LIBRARY INTEGRATION section:

  • Tap Output implementation then tap Console.
  • Tap Output Info.plist snippet then tap Console.

The output will appear in the Xcode console output:

Step 2: Add AppfigurateLibrary.xcframework

Choose one of the following integration methods:

Manual integration
Cocoapods integration
Carthage integration
Swift Package Manager integration

Step 2.1 Swift manual integration

Drag and drop AppfigurateLibrary.xcframework into your project.

Step 2.2 Swift Cocoapods integration

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.

Step 2.3 Swift Carthage integration

  • 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 that 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 the Carthage/Build).

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

Step 2.4 Swift Package Manager integration

  • Add a package dependency File ‣ Swift Packages ‣ Add Package Dependency with the URL https://github.com/electricbolt/appfiguratesdk

Step 3: Create APLConfiguration subclass

In your app, add a new Swift class, subclassing APLConfiguration, called Configuration.

In your apps Configuration.swift file, paste the .swift implementation file output to the Console in step 1.

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 {
		// E4 8B B6 25 EE 01
		return "-----BEGIN PUBLIC KEY-----\n" +
			"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnD67fMex1KkP7kltlNaO\n" +
			"wncfzWUuWIH7C6xMPczJMPpmTNLkq1LhAhGfJMXByHHR4m9dqHO/pQZ1pFqtTSti\n" +
			"ZBw81DQqOHAINQEf1vhJw1b7EMOFUAsS98X32imT9mNC9ya8n8AB2b5giQpef9YJ\n" +
			"PHV0IPUo9t6DUQIOtMG5YLNqrFmp40HpW7r2vGmi8Vh7fCZHFwWS3QvsUqj4tYsr\n" +
			"S3IyVOGfiQXxrEVtfKM/ABtj7oxqe6rr/UYyFfVasqYxnUrL+RgnLieAO88dhtOh\n" +
			"dAHDAZiVMPnJ8CN42XShGNC6i1vQb0tg6op0KpoBCd94tVqB55wa+WpXAc86qF+t\n" +
			"EQIDAQAB\n" +
			"-----END PUBLIC KEY-----\n"
	}

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

}

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

See also Advanced configuration - Subclassing.

Step 4: Edit Info.plist

In your apps Info.plist file (right click, Open As ‣ Source Code). Paste the Info.plist snippet output to the Console in step 1.

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleURLName</key>
		<string>appfigurate.quickstart</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>quickstart</string>
		</array>
	</dict>
</array>

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

See also Advanced configuration - iOS apps without Flutter.

Step 5: Update UIApplicationDelegate

In your apps AppDelegate.m file, include calls to APLApplicationOpenURL and APLDidFinishLaunchingWithOptions

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
	return APLApplicationOpenURL(url)
}

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

See also Advanced configuration - iOS apps without Flutter.

Step 6: Update UIWindowSceneDelegate

If your app targets iPadOS 13+, in your apps SceneDelegate.m file, include a call to APLApplicationOpenURL

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
	if let url = URLContexts.first?.url {
		APLApplicationOpenURL(url)
	}
}

See also Advanced configuration - iOS apps without Flutter.

Step 7: Test your configuration subclass

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

  • Compile and run Quickstart to the same Simulator instance that Appfigurate Simulator was run from previously.
  • Press Shift-Cmd-H to get back to the Simulator home screen.
  • Tap the Appfigurate app icon.
  • Tap the Quickstart row. The Simulator screen will briefly flicker as it swaps to the Quickstart app, reads its configuration and swaps back to Appfigurate.
  • Appfigurate will now be displayed and showing the following screen:
  • Since we added a @BoolProperty for debugLogging and @StringPropertyListEdit for serverURL, you can now change these configuration items at runtime. Tap (or long tap for additional options) Apply⌄ to apply the configuration to the Quickstart app.