跳到主要内容
版本:1.10.x

Unreal Engine

iOS 要求


  • Xcode15.X
  • AppGuard for iOS SDK v1.10.1.3 及以上

Unreal 插件基本说明


本文档旨在提供一种通过插件方式在 Unreal Engine 4、5 开发环境中比传统 SDK 应用方式更容易的应用方法。

下载并安装 Unreal 插件

安装 Unreal 插件,并在 Unreal Engine 4、5 中配置项目的方法如下:

  1. 访问 AppGuard 管理服务器,选择 Download > Unreal Plugins 下载最新版本。

  2. 在下载的 AppGuardUnrealPlugin.zip 文件中有一个名为 /AppGuardSDK 的文件夹,将该 AppGuardSDK 文件夹复制到 Project/Plugins/ 路径中。

  3. 打开 Project/Source/ProjectName/ 路径中的 APPNAME.Build.cs 文件,按如下方式添加 "AppGuardSDK" 以在 Unreal 项目中安装 AppGuard SDK。

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

下载并设置 AppGuard Config 文件

  1. 访问 AppGuard 管理服务器,选择 Applying Security > 下载 > CHAPTER 2. nProtect AppGuard CONFIG 文件下载 > CONFIG FILE DOWNLOAD 进行下载。

  2. 解压下载的 Config 文件后,AppGuard Config 文件由以下四个文件组成:appguard, appguard.crt, appguard.mf, appguard106000

  3. 将这四个文件复制到以下路径:
    Copy To: Project/Binaries/IOS/Payload/APPNAME.app/

信息

使用 UE5.2 及以上版本支持的 Modernized Xcode 选项进行构建时
AppGuard Config 文件必须复制到 Unreal Project/XXXXProject/Binaries/IOS/XXXXX.app/ 内部。

警告

如果尚未在 Unreal Editor 中执行过 iOS 构建,Project/Binaries/IOS 文件夹可能不存在。在这种情况下,请先执行一次 iOS 构建,然后再执行上述操作。

应用 AppGuardSDK Unreal 插件


在 Delegate 中注册回调并调用 AppGuard 初始化函数

如果在应用程序运行时检测到安全策略违规,需要通过回调接收事件,则必须在 Delegate 中注册回调。此外,为了进行 AppGuard 初始化工作,必须调用 UAppGuardSDKBlueprintLibrary::Start(); 函数。该函数必须在 应用程序运行时最先执行的时刻 调用。

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

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

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

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

void ASampleProjectGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) {
//. 注册安全检测回调函数
FAppGuardSDKModule::OnDetected.AddUObject(this, &ASampleProject::OnDetected); // 注册回调

//. 注册服务器认证回调函数
FAppGuardSDKModule::OnS2AuthCompleted.AddUObject(this, &ASampleProject::OnS2AuthCompleted);

//. 为使用 AppGuardCore.framework 进行 AppGuard 初始化
UAppGuardSDKBlueprintLibrary::Start();
}

/* 安全检测回调函数示例 */
void ASampleProjectGameMode::OnDetected (int data) {
bool killed = data > 0;
int code = data > 0 ? data : data * -1;

/*
如果 Data 的值为正数,AppGuard 将在 30 秒后终止。
应使用以下示例代码在用户可见的屏幕上显示。
*/
if (killed) {
//. 显示终止通知窗口,通知用户游戏即将终止。
//. 终止通知窗口应在确认按钮点击时终止应用程序。
}
}

/* 服务器认证回调函数示例 */
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data) {
//. 服务器认证回调函数的实现部分请参考 [服务器认证应用] 步骤
}
警告

在服务发布时,请务必移除上述安全检测回调函数和服务器认证回调函数中的日志输出函数

设置 UserID

提供 SetUserId() 方法以便在检测到策略违规时将 User ID 发送到日志服务器。

如以下示例代码所示,可以将该会话的用户 ID 以 FString 形式的数据传递到 userID 部分进行使用。

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

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

应用服务器认证(可选)


此内容适用于使用服务器认证的情况,如果不使用服务器认证,则不适用。

实现服务器认证回调函数

服务器认证相关的回调通过在 Delegate 中注册回调并调用 AppGuard 初始化函数 部分编写的 OnS2AuthCompleted() 回调方法传递服务器认证操作事件。

