Configure callbacks on iOS

Prev Next

When App Shielding performs security checks, it can either be configured to exit the application when a security problem is detected (e.g., Exit on hooking frameworks), or it can be configured to notify the application via a callback. By handling the callback, you can, for instance, inform the user about the possible security threat.

Delegate callbacks currently occur when the application registers an observer with PRMShieldEventManager, during application launch, and when the application is moved to the foreground.

Optionally, you can configure App Shielding to provide security check results.

To configure App Shielding to provide security check results

  1. Ensure the relevant security feature is enabled in the configuration (e.g., Check jailbreak), and is not configured to terminate the application when a security problem is detected (e.g., Exit on jailbreak.

  2. Ensure that ShieldSDK.xcframework is included in the project.

  3. Import the ShieldSDK/Shield.h umbrella header into all source files that will interact with the callback API.

  4. Create a class that implements the PRMShieldEventDelegate protocol, as defined in ShieldEvent.h. This protocol defines delegate methods that, when implemented, are called when different security checks are finished.

    The callback methods are triggered on the main thread, so it is possible to perform UI operations directly from the delegate methods.

  5. Register an object of the class implementing the PRMShieldEventDelegate protocol by calling the - addObserver method of the PRMShieldEventManager class. This registration should be performed as early as possible, because many security checks are performed right after application has launched. Ideally, the registration is performed in the didFinishLaunchingWithOptions method of the application delegate.

    Observers can also be removed with the removeObserver method of the PRMShieldEventManager API. However, App Shielding retains observers that were added with the legacy ShieldCallbackManager API indefinitely. They cannot be removed, and their callbacks remain active for as long as the application is running.

You can see an example of how to use the callbacks in the sample provided with the package.

Debugging: manual triggering of callbacks

To debug or test unshielded apps in the iOS simulator and on real devices, ShieldSDK callbacks can be manually triggered using instance methods of the PRMShieldEventManager class. ShieldSDK provides an API for debugging purposes. This debugging API allows you to trigger callbacks with the desired value and delay when the callback should be triggered. The API will not trigger any checks to be run but rather the desired callback which you want to validate.

---
- (void)triggerJailbreakStatus:(BOOL)value afterDelay:(NSTimeInterval)delay;
- (void)triggerEmulatorDetectedAfterDelay:(NSTimeInterval)delay;
...
---

This code is for debugging purpose only and should not exist in the binary when shielding it. When these calls are included in a shielded app, the app will terminate unexpectedly.

This feature will not be available after shielding, as the Shielding Tool will replace the stub library with the actual App Shielding library.

Callbacks on iOS

Callback

Description

jailbreakStatus

Provides a boolean that indicates whether the device on which the application is running is jailbroken.

Some detectors for Dopamine RootHide jailbreaks currently do not trigger a callback.

systemIntegrityProtectionStatus

Provides a boolean that indicates whether the app is running on a Mac with System Integrity Protection (SIP) disabled.

repackagingStatus

Provides a boolean that indicates whether the application has been repackaged. If the application is running in a simulator, this method is never called.

screenRecordingStatus

Provides a boolean that indicates whether one or more screens used by the app is being recorded.

developerModeStatus

Provides a boolean that indicates whether Developer Mode is enabled on the device. Developer Mode was added in iOS 16, so this method always returns false on devices running iOS 15 and earlier.

debuggerStatus

Provides a boolean that indicates whether a debugger is attached to the host application. If App Shielding is configured to block debuggers, this method is never called.

screenshotDetected

Called when App Shielding discovers that a screenshot of the application has been taken. If the application is running in a simulator, this method is never called.

libraryInjectionPrevented

Called when App Shielding has prevented an untrusted library from being injected into the process during runtime.

This callback is deprecated and does not trigger on iOS/tvOS 17 or later and macOS 14 or later. Instead, the app terminates unexpectedly.

libraryInjectionDetected

Called when App Shielding has detected that there are untrusted libraries in the process. A repackaged app can also trigger this callback in addition to the repackaging callback. In production, however, you should configure App Shielding to use the exitOnLibraryInjection option, and not rely on handling a callback.

hookingFrameworksDetected

Called when App Shielding has detected that there are hooking frameworks in the process. In production, however, you should configure App Shielding to use the exitOnHookingFrameworks option and not rely on handling a callback.

Exit on... security options like Exit on Jailbreak will cause the application to immediately exit before the corresponding callback is triggered. Also note that some of these options, like Exit on Repackaging, are always enabled in production mode.