Skip to main content
Version: 1.10.x

Unreal Engine

iOS Requirements


  • Xcode 15.X
  • AppGuard for iOS SDK v1.10.1.3 or later

Unreal Plugin Overview


This document explains how to apply the AppGuard SDK in Unreal Engine 4 and 5 environments using the plugin method, which is easier than traditional integration methods.

Download and Install Unreal Plugin

To install the Unreal Plugin and set up your project in Unreal Engine 4 or 5, follow these steps:

  1. Access the AppGuard Manager server and select Download > Unreal Plugins to download the latest version.

  2. In the downloaded AppGuardUnrealPlugin.zip file, you'll find a folder named /AppGuardSDK. Copy this folder to the Project/Plugins/ directory.

  3. Open the APPNAME.Build.cs file in the Project/Source/ProjectName/ path and add "AppGuardSDK" as shown below to install AppGuard SDK into your Unreal project.

APPNAME.Build.cs
PublicDependencyModuleNames.AddRange(new string[] 
{
"Core", "CoreUObject", "Engine", "InputCore", "AppGuardSDK"
});

Download and Configure AppGuard Config Files

  1. Access the AppGuard Manager server and select Applying Security > Download > CHAPTER 2. nProtect AppGuard CONFIG File Download > CONFIG FILE DOWNLOAD to download the files.

  2. After extracting the downloaded config file, you will find four files: appguard, appguard.crt, appguard.mf, and appguard106000.

  3. Copy these four files to the following path:
    Copy To: Project/Binaries/IOS/Payload/APPNAME.app/

info

If you are using Modernized Xcode options supported in UE5.2 or later,
you must copy the AppGuard Config files into Unreal Project/XXXXProject/Binaries/IOS/XXXXX.app/.

caution

If you have never performed an iOS build from Unreal Editor, the Project/Binaries/IOS folder might not exist. In this case, perform an iOS build once before proceeding with the above steps.

Applying AppGuardSDK Unreal Plugin


Register Callback in Delegate and Call AppGuard Initialization Function

To receive event notifications when a security policy violation is detected during app execution, register a callback in the Delegate. Also, you must call the UAppGuardSDKBlueprintLibrary::Start(); function to initialize AppGuard. This function should be called at the earliest point when the app starts.

ASampleProjectGameMode.h
class ASampleProjectGameMode : public AGameModeBase
{
GENERATED_BODY()

//. Add
virtual void InitGame(const FString& MapName,
const FString& Options,
FString& ErrorMessage) override;

void OnS2AuthCompleted(int value, const FString& data);
void OnDetected(int value);
//. Add

public:
ASampleProjectGameMode();
};
ASampleProjectGameMode.cpp
#include "AppGuardSDKPlugin.h"
#include "AppGuardSDKBlueprintLibrary.h"

void ASampleProjectGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) {
//. Register callback function for security detection
FAppGuardSDKModule::OnDetected.AddUObject(this, &ASampleProject::OnDetected); // Register callback

//. Register callback function for server authentication
FAppGuardSDKModule::OnS2AuthCompleted.AddUObject(this, &ASampleProject::OnS2AuthCompleted);

//. Initialize AppGuardCore.framework to use AppGuard
UAppGuardSDKBlueprintLibrary::Start();
}

/* Sample callback function for security detection */
void ASampleProjectGameMode::OnDetected (int data) {
bool killed = data > 0;
int code = data > 0 ? data : data * -1;

/*
If the value of data is positive, AppGuard will close after 30 seconds.
Use the sample code below to display this message to the user on the appropriate screen.
*/
if (killed) {
//. Show an exit notification to inform the user that the game will close.
//. The exit notification should be configured so that the app closes when the OK button is clicked.
}
}

/* Sample callback function for server authentication */
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data) {
//. Refer to the [Server Authentication Application] stage for server authentication callback implementation.
}
caution

For service releases, make sure to remove any log output statements from the above security detection and server authentication callback functions.

Setting UserID

To send a User ID to the log server in case of a policy violation detection, you can use the SetUserId() method.

As shown in the sample code below, pass the session's user ID as an FString in the userID field.

ASampleProjectGameMode.cpp
#include "AppGuardSDKPlugin.h"
#include "AppGuardSDKBlueprintLibrary.h"

UAppGuardSDKBlueprintLibrary::SetUserId(TEXT("userID"));

Applying Server Authentication (Optional)


This section is only relevant if server authentication is being used. If not, it can be ignored.

Implementing the Callback Function for Server Authentication

Server authentication-related callbacks are triggered through the OnS2AuthCompleted() callback method, which was registered in the Register Callback in Delegate and Call AppGuard Initialization Function section.

The following sample code shows how the server authentication status results are communicated via the OnS2AuthCompleted() callback method.

ASampleProjectGameMode.cpp
#include "AppGuardSDKPlugin.h"
#include "AppGuardSDKBlueprintLibrary.h"

// Sample callback function for server authentication
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data)
{
switch (value)
{
case AppGuardEventType::S2Auth::S2AUTH_RESULT_SUCCESS:
/*
Server authentication was successful, and the authentication process has been completed.
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_RETRY:
/*
Server authentication failed and a retry will be attempted. This could be due to a temporary client network or server issue.
The retry process will continue for up to 3 minutes based on internal mechanisms.
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_FAIL:
/*
Server authentication has completely failed, and no further attempts will be made.
*/
break;
}
}
tip

