iOS
The purpose of this article is to describe how to set up Discord authentication so that your game can be logged in through the Discord channel using the Player Network login authentication service.
As the Discord SDK has stopped maintaining a license method for pulling up Discord Apps, there may be subsequent impacts on Discord App licensing.To ensure that Discord authorization is stable and available, it is recommended to use WebView for web authorization, see Configuring DISCORD_LOGIN_USING_WEB for details.
从 2024 年春季开始,对于需更新或上传至 Apple App Store Connect 的应用,开发者需明确 注明使用原因,以展示该应用如何使用 required reason API(需提交使用原因的 API)。更多信息,请参见 即将发布的第三方 SDK 要求。
Since Discord's privacy manifest has not yet been released, the corresponding content is not included in the Player Network SDK privacy manifest. For details, see iOS 17 Privacy Manifest.
Prerequisites
1. Configuring the application on the Discord Developer Platform
1. Create Discord Application
Before creating a Discord application, register an account on the official Discord website and follow the prompts to complete account authentication (via email).
- Enter Discord Developer Platform.
When logging in for the first time, users may need to verify that they are not a robot.You can do this after email verification. - In the upper right corner of the Applications page, click New Application.

- In the application creation window that pops up, enter the application name and click Create.
- On the General Information page, view the APPLICATION ID.
The user must configure the App ID in the INTLConfig.ini file.

2. Configure Application
-
Go to Discord Developer Platform.
-
Click the application to configure on the Applications page.
-
Click OAuth2 in the left navigation bar and go to OAuth2 > General.
-
Configure the following redirect URLs under Redirects to receive callbacks after authorization on the Discord web page by clicking Add Another to add the cell:
- https://common-web.intlgame.com/jssdk/discordlogincallback.html
- https://test-common-web.intlgame.com/jssdk/discordlogincallback.html

On mobile, if you want to authorize using the Discord app instead of the Discord webpage, you will also need to fill in a redirect URL for the Discord app post-authorization callback. Redirect URL Rules:
- Use all lowercase.
- Programs should begin with "intl".
- The URL should include the host and path.
Example: intlmoba://auth/callback
For INTLConfig.ini's DISCORD_UNIVERSAL_LINK_IOS.
- Configure open a generic link to the game.
- Add link to Redirect URL
A separate REDIRECT_URL_SCHEME is required for the multi-store channel package:.
Support for multi-store channel packages requires a separate REDIRECT_URL_SCHEME.An App ID supports 10 redirect URLs (about 4 multi-store channel packs).If the game requires more than 4 multi-store channel packs, please request more App IDs.To use multiple application IDs, the game requires Configure multiple application IDs in INTLConfig.ini and Register multiple Discord applications on Player Network.
-
Click Rich Presence in the left navigation bar and enter Rich Presence Art Assets page.
-
Click Add Image(s) to configure the application's image resources.