可以通过以下示例代码通过 OnS2AuthCompleted() 回调方法确认服务器认证状态结果。

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

// 服务器认证回调函数示例
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data)
{
switch (value)
{
case AppGuardEventType::S2Auth::S2AUTH_RESULT_SUCCESS:
/*
服务器认证成功,认证已正常完成。
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_RETRY:
/*
服务器认证失败,将尝试重新认证。这可能是暂时的客户端网络故障或服务器故障,
重新尝试可能会根据内部机制进行最长 3 分钟。
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_FAIL:
/*
服务器认证完全失败,不再尝试服务器认证。
*/
break;
}
}
提示

如以下 开始服务器认证 说明中所示,调用 UAppGuardSDKBlueprintLibrary::SetUniqueClientId() 方法时, 从该时刻起 AppGuard 安全模块将尝试服务器认证,并通过回调方法传递如上示例代码所示的 3 种状态代码。

警告

在服务发布时,请务必移除上述服务器认证回调函数中的日志输出函数

开始服务器认证

要在客户端启动服务器认证,可以通过以下示例代码使用从服务器接收到的用户会话的 UniqueClientID 调用以下方法。

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

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

该函数的第一个参数中给定的 Formatted-Unique-Client-Id 的规则及生成方法请参考 [主要 API]

应用 AppGuard SDK Privacy Manifests (UE4, UE5)

本指南要求使用 AppGuard SDK v1.10.1.3 及以上版本 以应用 Privacy Manifests。

提示

Unreal Plugin 包含以 AppGuardCore.framework 名称发布的 AppGuard SDK。
AppGuardCore.frameworkAppGuardCore.framework.zip 文件的形式发布在 Unreal Project/Plugins/AppGuardSDK/Source/AppGuardSDK/Libs/IOS/ 内部。

AppGuardCore.frameworkDo Not Embed 方式链接到项目并进行构建。

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"));
}

AppGuardCore.framework 的模块合并到链接 AppGuardCore.framework 的 TARGETS 中发布

Apple Privacy Manifests 相关的 PrivacyInfo.xcprivacy 必须包含在链接 AppGuard SDK 的 TARGETS 的 PrivacyInfo.xcprivacy 中 AppGuardCore.framework 的 PrivacyInfo.xcprivacy 内容

为了在 PrivacyInfo.xcprivacy 中指定 AppGuardCore.framework 相关内容,请参考以下指南进行合并操作

  • Unreal Project 中存在使用中的 PrivacyInfo.xcprivacy 文件

    • 比较 AppGuardCore.framework 内部的 PrivacyInfo.xcprivacy 文件内容与现有使用中的 PrivacyInfo.xcprivacy 以确认缺失部分。
    • 如果发现缺失部分,请将缺失部分添加并合并到现有使用中的 PrivacyInfo.xcprivacy 文件中。
  • Unreal Project 中不存在 PrivacyInfo.xcprivacy 文件

    • 复制以下内容以创建 PrivacyInfo.xcprivacy 文件。
      以下内容是 UE5.4 中生成的 PrivacyInfo.xcprivacy 文件与 AppGuardCore.framework 的 PrivacyInfo.xcprivacy 文件合并后的内容。 请参考进行合并。

      查看 UE5.4 中生成的 PrivacyInfo.xcprivacy 文件与 AppGuardCore.framework 的 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>
    • 请将创建的 PrivacyInfo.xcprivacy 文件复制并添加到 UnrealProjects/XXXXProject/Binaries/IOS/Payload/XXXXX.app/ 内部。

提示

使用 UE5.2 及以上版本支持的 Modernized Xcode 选项进行构建时
PrivacyInfo.xcprivacy 的复制位置必须在 Unreal Project/XXXXProject/Binaries/IOS/XXXXX.app/ 内部。

AppGuard for iOS SDK v1.10.1.3 及以上版本AppGuardCore.framework 名称发布,
该 SDK 以 static framework 形式制作并发布。

AppGuard for iOS SDK v1.10.1.3 及以上版本 在 Apple 要求的 Privacy Manifest 中标明的 Required reason API 项目 中,除 NSPrivacyAccessedAPICategoryUserDefaults 外未使用其他 API,请参考。

链接到项目的第三方 SDK 的 static framework 可能需要与 AppGuard SDK 类似的 在客户的 PrivacyInfo.xcprivacy 中进行合并操作