# Encrypted String

{% tabs %}
{% tab title="Swift" %}
The default value of an encrypted `String` is "". You **must** change the default value of the property by assigning a new plain text value in an overridden [<mark style="color:blue;">`reset`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html#/c:objc\(cs\)APLConfiguration\(im\)reset) method.
{% endtab %}

{% tab title="Objective-C" %}
The default value of a `NSString` is @"". You **must** change the default value of the property by assigning a new plain text value in an overridden [<mark style="color:blue;">`reset`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html#/c:objc\(cs\)APLConfiguration\(im\)reset) method.

`NSString` properties should be declared in your [<mark style="color:blue;">`APLConfiguration`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html) subclass header file as follows:

```objectivec
@import AppfigurateLibrary;

@interface Configuration : APLConfiguration

@property(nonatomic, strong) NSString* propertyName;
...
```

{% endtab %}

{% tab title="Dart" %}
The flutter [<mark style="color:blue;">`APLNativeConfiguration`</mark>](https://pub.dev/documentation/appfigurateflutter/latest/appfigurateflutter/APLNativeConfiguration-class.html) class defers to the underlying platform [<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 to read property values.
{% endtab %}

{% tab title="JavaScript" %}
The React Native module `AppfigurateModule` class defers to the underlying platform [<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 to read property values.
{% endtab %}
{% endtabs %}

This page describes encrypted strings. Appfigurate also supports [plain textual strings](https://docs.electricbolt.co.nz/configuration-subclasses/supported-property-types/plain-string).

## **Local properties**

### **Editable List UI**

Allows a string property to be changed in Appfigurate by allowing the user to select from a predefined list of valid choices. The user can customize the list adding by additional values using a text field and an optional regular expression validating input.&#x20;

![](https://1008176080-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fw1fcw3dvtSrfUh3YtO9Z%2Fuploads%2FlVyzD1sOPsr9f9tFFM5N%2FEncryptedStringListEdit.png?alt=media\&token=7a7b91fc-c737-4429-9759-5b29f2c97677)

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

> Swift @EncryptedStringPropertyListEdit prototype

<pre class="language-swift"><code class="lang-swift">@EncryptedStringPropertyListEdit(regex, description, encrypted, restart, values)
var propertyName: <a data-footnote-ref href="#user-content-fn-1">String</a>
</code></pre>

The `encrypted` parameter of `EncryptedStringPropertyListEdit` must be the result of calling the `ENCRYPTED()` function. e.g.

```swift
... description: "url", encrypted: ENCRYPTED(), restart: ...
```

> Swift @EncryptedStringPropertyListEdit example

<pre class="language-swift"><code class="lang-swift">    @EncryptedStringPropertyListEdit(regex: #"https://[\w\.-]+\.appfigurate.io/.*"#, description: "url", encrypted: ENCRYPTED(), restart: false, values: [
        "Dev":ENCRYPTED_STRING("https://dev.appfigurate.io/list","H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="),
        "Test":ENCRYPTED_STRING("https://test.appfigurate.io/list","PL+UtWB9WHuO7...aX5BdNqEcbmQE="),
        "Prod":ENCRYPTED_STRING("https://m.appfigurate.io/list","IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")])
    var url: <a data-footnote-ref href="#user-content-fn-1">String</a>
    
    override func reset() {
        url = "https://m.appfigurate.io/list"
    }
    ...
</code></pre>

### **ENCRYPTED\_STRING function**

> Swift ENCRYPTED\_STRING prototype

```swift
func ENCRYPTED_STRING(_ plaintext: String, _ ciphertext: String) -> String
```

For an iOS app (or watchOS and it's companion iOS app) where the `APLConfiguration` subclass has one public key use the `ENCRYPTED_STRING` function for each list item in the `@EncryptedStringPropertyListEdit`.

The first parameter of the `ENCRYPTED_STRING` function is the plaintext, and will be used by `DEBUG` builds. The second parameter of the `ENCRYPTED_STRING` macro is the ciphertext, and will be used by `RELEASE` builds. To generate the ciphertext, use the [source editor extension for Xcode](https://docs.electricbolt.co.nz/appfigurate-se-user-guide/xcode-source-editor-extension) or [AppfigurateSE app](https://docs.electricbolt.co.nz/appfigurate-se-user-guide/manual-encryption).

> Swift ENCRYPTED\_STRING example

```swift
    @EncryptedStringPropertyListEdit(regex: #"https://[\w\.-]+\.appfigurate.io/.*"#, description: "url", encrypted: ENCRYPTED(), restart: false, values: [
        "Dev":ENCRYPTED_STRING("https://dev.appfigurate.io/list","H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="),
        "Test":ENCRYPTED_STRING("https://test.appfigurate.io/list","PL+UtWB9WHuO7...aX5BdNqEcbmQE="),
        "Prod":ENCRYPTED_STRING("https://m.appfigurate.io/list","IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")])
    var url: String
```

### **ENCRYPTED function**

> Swift ENCRYPTED prototype

```swift
func ENCRYPTED() -> Bool
```

Used in conjunction with the `@EncryptedStringPropertyListEdit` property wrapper. The `encrypted` parameter of `@EncryptedStringPropertyListEdit` must be the result of calling the `ENCRYPTED()` function. e.g.

```swift
... description: "url", encrypted: ENCRYPTED(), restart: ...
```

The function returns `true` if the calling app has been compiled in RELEASE mode or `false` if the calling app has been compiled in DEBUG mode.

### ENCRYPTED function & Swift compiler ‣ Optimizing for Size

{% hint style="warning" %}
**Warning:** The ENCRYPTED function will behave incorrectly if the apps build settings `Swift compiler - Code generation ‣ Optimization Level` is set to `Optimize for Size` (-Osize). The default Swift compiler optimization levels are `No Optimization` for `DEBUG` builds and `Optimize for Speed` -Ospeed for `RELEASE` builds. If you must use -Osize, then implement your own `isEncrypted()` style function as follows:
{% endhint %}

> Swift isEncrypted example

```swift
func isEncrypted() {
#if DEBUG
	return false
#else
	return true
#end
}
```

Then call your own `isEncrypted()` function instead of the provided `ENCRYPTED()` function e.g.

```swift
... description: "url", encrypted: isEncrypted(), restart: ...
```

{% endtab %}

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

> Objective-C ENCRYPTED\_STRING\_PROPERTY\_LIST\_EDIT prototype

```objectivec
ENCRYPTED_STRING_PROPERTY_LIST_EDIT(propertyName, regex, description, restart, ...)
```

> Objective-C ENCRYPTED\_STRING\_PROPERTY\_LIST\_EDIT example

```objectivec
@import AppfigurateLibrary;

@interface Configuration : APLConfiguration

@property(nonatomic, strong) NSString* url;

@end

@implementation Configuration

ENCRYPTED_STRING_PROPERTY_LIST_EDIT(url, @"https://[\\w\\.-]+\\.appfigurate.io/.*", @"url", NO, @{
    @"Dev": ENCRYPTED_STRING(@"https://dev.appfigurate.io/list",@"H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="), 
    @"Test": ENCRYPTED_STRING(@"https://test.appfigurate.io/list",@"PL+UtWB9WHuO7...aX5BdNqEcbmQE="), 
    @"Prod": ENCRYPTED_STRING(@"https://m.appfigurate.io/list",@"IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")});
    
- (void) reset {
    self.url = @"https://m.appfigurate.io/list";
}
...
```

### **ENCRYPTED\_STRING macro**

> Objective-C ENCRYPTED\_STRING prototype

```objectivec
ENCRYPTED_STRING(plaintext, ciphertext)
```

For an iOS app (or watchOS and it's companion iOS app) where the `APLConfiguration` subclass has one public key use the `ENCRYPTED_STRING` macro for each list item in the `ENCRYPTED_STRING_PROPERTY_LIST_EDIT`.

The first parameter of the `ENCRYPTED_STRING` macro is the plain text, and will be used by `DEBUG` builds. The second parameter of the `ENCRYPTED_STRING` macro is the ciphertext, and will be used by `RELEASE` builds. To generate the ciphertext, use the [source editor extension for Xcode](https://docs.electricbolt.co.nz/appfigurate-se-user-guide/xcode-source-editor-extension) or [AppfigurateSE app](https://docs.electricbolt.co.nz/appfigurate-se-user-guide/manual-encryption).

> Objective-C ENCRYPTED\_STRING example

```objectivec
ENCRYPTED_STRING_PROPERTY_LIST_EDIT(url, @"https://[\\w\\.-]+\\.appfigurate.io/.*", @"url", NO, @{
    @"Dev":ENCRYPTED_STRING(@"https://dev.appfigurate.io/list",@"H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="), 
    @"Test":ENCRYPTED_STRING(@"https://test.appfigurate.io/list",@"PL+UtWB9WHuO7...aX5BdNqEcbmQE="), 
    @"Prod":ENCRYPTED_STRING(@"https://m.appfigurate.io/list",@"IxrJFFUarMg6p...E7OWYOC2uJ1AQ==")});
```

{% endtab %}

{% tab title="Dart" %}

> Dart prototype

```dart
String get propertyName => nativeString('propertyName');
```

> Dart example

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

public class Configuration extends APLNativeConfiguration {

    String get url => nativeString('url');
    ...
```

{% endtab %}

{% tab title="JavaScript" %}

> JavaScript example

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

const {Appfigurate} = NativeModules;

...

let url = await Appfigurate.nativeValue("url");
```

{% endtab %}
{% endtabs %}

## Encryption best practice

### **iOS and watchOS**

Using `ENCRYPTED_STRING` guarantees that the plaintext of the list item values will not be included in the resulting application binary, only the ciphertext. The ciphertext can only be decrypted by Appfigurate using the correct private key.

You can verify that the plain text is not included in the RELEASE application binary using the macOS `strings` tool as follows:

> Terminal

```bash
> cd ~/Library/Developer/Xcode/DerivedData/AppfigurateWorkspace-esajjxyazigjunfteipthjfiobut/Build/Products/Release-iphoneos/AppfigurateExample (iOS).app
> strings AppfigurateExample | grep "https://dev.appfigurate.io/list"     // no results
> strings AppfigurateExample | grep "H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ=="     // prints H7o9Lgqd4RgMJ...rtJQGh8DiiSAQ==
```

It is best practice to use `ENCRYPTED_STRING` to encrypt sensitive information such as server urls (e.g. internal test environments), rather than expose them as plain text.

### Flutter

Ensure you have read the encryption best practices for [iOS and watchOS](#ios-and-watchos) sections.

### React Native

Ensure you have read the encryption best practices for [iOS and watchOS](#ios-and-watchos) sections.

[^1]: You should leave this as String, and not String! or String?. Any value assigned to this instance variable will be ignored, instead set the default value in the reset method.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.electricbolt.co.nz/configuration-subclasses/supported-property-types/encrypted-string.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
