iOS Configuration API
Monitor offers three configuration options for iOS: Cloud (zero-config), JSON file, and Programmatic API. You can also combine them for a hybrid approach.
Token Setup
Before configuring protections, set up your ByteHide Project Token. You have four options (listed by resolution priority):
Option A: Environment Variable (Recommended)
Configure BYTEHIDE_TOKEN in your Xcode scheme:
- Edit Scheme > Run > Arguments > Environment Variables
- Add:
BYTEHIDE_TOKEN=your-project-token
You can also use BYTEHIDE_MONITOR_TOKEN which takes the highest priority.
Option B: JSON Configuration File
Create monitor-config.json in your project root:
{
"apiToken": "bh_your_project_key"
}{
"apiToken": "bh_your_project_key"
}Make sure the file is included in your app target's Copy Bundle Resources. Get your project key at cloud.bytehide.com.
Option C: Info.plist
Add to your Info.plist:
<key>ByteHideMonitor</key>
<dict>
<key>APIToken</key>
<string>${BYTEHIDE_TOKEN}</string>
</dict><key>ByteHideMonitor</key>
<dict>
<key>APIToken</key>
<string>${BYTEHIDE_TOKEN}</string>
</dict>Then configure the BYTEHIDE_TOKEN environment variable (same as Option A). Or hardcode the token directly (not recommended for production).
Option D: Code Configuration
Pass the token programmatically via BHMMonitor.configure() (see Option C: Programmatic Configuration below).
Token Resolution Order
Monitor resolves the project token in this order:
BYTEHIDE_MONITOR_TOKENenvironment variableBYTEHIDE_TOKENenvironment variableapiTokenvalue inmonitor-config.jsonByteHideMonitor > APITokeninInfo.plist- Code configuration (
BHMMonitor.configure())
Configuration Options Overview
| Option | Best For | Code Required | Offline Support |
|---|---|---|---|
| Cloud (Zero-Config) | Most projects | None | No (fetches from API) |
| JSON File | Offline / auditable config | None | Yes |
| Programmatic API | Custom actions / dynamic logic | Yes | Yes |
Option A: Cloud Configuration (Zero-Config)
The simplest approach. Monitor fetches its configuration automatically from your ByteHide dashboard.
How it works:
- During build, the token is validated and configuration is embedded
- At runtime, Monitor auto-initializes using
+load()(beforemain()) - Applies protections configured in your dashboard
- Periodically syncs for configuration updates
Setup:
Configure your token (see above) and build:
xcodebuild -workspace YourApp.xcworkspace -scheme YourApp -configuration Releasexcodebuild -workspace YourApp.xcworkspace -scheme YourApp -configuration ReleaseNo code changes needed. Monitor initializes automatically.
Option B: JSON Configuration
Define protections locally in a JSON file. Ideal for offline environments or version-controlled configuration.
Create monitor-config.json in your project root:
{
"apiToken": "bh_YourToken",
"logLevel": "info",
"enableConsoleLogs": true,
"enableFileLogs": false,
"protections": [
{
"type": "DebuggerDetection",
"action": "close"
},
{
"type": "JailbreakDetection",
"action": "close"
},
{
"type": "SimulatorDetection",
"action": "log"
},
{
"type": "ClockTampering",
"action": "log"
},
{
"type": "MemoryDumpDetection",
"action": "close"
},
{
"type": "ProcessInjection",
"action": "close"
}
]
}{
"apiToken": "bh_YourToken",
"logLevel": "info",
"enableConsoleLogs": true,
"enableFileLogs": false,
"protections": [
{
"type": "DebuggerDetection",
"action": "close"
},
{
"type": "JailbreakDetection",
"action": "close"
},
{
"type": "SimulatorDetection",
"action": "log"
},
{
"type": "ClockTampering",
"action": "log"
},
{
"type": "MemoryDumpDetection",
"action": "close"
},
{
"type": "ProcessInjection",
"action": "close"
}
]
}Monitor loads this file automatically. No code required.
Option C: Programmatic Configuration
Configure Monitor directly in code for maximum control, custom actions, and dynamic logic.
Swift
import ByteHideMonitor
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BHMMonitor.configure { config in
// Token (optional if already embedded)
config.useToken("bh_YourToken")
// Set log level
config.logLevel(.info)
// Register a custom action
config.registerCustomAction("notify") { threat in
print("ALERT: \(threat.threatDescription ?? "Unknown threat")")
// Send notification, log to analytics, etc.
}
// Enable all protections with a default action
config.enableAllProtections(.log)
// Or configure individual protections
config.enableProtection(.debuggerDetection, action: .close)
config.enableProtection(.jailbreakDetection, customAction: "notify")
}
return true
}
}import ByteHideMonitor
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BHMMonitor.configure { config in
// Token (optional if already embedded)
config.useToken("bh_YourToken")
// Set log level
config.logLevel(.info)
// Register a custom action
config.registerCustomAction("notify") { threat in
print("ALERT: \(threat.threatDescription ?? "Unknown threat")")
// Send notification, log to analytics, etc.
}
// Enable all protections with a default action
config.enableAllProtections(.log)
// Or configure individual protections
config.enableProtection(.debuggerDetection, action: .close)
config.enableProtection(.jailbreakDetection, customAction: "notify")
}
return true
}
}Objective-C
#import <ByteHideMonitor/ByteHideMonitor.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[BHMMonitor configure:^(BHMMonitorConfiguration *config) {
// Token
[config useToken:@"bh_YourToken"];
// Set log level
[config logLevel:BHMLogLevelInfo];
// Register a custom action
[config registerCustomAction:@"notify" handler:^(BHMThreatContext *threat) {
NSLog(@"ALERT: %@", threat.threatDescription);
}];
// Enable all protections
[config enableAllProtections:BHMActionTypeLog];
// Or configure individual protections
[config enableProtection:BHMProtectionModuleTypeDebuggerDetection
action:BHMActionTypeClose];
}];
return YES;
}
@end#import <ByteHideMonitor/ByteHideMonitor.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[BHMMonitor configure:^(BHMMonitorConfiguration *config) {
// Token
[config useToken:@"bh_YourToken"];
// Set log level
[config logLevel:BHMLogLevelInfo];
// Register a custom action
[config registerCustomAction:@"notify" handler:^(BHMThreatContext *threat) {
NSLog(@"ALERT: %@", threat.threatDescription);
}];
// Enable all protections
[config enableAllProtections:BHMActionTypeLog];
// Or configure individual protections
[config enableProtection:BHMProtectionModuleTypeDebuggerDetection
action:BHMActionTypeClose];
}];
return YES;
}
@endAvailable Action Types
| Type | Description | Recommended Use |
|---|---|---|
| none | Detect only, take no action | Testing, initial analysis |
| log | Log the incident | Production monitoring |
| close | Close the application immediately | Maximum security |
| erase | Wipe sensitive data and close | Critical data (finance, health) |
| custom | Execute your custom handler | Business-specific logic |
Hybrid Configuration (Recommended for Production)
Combine cloud/JSON configuration with programmatic overrides:
BHMMonitor.configure { config in
// Base config is already loaded from cloud or monitor-config.json
// Override only what you need
config.registerCustomAction("criticalAlert") { threat in
sendPushNotification("Security Alert", threat.threatDescription ?? "Unknown threat")
exit(1)
}
// Add extra protection with custom action
config.enableProtection(.memoryDumpDetection, customAction: "criticalAlert")
}BHMMonitor.configure { config in
// Base config is already loaded from cloud or monitor-config.json
// Override only what you need
config.registerCustomAction("criticalAlert") { threat in
sendPushNotification("Security Alert", threat.threatDescription ?? "Unknown threat")
exit(1)
}
// Add extra protection with custom action
config.enableProtection(.memoryDumpDetection, customAction: "criticalAlert")
}Configuration loading order:
- Monitor loads from
monitor-config.json(if present in bundle) - If no JSON file, fetches configuration from cloud (dashboard)
- Applies programmatic configuration (if
Monitor.configureis called) - Programmatic configuration overrides automatic configuration
Auto-Initialization
Monitor for iOS auto-initializes automatically using the Objective-C +load() method, which executes before main().
How it works:
- During build: The token is validated and configuration is embedded in the app bundle
- During execution: Monitor initializes automatically before your code runs, validating the app signature and activating configured protections
No additional code is required unless you use Option C (programmatic configuration).
Info.plist Advanced Configuration
Beyond the API token, you can configure additional Monitor settings directly in Info.plist:
<key>ByteHideMonitor</key>
<dict>
<key>APIToken</key>
<string>${BYTEHIDE_TOKEN}</string>
<key>LogLevel</key>
<string>info</string>
<key>EnableMobileProtections</key>
<true/>
<key>DefaultAction</key>
<string>close</string>
<key>DisableAutoInit</key>
<false/>
</dict><key>ByteHideMonitor</key>
<dict>
<key>APIToken</key>
<string>${BYTEHIDE_TOKEN}</string>
<key>LogLevel</key>
<string>info</string>
<key>EnableMobileProtections</key>
<true/>
<key>DefaultAction</key>
<string>close</string>
<key>DisableAutoInit</key>
<false/>
</dict>| Key | Type | Default | Description |
|---|---|---|---|
APIToken | string | — | ByteHide project token (supports ${ENV_VAR} syntax) |
LogLevel | string | "info" | Minimum log level: "debug", "info", "warning", "error" |
EnableMobileProtections | boolean | true | Enable default mobile protections (Jailbreak, Simulator, Debugger, ClockTampering) |
DefaultAction | string | "log" | Default action for all protections: "none", "log", "close", "erase" |
DisableAutoInit | boolean | false | Disable automatic initialization before main() |
Disabling Auto-Initialization
If you need full control over when Monitor starts (for example, to show a splash screen first or wait for user consent), disable auto-initialization and start Monitor manually:
Step 1: Add to Info.plist:
<key>ByteHideMonitor</key>
<dict>
<key>DisableAutoInit</key>
<true/>
</dict><key>ByteHideMonitor</key>
<dict>
<key>DisableAutoInit</key>
<true/>
</dict>Step 2: Initialize manually in your code:
BHMMonitor.configure { config in
config.useToken("bh_your_project_key")
config.enableMobileProtections(.close)
}BHMMonitor.configure { config in
config.useToken("bh_your_project_key")
config.enableMobileProtections(.close)
}Security gap
When auto-initialization is disabled, your app is unprotected between launch and the point where you call BHMMonitor.configure(). Only disable it if you have a specific reason.