All image resources used in the application must be configured on this page, including the cover photo for friend invitations.
- Obtain Player Network console login account.
- Create a new project for the game, or join an existing project.
- Download SDK.
- Integrate the SDK.
- Add Discord as the login authentication method for the service in the Player Network console.
Step 1:Configuring the SDK for Discord Login
The Discord SDK is only compatible with iOS 12.0 and later.
Unreal Engine 应首先在 Plugins/INTLSDK/Source/INTLCore/INTLCore.Build.cs 文件中找到捆绑资源路径:
AdditionalBundleResources.Add(new BundleResource(Path.Combine(ModuleDirectory, "Libs/iOS/INTLCore/INTLSDK.bundle"), bShouldLog: false));
1. Loading required permissions and plug-ins
- Unity
- Unreal Engine
Open the INTLDiscordKit.projmods file and replace {INTL_DISCORD_APP_ID} with the App ID of the game.
"Info.plist":{
"LSApplicationQueriesSchemes":
[
"com.hammerandchisel.discord"
],
"NSAppTransportSecurity":
{
"NSAllowsArbitraryLoads". true
},
"CFBundleURLTypes" :
[
{
"CFBundleTypeRole": "Editor",
"CFBundleURLName": "Discord",
"CFBundleURLSchemes": ["discord-{INTL_DISCORD_APP_ID}"]
}
]
}
- SDK 1.24 and later versions
- SDK versions before 1.24
Open the INTLSDK/Source/INTLDiscord/Libs/iOS/INTLDiscord_UPL.xml file and replace {INTL_DISCORD_APP_ID} with the App ID of the game.
<dict>
<key>CFBundleURLName</key>
<string> Discord</string>
<key> CFBundleURLSchemes</key>
<array>
<string> discord-{INTL_DISCORD_APP_ID}</string>
</array>
</dict>
Open the INTLSDK/Source/INTLConfig/Configs/iOS/Plist/INTLDiscord.plist file and replace {INTL_DISCORD_APP_ID} with the App ID of the game.
<dict>
<key>CFBundleURLName</key>
<string> Discord</string>
<key> CFBundleURLSchemes</key>
<array>
<string> discord-{INTL_DISCORD_APP_ID}</string>
</array>
</dict>
iOS Instructions for Use
According to iOS permission requirements, when applying for sensitive permissions, fill in Usage Instructions, and the system will pop up to prompt the user to fill in this information.
- Unity
- Unreal Engine
-
In
Assets/INTLSDK/Editor/XUPorter/Mods~/INTLCoreKit.projmods, the following permissions have been escalated:"NSPhotoLibraryUsageDescription"
"NSCameraUsageDescription"
"NSLocationWhenInUseUsageDescription"
"NSPhotoLibraryAddUsageDescription"
"NSMicrophoneUsageDescription"At the time of access, the user can modify the content as needed.
-
In
Assets/INTLSDK/Editor/XUPorter/Mods~/INTLADTrackingKit.projmods, the following permissions have been escalated:"NSUserTrackingUsageDescription"
Upon access, users can modify content as needed** and confirm content compliance with the legal team**.If there are no changes, replace INTLSample with the game name.
-
In
Plugins/INTLSDK/Source/INTLConfig/Configs/iOS/Plist/INTLCore.plist, the following permissions have been escalated:<key>NSPhotoLibraryUsageDescription</key>
<key>NSCameraUsageDescription</key>
<key>NSLocationWhenInUseUsageDescription</key>
<key>NSPhotoLibraryAddUsageDescription</key>
<key>NSMicrophoneUsageDescription</key> -
In
Plugins/INTLSDK/Source/INTLConfig/Configs/iOS/Plist/INTLADTracking.plist, the following permissions have been escalated:<key>NSUserTrackingUsageDescription</key>
Upon access, users can modify content as needed** and confirm content compliance with the legal team**.If there are no changes, replace INTLSample with the game name.
2. Swift SDK Adapter
If the module uses Swift version SDK, this involves the integration of iOS' Swift and Objective-C. Xcode requires a bridging layer to align the class names, etc., of the two languages for compatibility. Follow these steps.
-
Create a new file and choose Swift File type.

-
Name it according to your needs and ensure the file suffix is .swift, then click Create.

-
Click Create Bridging Header.
Make sure to select Create Bridging Header.Otherwise, Xcode will not create the bridging file.

- Ensure two files are created in the Xcode project (one is the .swift file from step two, and the other is the automatically created project_name-Bridging-Header.h file).
No need to modify the file contents.

- Unity
- Unreal Engine
Not applicable.
Swift modules cannot be directly added to the iOS side in Unreal Engine, and engine configuration needs to be modified.
-
For Xcode 12 and later versions, add the following code in
/Plugins/INTLSDK/Source/INTLCore/INTLCore.Build.cs.PublicSystemLibraryPaths.Add("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos");
PublicSystemLibraryPaths.Add("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/iphoneos");
Player Network SDK already includes the following configuration, so you can skip this step when using other versions of Xcode.

Because building Unreal Engine with Xcode 12 or higher's Swift lib may cause compilation errors, you only need this step when using Xcode 12 or later to resolve issues.

