Functions
The following functions are available globally.
-
Target availability: iOS apps.
You must call
APLApplicationDidFinishLaunchingWithOptions()
in your app delegate’sapplication:didFinishLaunchingWithOptions:
method.Objective-C example
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { APLApplicationDidFinishLaunchingWithOptions(launchOptions); return YES; }
Swift example
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { APLApplicationDidFinishLaunchingWithOptions(launchOptions) return true }
Declaration
Objective-C
extern void APLApplicationDidFinishLaunchingWithOptions( NSDictionary *_Nullable launchOptions)
Swift
func APLApplicationDidFinishLaunchingWithOptions(_ launchOptions: [AnyHashable : Any]?)
-
Target availability: iOS apps.
You must call
APLApplicationOpenURL()
in your app delegate’sapplication:openURL:options:
method.Objective-C example
- (BOOL) application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { return APLApplicationOpenURL(url); }
Swift example
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { return APLApplicationOpenURL(url) }
Declaration
Objective-C
extern BOOL APLApplicationOpenURL(NSURL *_Nonnull url)
Swift
func APLApplicationOpenURL(_ url: URL) -> Bool
-
Target availability: watchOS apps.
You must call
APLApplicationDidFinishLaunching()
in your extension’s delegateapplicationDidFinishLaunching
method.Objective-C example
- (void) applicationDidFinishLaunching { APLApplicationDidFinishLaunching(); }
Swift example
func applicationDidFinishLaunching() { APLApplicationDidFinishLaunching() }
Declaration
Objective-C
extern void APLApplicationDidFinishLaunching(void)
Swift
func APLApplicationDidFinishLaunching()
-
Target availability: watchOS apps.
Receives configuration commands and payloads from the paired iPhone’s Appfigurate app.
If your watch app has its own
WCSessionDelegate
, then call theAPLSessionDidReceiveMessage()
function from within yoursession:didReceiveMessage:replyHandler:
method (see examples below). If your watch app does not have its ownWCSessionDelegate
then you do not need to do anything - Appfigurate library installs aWCSessionDelegate
and callsAPLSessionDidReceiveMessage()
automatically.Objective-C example
- (void) session: (WCSession*) session didReceiveMessage: (NSDictionary<NSString*,id>*) message replyHandler: (void (^)(NSDictionary<NSString*,id>*)) replyHandler { NSDictionary* reply = APLSessionDidReceiveMessage(message); if (reply != nil) replyHandler(reply); else ...
Swift example
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { let reply = APLSessionDidReceiveMessage(message) if reply != nil { replyHandler(reply) } else { ...
Declaration
Objective-C
extern NSDictionary *_Nullable APLSessionDidReceiveMessage( NSDictionary<NSString *, id> *_Nonnull message)
Swift
func APLSessionDidReceiveMessage(_ message: [String : Any]) -> [AnyHashable : Any]?
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Returns the version of the Appfigurate library in the format “major.minor.patch”. e.g. “5.1.2”
Declaration
Objective-C
extern NSString *_Nonnull APLVersion(void)
Swift
func APLVersion() -> String
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Registers a delegate method that will be called back when Appfigurate has updated the configuration of the app or extension. See also
APLAddConfigurationUpdatedBlock()
function for block based callback.Declaration
Objective-C
extern void APLAddConfigurationUpdatedListener(id<APLConfigurationUpdated> _Nonnull target)
Swift
func APLAddConfigurationUpdatedListener(_ target: any APLConfigurationUpdated)
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Registers a block that will be called back when Appfigurate has updated the configuration of the app or extension. Returns an opaque object to act as the observer. See also
APLRemoveConfigurationUpdatedBlock()
.Declaration
Objective-C
extern id<NSObject> _Nonnull APLAddConfigurationUpdatedBlock( APLConfigurationUpdatedBlock _Nonnull block)
Swift
func APLAddConfigurationUpdatedBlock(_ block: @escaping APLConfigurationUpdatedBlock) -> any NSObjectProtocol
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Unregisters the delegate method that will be called back when Appfigurate has updated the configuration of the application. You may optionally call this method before the target is deallocated.
Declaration
Objective-C
extern void APLRemoveConfigurationUpdatedListener( id<APLConfigurationUpdated> _Nonnull target)
Swift
func APLRemoveConfigurationUpdatedListener(_ target: any APLConfigurationUpdated)
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Unregisters the block that will be called back when Appfigurate has updated the configuration of the application. You must call this method before the block is deallocated. The observer argument is the result of
APLAddConfigurationUpdatedBlock()
.Declaration
Objective-C
extern void APLRemoveConfigurationUpdatedBlock(id<NSObject> _Nonnull observer)
Swift
func APLRemoveConfigurationUpdatedBlock(_ observer: any NSObjectProtocol)
-
Target availability: iOS apps.
When integrating with third party remote configuration providers, you must specify a block that is called back whenever Appfigurate requires the current value of a third party remote configuration property. The block will be called for each
REMOTE_BOOL_PROPERTY
,REMOTE_XXXX_PROPERTY_EDIT
macro (Objective-C) or@RemoteBoolProperty
,@RemoteXXXXPropertyEdit
property wrapper (Swift) you have specified in your APLConfiguration subclass.REMOTE_BOOL_PROPERTY/@RemoteBoolProperty ‣ APLRemotePropertyTypeBool ‣ [NSNumber boolValue] ‣ BOOL/Bool REMOTE_INT_PROPERTY_EDIT/@RemoteIntPropertyEdit ‣ APLRemotePropertyTypeInt ‣ [NSNumber integerValue] ‣ NSInteger/Int REMOTE_DOUBLE_PROPERTY_EDIT/@RemoteDoublePropertyEdit ‣ APLRemotePropertyTypeDouble ‣ [NSNumber doubleValue] ‣ double/Double REMOTE_STRING_PROPERTY_EDIT/@RemoteStringPropertyEdit ‣ APLRemotePropertyTypeString ‣ NSString ‣ NSString/String
propertyKey
is the name of the remote property in the third party provider’s system.propertyType
will be one of theAPLRemotePropertyType
enumerations indicating the exact type of the property.defaultValue
will be the value specified by the subclasses-[APLConfiguration reset]
method.Objective-C Firebase Remote Config example
APLFetchRemoteConfiguration(^NSObject* (NSString* propertyKey, APLRemotePropertyType propertyType, NSObject* defaultValue) { if (propertyType == APLRemotePropertyTypeString) { return [self.remoteConfig configValueForKey: propertyKey].stringValue; } else if (propertyType == APLRemotePropertyTypeBool) { return [NSNumber numberWithBool: [self.remoteConfig configValueForKey: propertyKey].boolValue]; } else // APLRemotePropertyTypeInt || APLRemotePropertyTypeDouble { return [self.remoteConfig configValueForKey: propertyKey].numberValue; } });
Swift Firebase Remote Config example
APLFetchRemoteConfiguration { propertyKey, propertyType, _ in if propertyType == .string { return self.remoteConfig.configValue(forKey: propertyKey).stringValue! as NSObject } else if propertyType == .bool { return self.remoteConfig.configValue(forKey: propertyKey).boolValue as NSObject } else { // .int || .double return self.remoteConfig.configValue(forKey: propertyKey).numberValue as NSObject } }
Objective-C Launch Darkly example
APLFetchRemoteConfiguration(^NSObject* (NSString* propertyKey, APLRemotePropertyType propertyType, NSObject* defaultValue) { if (propertyType == APLRemotePropertyTypeBool) { return [NSNumber numberWithBool: [[LDClient get] boolVariationForKey: propertyKey defaultValue: [((NSNumber*) defaultValue) boolValue]]]; } else if (propertyType == APLRemotePropertyTypeInt) { return [NSNumber numberWithInteger: [[LDClient get] integerVariationForKey: propertyKey defaultValue: [((NSNumber*) defaultValue) integerValue]]]; } else if (propertyType == APLRemotePropertyTypeDouble) { return [NSNumber numberWithDouble: [[LDClient get] doubleVariationForKey: propertyKey defaultValue: [((NSNumber*) defaultValue) doubleValue]]]; } else { return [[LDClient get] stringVariationForKey: propertyKey defaultValue: (NSString*) defaultValue]; } });
Swift Launch Darkly example
APLFetchRemoteConfiguration { propertyKey, propertyType, defaultValue in if propertyType == .bool { return NSNumber(value: (LDClient.get()!.boolVariation(forKey: propertyKey, defaultValue: (defaultValue as! NSNumber).boolValue))) } else if propertyType == .int { return NSNumber(value: (LDClient.get()!.intVariation(forKey: propertyKey, defaultValue: (defaultValue as! NSNumber).intValue))) } else if propertyType == .double { return NSNumber(value: (LDClient.get()!.doubleVariation(forKey: propertyKey, defaultValue: (defaultValue as! NSNumber).doubleValue))) } else { return NSString(string: LDClient.get()!.stringVariation(forKey: propertyKey, defaultValue: (defaultValue as! String))) } }
Declaration
Objective-C
extern void APLFetchRemoteConfiguration(NSObject *_Nonnull (^_Nullable)( NSString *_Nonnull, APLRemotePropertyType, NSObject *_Nonnull))
Swift
func APLFetchRemoteConfiguration(_: ((String, APLRemotePropertyType, NSObject) -> NSObject)?)
-
Target availability: iOS apps.
You must call the
APLFlushRemoteConfiguration()
function anytime your third party remote configuration provider has received & activated remote configuration. Forces the callback passed intoAPLFetchRemoteConfiguration()
to be invoked to reload the new values of third party remote configuration properties.Objective-C Firebase Remote Config example
[remoteConfig activateWithCompletion: ^(BOOL changed, NSError* error) { ... APLFlushRemoteConfiguration(); }];
Swift Firebase Remote Config example
remoteConfig.activate { changed, error in ... APLFlushRemoteConfiguration() }
Objective-C Launch Darkly example
[LDClient startWithConfiguration:config context:context startWaitSeconds:5.0 completion:^(bool timedOut) { ... APLFlushRemoteConfiguration(); }]; [[LDClient get] observeAllKeysWithOwner: self handler:^(NSDictionary<NSString *,LDChangedFlag *> *handler) { ... APLFlushRemoteConfiguration(); }];
Swift Launch Darkly example
LDClient.start(config: config, startWaitSeconds: 5.0) { timedOut in if !timedOut { ... APLFlushRemoteConfiguration() } } LDClient.get()?.observeAll(owner: self) { keys in ... APLFlushRemoteConfiguration() }
Declaration
Objective-C
extern void APLFlushRemoteConfiguration(void)
Swift
func APLFlushRemoteConfiguration()
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Saves the configuration persisted in the keychain into temporary storage. Some apps have functionality to erase the keychain to reset apps back to “factory defaults”, which has the side effect of removing any Appfigurate configuration persisted in the keychain. Usage example:
Objective-C example
- (void) eraseKeychain { APLSaveConfiguration(); NSArray* secItemClasses = @[(__bridge id) kSecClassGenericPassword, (__bridge id) kSecClassInternetPassword, (__bridge id) kSecClassCertificate, (__bridge id) kSecClassKey, (__bridge id) kSecClassIdentity]; for (id secItemClass in secItemClasses) { NSDictionary *spec = @{(__bridge id)kSecClass: secItemClass}; SecItemDelete((__bridge CFDictionaryRef)spec); } APLRestoreConfiguration(); }
Declaration
Objective-C
extern void APLSaveConfiguration(void)
Swift
func APLSaveConfiguration()
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
Restores the configuration from temporary storage back into the keychain. See also
APLSaveConfiguration()
for more details and usage example.Declaration
Objective-C
extern void APLRestoreConfiguration(void)
Swift
func APLRestoreConfiguration()
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
The application or framework that links the static AppfigurateLibrary.xcframework must define a function with the following prototype that returns the
Class
(Objective-C) orAnyClass
(Swift) of yourAPLConfiguration
subclass.Objective-C example
- (Class) _Nonnull APLConfigurationClass(void) { return [ExampleConfiguration class]; }
Swift example
@_cdecl("APLConfigurationClass") func APLConfigurationClass() -> AnyClass { return ExampleConfiguration.self }
Declaration
Objective-C
extern Class _Nonnull APLConfigurationClass(void)
Swift
func APLConfigurationClass() -> AnyClass
-
Target availability: iOS XCUITest automation testing.
Sends a message to the application under test, and waits for a response. You can only call this function from within an XCUITest automation test case.
name
is the message name, must not benil
or blank, maximum 255 bytes after encoding with UTF-8.plist
is a property list object ornil
.timeout
is the duration in seconds you expect to receive a response, otherwise anAppfigurateLibraryException
is thrown (minimum of 3.0 seconds). Returns a property list object ornil
from the application under test. See alsoAPLAutomationMessageReceivedBlock()
.Objective-C example
- (void) testLogin { XCUIApplication *app = [XCUIApplication new]; [app launch]; APLAutomationSendMessage(@"SetResponseData", @{ @"Request": @"/login", @"Status": [NSNumber numberWithInt: 200], @"Response": @"{'Customer':'2311569'}" }, 3.0); ...
Swift example
func testLogin() { var app = XCUIApplication() app.launch APLAutomationSendMessage("SetResponseData", [ "Request": "/login", "Status": 200, "Response": "{'Customer':'2311569'}" ], 3.0) ...
Declaration
Objective-C
extern id _Nullable APLAutomationSendMessage(NSString *_Nonnull name, id _Nullable plist, NSTimeInterval timeout)
Swift
func APLAutomationSendMessage(_ name: String, _ plist: Any?, _ timeout: TimeInterval) -> Any?
-
Target availability: iOS XCUITest automation testing.
Register a single block (in the application under test) that will be invoked when an XCUITest automation test case has sent a message using the
APLAutomationSendMessage()
function. The-[APLConfiguration allowInvalidSignatures]
method in the application under test must returnYES
for the message to be processed. See alsoAPLAutomationSendMessage()
.Objective-C example
APLAutomationMessageReceivedBlock(^NSObject* (NSString* name, id data) { if ([name isEqualToString: @"SetResponseData"]) { [MockedHttpInterceptor setResponse: data]; } return nil; });
Swift example
APLAutomationMessageReceivedBlock { (name: String, data: Any) -> NSObject in if name == "SetResponseData" { MockedHttpInterceptor.setResponse(data) } return nil }
Declaration
Objective-C
extern void APLAutomationMessageReceivedBlock( id _Nullable (^_Nullable message)(NSString *_Nonnull, id _Nullable))
Swift
func APLAutomationMessageReceivedBlock(_ message: ((String, Any?) -> Any?)?)
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
If
logLevel
isAPLLogLevelDebug
and logging is enabled (see alsoAPLSetLogging()
) then logsmsg
with optional parameters to the console. IflogLevel
isAPLLogLevelError
then logsmsg
with optional parameters to the console even if logging is disabled. You should prefer to use APLDEBUG or APLERROR macros for Objective-C. See alsoAPLLogS()
for Swift.Declaration
Objective-C
extern void APLLog(APLLogLevel logLevel, NSString *_Nonnull msg, ...)
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
If
logLevel
is.debug
and logging is enabled (see alsoAPLSetLogging
) then logsmsg
to the console. IflogLevel
is.error
then logsmsg
the console even if logging is disabled. See alsoAPLLog
for Objective-C.Declaration
Objective-C
extern void APLLogS(APLLogLevel logLevel, NSString *_Nonnull msg)
Swift
func APLLogS(_ logLevel: APLLogLevel, _ msg: String)
-
Target availability: iOS apps, iOS app extensions, watchOS apps, watchOS app extensions.
When
YES
, Appfigurate library debugging messages will be output to the console. The default isNO
. It is best practice to distribute applications via TestFlight and the App Store with logging set toNO
. Also seeAPLLogging
key in theInfo.plist
file.Declaration
Objective-C
extern void APLSetLogging(BOOL logging)
Swift
func APLSetLogging(_ logging: Bool)