When you call the UAppGuardSDKBlueprintLibrary::SetUniqueClientId() method as described in the Start Server Authentication section, the AppGuard security module will attempt server authentication and send one of the three status codes via the callback method, as shown in the sample code above.

caution

For service releases, make sure to remove any log output statements from the above server authentication callback function.

Start Server Authentication

To start server authentication from the client, use the UniqueClientID received from the server and pass it to the method as shown in the following sample code.

ASampleProjectGameMode.cpp
#include "AppGuardSDKPlugin.h"
#include "AppGuardSDKBlueprintLibrary.h"

UAppGuardSDKBlueprintLibrary::SetUniqueClientId(TEXT("Formatted-Unique-Client-Id", 180));
tip

For the formatting rules and creation method for the Formatted-Unique-Client-Id, refer to [Key API Documentation].

Applying AppGuard SDK Privacy Manifests (UE4, UE5)

This guide requires AppGuard SDK version v1.10.1.3 or later to apply Privacy Manifests.

tip

The Unreal Plugin includes the AppGuard SDK, which is distributed under the name AppGuardCore.framework.
AppGuardCore.framework is distributed as a .zip file located inside Unreal Project/Plugins/AppGuardSDK/Source/AppGuardSDK/Libs/IOS/.

AppGuardCore.framework is linked to the project as Do Not Embed and built.

AppGuardSDK.Build.cs
if(Target.Platform == UnrealTargetPlatform.IOS)
{
string LibPath = Path.Combine(ModuleDirectory, "Libs/IOS");

PrivateIncludePaths.Add("AppGuardSDK/Private/IOS");
PublicFrameworks.Add("Security");
PublicAdditionalFrameworks.Add(
new Framework(
"AppGuardCore",


Path.Combine(LibPath, "AppGuardCore.framework.zip"),
""
)
);
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory,
Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("IOSPlugin",
Path.Combine(PluginPath, "AppGuardSDK_UPL_IOS.xml"));
}

The AppGuardCore.framework module is merged and distributed with the TARGETS that link to the AppGuardCore.framework.

For Apple Privacy Manifests, the PrivacyInfo.xcprivacy of AppGuard SDK must be included in the TARGETS that link AppGuard SDK, and the contents of the AppGuardCore.framework's PrivacyInfo.xcprivacy must be merged with the PrivacyInfo.xcprivacy file of the linked TARGETS.

To specify the AppGuardCore.framework details in PrivacyInfo.xcprivacy, refer to the following guide for the merging process.

  • If your Unreal Project already has a PrivacyInfo.xcprivacy file:

    • Compare the contents of AppGuardCore.framework's PrivacyInfo.xcprivacy file with the existing PrivacyInfo.xcprivacy file to check for missing parts.
    • If missing parts are found, add and merge them into the existing PrivacyInfo.xcprivacy file.
  • If your Unreal Project does not have a PrivacyInfo.xcprivacy file:

    • Copy the content below and create a PrivacyInfo.xcprivacy file.
      The content below is a merged version of the PrivacyInfo.xcprivacy file generated in UE5.4 with AppGuardCore.framework's PrivacyInfo.xcprivacy file.

      View the merged PrivacyInfo.xcprivacy file from UE5.4 with AppGuardCore.framework's PrivacyInfo.xcprivacy
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
      <key>NSPrivacyCollectedDataTypes</key>
      <array>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeCrashData</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <false/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeGameplayContent</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <true/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeProductInteraction</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <false/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeUserID</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <true/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeDeviceID</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <true/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyCollectedDataType</key>
      <string>NSPrivacyCollectedDataTypeOtherDataTypes</string>
      <key>NSPrivacyCollectedDataTypeLinked</key>
      <true/>
      <key>NSPrivacyCollectedDataTypeTracking</key>
      <false/>
      <key>NSPrivacyCollectedDataTypePurposes</key>
      <array>
      <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
      </array>
      </dict>
      </array>
      <key>NSPrivacyTracking</key>
      <false/>
      <key>NSPrivacyAccessedAPITypes</key>
      <array>
      <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
      <string>C617.1</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
      <string>E174.1</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
      <string>35F9.1</string>
      </array>
      </dict>
      <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
      <string>CA92.1</string>
      </array>
      </dict>
      </array>
      </dict>
      </plist>
    • Copy the created PrivacyInfo.xcprivacy file to UnrealProjects/XXXXProject/Binaries/IOS/Payload/XXXXX.app/.

tip

For builds using the Modernized Xcode option supported in UE5.2 or later,
you must copy the PrivacyInfo.xcprivacy to Unreal Project/XXXXProject/Binaries/IOS/XXXXX.app/.

Starting from AppGuard for iOS SDK v1.10.1.3, the SDK is distributed as AppGuardCore.framework. This SDK is distributed as a static framework.

Note that AppGuard for iOS SDK v1.10.1.3 only uses NSPrivacyAccessedAPICategoryUserDefaults from the required reason API items in Apple's Privacy Manifest.

For third-party SDKs linked as static frameworks, the same PrivacyInfo.xcprivacy merging process may be required, similar to AppGuard SDK.