-
Modify the local Unreal Engine source code.
In the function
private void AppendProjectBuildConfiguration(StringBuilder Content, string ConfigName, string ConfigGuid)in /Your_UE_Installation_Path/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs, add the following code.// Enable Swift
Content.Append("\t\t\t\tCLANG_ENABLE_MODULES = YES;" + ProjectFileGenerator.NewLine);
Content.Append("\t\t\t\tSWIFT_VERSION = 5.0;" + ProjectFileGenerator.NewLine);
Content.Append("\t\t\t\tLIBRARY_SEARCH_PATHS = \"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\";" + ProjectFileGenerator.NewLine);
if (ConfigName == "Debug")
{
Content.Append("\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";" + ProjectFileGenerator.NewLine);
}
Content.Append("\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;" + ProjectFileGenerator.NewLine);
Content.Append("\t\t\t\tEMBEDDED_CONTENT_CONTAINS_SWIFT = YES;" + ProjectFileGenerator.NewLine);
-
In /Your_UE_Installation_Path/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs, add the following code in the
string GetLinkArguments_Global(LinkEnvironment LinkEnvironment)function.
- Before XCode 12
- XCode 12 and later
// enable swift support
Result += " -rpath \"/usr/lib/swift\"";
Result += " -rpath \"@executable_path/Frameworks\"";
// /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/swift/
String swiftLibPath = String.Format(" -L {0}Platforms/{1}.platform/Developer/SDKs/{1}{2}.sdk/usr/lib/swift",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName : Settings.Value.SimulatorPlatformName, Settings.Value.IOSSDKVersion);
Result += swiftLibPath;
Log.TraceInformation("Add swift lib path : {0}", swiftLibPath);
///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos
swiftLibPath = String.Format(" -L {0}Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/{1}",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName.ToLower() : Settings.Value.SimulatorPlatformName.ToLower());
Result += swiftLibPath;
Log.TraceInformation("Add swift lib path : {0}", swiftLibPath);
///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/iphoneos
swiftLibPath = String.Format(" -L {0}Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/{1}",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName.ToLower() : Settings.Value.SimulatorPlatformName.ToLower());
Result += swiftLibPath;

// This line of code should be placed earlier (see the example image below for the correct position)
// enable swift support, make sure '/usr/lib/swift' goes before '@executable_path/Frameworks'
Result += " -rpath \"/usr/lib/swift\"";

// enable swift support
Result += " -rpath \"@executable_path/Frameworks\"";
// /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/swift/
String swiftLibPath = String.Format(" -L {0}Platforms/{1}.platform/Developer/SDKs/{1}{2}.sdk/usr/lib/swift",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName : Settings.Value.SimulatorPlatformName, Settings.Value.IOSSDKVersion);
Result += swiftLibPath;
Log.TraceInformation("Add swift lib path : {0}", swiftLibPath);
///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos
swiftLibPath = String.Format(" -L {0}Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/{1}",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName.ToLower() : Settings.Value.SimulatorPlatformName.ToLower());
Result += swiftLibPath;
Log.TraceInformation("Add swift lib path : {0}", swiftLibPath);
///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/iphoneos
swiftLibPath = String.Format(" -L {0}Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/{1}",
Settings.Value.XcodeDeveloperDir, bIsDevice? Settings.Value.DevicePlatformName.ToLower() : Settings.Value.SimulatorPlatformName.ToLower());
Result += swiftLibPath;
// Xcode 12 adds the swiftCompatibility51 library, so you need to add the following code
if (Settings.Value.IOSSDKVersionFloat >= 14.0f)
{
Result += String.Format(" -lswiftCompatibility51");
}

- Open the solution and recompile
/Users/intl/UE4/UE_4.25/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.sln.
3. Complete Player Network SDK configuration
- Open your project's INTLConfig.ini file:
[Discord channel configuration]
DISCORD_APP_ID = {INTL_DISCORD_APP_ID}
DISCORD_REDIRECT_URL = {INTL_DISCORD_REDIRECT_URL}
DISCORD_UNIVERSAL_LINK_IOS = {INTL_DISCORD_UNIVERSAL_LINK_IOS}
- Replace
{INTL_DISCORD_APP_ID}with the Discord App ID for the game. - Replace
{INTL_DISCORD_REDIRECT_URL}with the Redirect URL configured on the platform. - Replace
{INTL_DISCORD_UNIVERSAL_LINK_IOS}with the Redirect generic link configured on the developer platform.
- Adds the Discord to the
Info.plistfile.
- Unity
- Unreal Engine
When exporting an Xcode project using Unity, configure the .projmods file.
The Player Network SDK already writes these configurations to the INTLCoreKit.projmods file, so the game team only needs to check the configurations.
{
"group": "INTL",
"Info.plist":{
"CFBundleURLTypes" :
[
{
"CFBundleTypeRole":"Editor",
"CFBundleURLName":"Discord",
"CFBundleURLSchemes":["{INTL_DISCORD_REDIRECT_SCHEME}"]
}
]
},
}
- SDK 1.18 and later versions
- SDK version before 1.18
Open the corresponding file according to the SDK version to modify:
- V1.24 and later:
INTLSDK/Source/INTLDiscord/Libs/iOS/INTLDiscord_UPL.xml - V1.18 to V1.23:
INTLSDK/Source/INTLConfig/Configs/iOS/Plist/INTLDiscord.plist
<key>CFBundleURLSchemes</key>
<array>
<string>{INTL_DISCORD_REDIRECT_SCHEME}</string>
</array>
Business needs to go to Unreal Engine > Settings > Project Settings > Platforms > iOS > Extra Plist Data to change the configuration and add the SDK to the PLIST file.

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Discord</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{INTL_DISCORD_REDIRECT_SCHEME}</string>
</array>
</dict>
</array>
Replace {INTL_DISCORD_REDIRECT_SCHEME} with the scheme configured in the redirect URL.
For example, if the Redirect URL configured on the Discord Developer Platform is intlsample://auth/callback:
{INTL_DISCORD_REDIRECT_SCHEME} = intlsample
Step 2:Add Discord Login
Discord does not require an application to be installed before logging in.If the app is installed, it will open the app login, otherwise it will open the web page login.
Discord login permission needs to add identify.If you need to integrate Discord sharing, add relationships.read,activities.write as well.
- Register login-related callbacks.
- Unity
- Unreal Engine
// Add callbacks
public void AddAuthObserver()
{
INTLAPI.AddAuthResultObserver(OnAuthResultEvent);
}
// Remove callbacks
public void RemoveAuthObserver()
{
INTLAPI.RemoveAuthResultObserver(OnAuthResultEvent);
}
// Process the INTLAuthResult callback
public void OnAuthResultEvent(INTLAuthResult ret)
{
Debug.Log($"MethodID: {ret.MethodId}");
string methodTag = "";
if (authRet.MethodId == (int)INTLMethodID.INTL_AUTH_LOGIN)
{
methodTag = "Login";
}
else if (authRet.MethodId == (int)INTLMethodID.INTL_AUTH_BIND)
{
methodTag = "Bind";
}
else if (authRet.MethodId == (int)INTLMethodID.INTL_AUTH_AUTOLOGIN)
{
methodTag = "AutoLogin";
}
else if (authRet.MethodId == (int)INTLMethodID.INTL_AUTH_QUERY_USER_INFO)
{
methodTag = "QueryUserInfo";
}
else if (authRet.MethodId == (int)INTLMethodID.INTL_AUTH_GET_AUTH_RESULT)
{
methodTag = "GetAuthResult";
}
}
C++ Event Handling (above v1.15)
//configure callback
FINTLAuthEvent authEvent;
authEvent.AddUObject(this, &OnAuthResult_Implementation);
UINTLSDKAPI::SetAuthResultObserver(authEvent);
// Remove callbacks
UINTLSDKAPI::GetAuthResultObserver().Clear();
void OnAuthResult_Implementation(FINTLAuthResult ret)
{
UE_LOG(LogTemp, Warning, TEXT("MethodID: %d"), ret.MethodId);
}
Unreal Event Handling
void OnAuthResult_Implementation(FINTLAuthResult ret)
{
UE_LOG(LogTemp, Warning, TEXT("MethodID: %d"), ret.MethodId);
}
- Call the
AutoLogininterface to log in automatically.
- Unity
- Unreal Engine
INTLAPI.AutoLogin();
UINTLSDKAPI::AutoLogin();
- If automatic login fails, call the
Logininterface to let the player log in manually.
- Unity
- Unreal Engine
INTLAPI.Login(INTLChannel.Discord, "identify", "");
INTLAPI.Login(INTLChannel.Discord, "identify,relationships.read,activities.write", ""); //Friend functions
UINTLSDKAPI::Login(EINTLLoginChannel::Discord, "identify", "");
UINTLSDKAPI::Login(EINTLLoginChannel::Discord, "identify,relationships.read,activities.write", ""); //Friend functions
- Synchronize client authentication status with the game backend and wait for the final verification result.
Step 3: Acceptance testing for login functionality
Search for the keyword "AuthResult" in the Player Network SDK logs to confirm whether the channel name and OpenID are returned correctly.If correct, it means the integration configuration is successful, and login functionality has been successfully added.
If you encounter problems during the integration process, please refer to Frequently Asked Questions.