# Custom executable actions

## Action UI

Allows the custom executable action to be executed by Appfigurate. Any configuration properties you modify in the action method are persisted. Actions appear below properties in the Appfigurate UI.

![](https://1008176080-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fw1fcw3dvtSrfUh3YtO9Z%2Fuploads%2FCjxEhNUGuCXZkk76Zhw1%2FAction.png?alt=media\&token=0a32ce58-e631-4a94-945d-6f917f17d8ed)

{% tabs %}
{% tab title="Swift" %}

> Swift prototype

As you cannot annotate a Swift method with a property wrapper, your action methods must be specified manually.

Replace `XXX` with the name of your action (e.g. `freshInstall`)

```swift
func XXXDescription() -> String
func XXXAction()
func XXXRestart() -> Bool
```

If you return `true` from your `XXXRestart()` method, then the app will be restarted after the action method is executed.

> Swift example

```swift
@objcMembers class Configuration: APLConfiguration {

    func freshInstallDescription() -> String {
        return "Resets application to fresh install state"
    }
    
    func freshInstallAction() {
        let defs = UserDefaults.standard
        let dict = defs.dictionaryRepresentation()
        for key in dict.keys {
            defs.removeObject(forKey: key)
        }
        defs.synchronize()
    }

    func freshInstallRestart() -> Bool {
        return false
    }
    ...
```

{% endtab %}

{% tab title="Objective-C" %}

> Objective-C prototype

```objectivec
ACTION_METHOD(actionName, description, restart) { ... }
```

If `restart` is `YES` then the app will be restarted after the action method is executed.

> Objective-C example

```objectivec
@implementation Configuration

ACTION_METHOD(freshInstall, "Resets application to fresh install state", NO) {
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSDictionary* dict = [defs dictionaryRepresentation];
    for (id key in dict) {
        [defs removeObjectForKey: key];
    }
    [defs synchronize];
}
...
```

{% endtab %}

{% tab title="Kotlin" %}

> Kotlin prototype

```kotlin
@ActionMethod(description, restart)
```

If `restart` is `true` then the app will be restarted after the action method is executed.

> Kotlin example

```kotlin
@ActionMethod(description = "Resets application to fresh install state", restart = false)
fun freshInstall() {
    var preferences = context.getSharedPreferences("storage", Context.MODE_PRIVATE)
    var editor = preferences.edit()
    editor.clear()
    editor.apply()
}
```

{% endtab %}

{% tab title="Java" %}

> Java prototype

```java
@ActionMethod(description, restart)
```

If `restart` is `true` then the app will be restarted after the action method is executed.

> Java example

```java
@ActionMethod(description = "Resets application to fresh install state", restart = false)
public void freshInstall() {
    SharedPreferences preferences = context.getSharedPreferences("storage", MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();
    editor.clear();
    editor.apply();
}
```

{% endtab %}

{% tab title="Dart" %}
When an action is executed in the underlying native [<mark style="color:blue;">`APLConfiguration`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html) (iOS) or [<mark style="color:blue;">`nz.co.electricbolt.appfiguratelibrary.Configuration`</mark>](https://www.electricbolt.co.nz/api/android/nz/co/electricbolt/appfiguratelibrary/Configuration.html) (Android) subclass, Flutter is also notified. Override the [<mark style="color:blue;">`actionExecuted(action)`</mark>](https://pub.dev/documentation/appfigurateflutter/latest/appfigurateflutter/APLNativeConfiguration/actionExecuted.html) method in [<mark style="color:blue;">`APLNativeConfiguration`</mark>](https://pub.dev/documentation/appfigurateflutter/latest/appfigurateflutter/APLNativeConfiguration-class.html) as follows to receive the action:

> Dart example

```dart
import 'package:appfigurateflutter/appfigurateflutter.dart';

class ExampleConfiguration extends APLNativeConfiguration {
  factory ExampleConfiguration() => _instance;

  static final ExampleConfiguration _instance = ExampleConfiguration._internal();

  ExampleConfiguration._internal();

  @override
  void actionExecuted(String action) {
    if (action == 'freshInstall') {
      ...
    }
  }
...
```

{% endtab %}

{% tab title="JavaScript" %}
When an action is executed in the underlying native [`APLConfiguration`](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html) (iOS) or [`nz.co.electricbolt.appfiguratelibrary.Configuration`](https://www.electricbolt.co.nz/api/android/nz/co/electricbolt/appfiguratelibrary/Configuration.html) (Android) subclass, React Native is also notified. Subscribe to an event emitter to receive the action:

> JavaScript example

```javascript
import {
  NativeModules,
  NativeEventEmitter,
} from 'react-native';

const {Appfigurate} = NativeModules;
const AppfigurateEvents = new NativeEventEmitter(NativeModules.Appfigurate);

AppfigurateEvents.addListener('APLConfigurationUpdated', result => {
  if (result.APLConfigurationUpdatedAction == "freshInstall") {
    ...
  }
});
```

{% endtab %}
{% endtabs %}
