iOS
This article guides you through setting up Apple as an identity provider, enabling your iOS game to access Player Network authentication services.
Prerequisites
1. Set up the Apple app on the Apple Developer Platform
1. Create an App ID
Create a client_id
to identify the source that sends a request to Apple.
For iOS apps, the client_id
will be the App ID (Bundle ID).
Log in to the Apple Developer Platform.
In the sidebar, click Certificates, Identifiers & Profiles.
In the sidebar, click Identifiers and click the blue add icon (+).
Select App IDs and click Continue.
Enter the Description and Bundle ID.
- Description: The name or description of the game app.
- Bundle ID: The unique identifier of the game app which is included in the app ID.
Under Capabilities, select Sign in with Apple and click Continue.
Click Register to create an App ID.
For an existing App ID, find the designated App ID and select Sign in with Apple under Capabilities.
2. Create a private key to access services
Create the private key used to calculate the client_secret
and the corresponding Key ID.
From Certificates, Identifiers & Profiles, click Keys in the sidebar.
Click the the blue add icon (+).
Under Key Name, enter a unique name for the key.
Select the checkbox next to Sign in with Apple, and click Configure.
Under Primary App ID, select the app ID created in the previous step and click Save.
Click Continue.
Click Register to generate the key, and note down the Key ID.
Click Download to download the key file (CAN ONLY BE DOWNLOADED ONCE, DO NOT LOSE IT) which is saved as a text file with a .p8 file extension.
3. Create a description file
Create and download a description file. Then, install the downloaded description file in the development or packaging environment.
4. Get the Team ID
- Log in to the Apple Developer Platform.
- In the sidebar, click Membership to view the Team ID.
For more information about configurations on Apple Developer Platform, see What the Heck is Sign In with Apple?.
- Create an account for Player Network Console.
- Create a new project for your game, or join an existing one.
- Download the SDK.
- Integrate the SDK.
- Add Apple as an authentication method for your project on Player Network Console.
Step 1: Configure the SDK for Apple login
iOS SDK 9 and later
1. Bridging to Swift SDK
There will be mixed editing issue for iOS Swift and Objective-C if the module uses the Swift SDK. Take the following steps to create a bridge layer to align the class names of the two programming languages:
Create a new file and choose the Swift File type.
Specify the file name as needed and make sure that the extension is .swift. Then click on Create.
Click Create Bridging Header.
Make sure to select Create Bridging Header. Otherwise, Xcode will not create a bridge layer file.
- Make sure two files are created in the Xcode project (one is the .swift file created in step 2, and the other is the automatically created project_name-Bridging-Header.h file).
The file content remains unchanged.
- Unity
- Unreal Engine
Not applicable.
The iOS swift module cannot be directly added to Unreal Engine, and the engine configuration must be modified.
When using Xcode 12 or a later version, you must 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");noteBecause Player Network SDK has already set the following configuration in advance, you can skip this step when using other Xcode versions.
Because the following error will be reported when compiling Unreal Engine with Swift lib of Xcode 12 and later versions, this step is only required to solve the problem when using Xcode 12 and later versions.
Modify the local Unreal Engine source code.
Add the following code in the
private void AppendProjectBuildConfiguration(StringBuilder Content, string ConfigName, string ConfigGuid)
function of /Your_UE_Installation_Path/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs.// 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);Add the following code in the
string GetLinkArguments_Global(LinkEnvironment LinkEnvironment)
function of /Your_UE_Installation_Path/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs.
// 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 must be prepended (see the sample image below for the position of the prepended code)
// 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 solutions and recompile
/Users/intl/UE4/UE_4.25/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.sln
.
2. Add capabilities in Xcode
3. Add AuthenticationServices.framework
in Xcode BuildPhases and set Status
to optional.
Additional configurations for Unity
Check the configurations written in
INTLCoreKit.projmods
.{
"group": "INTL",
"libs": [],
"frameworks": ["AuthenticationServices.framework:weak"],
"files": [],
"folders": [],
"excludes": [],
"headerpaths":[],
"build_settings": {},
"system_capabilities": {},
"Info.plist":{}
}Add an entitlement file.
To add an entitlement file for Unity, see the solutions on Unity forum.Sample: `INTLDevDemo.entitlements`
```xml
<?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>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict>
</plist>
```
Step 2: Add Apple login
- It is not possible to test Apple login on a re-signed package. It is recommended to use TestFlight or Dev package.
- Apple login does not provide
PictureUrl
(User avatar URL). For more information, see INTLAuthResult for Unity and FINTLAuthResult for UE.
Passing email
and fullName
as login permission parameters to the Login
API:
- During first login, the username can be edited and an option to hide email is available (Fig 1).
email
andfullName
can be obtained from the callback.- If the player chose to hide their email, a random address will be returned.
- If the player chose to share their email, the actual email address will be returned.
email
andfullName
will not be returned on subsequent logins, and the login interface (Fig 2) will not provide options to edit username or hide email.- If the user stops the app from using the Apple ID and then logs in again, the interface will show the options in Fig 1.
Players can go to Settings > [Your Username] > Password and Security > Apps using Apple ID > [App Name] > Stop using Apple ID to stop or allow apps to use Apple ID for login.
When the Login
method login permission parameters pass in null strings, the login interface will not provide options to edit username and hide email (Fig 2). In the callback, the email
and fullName
fields are null.
Fig 1:
Fig 2:
Add an observer to handle authentication 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)
//Add 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
AutoLogin
method.- Unity
- Unreal Engine
INTLAPI.AutoLogin();
UINTLSDKAPI::AutoLogin();
Call the
Login
method to ask for user input if auto-login fails.- Unity
- Unreal Engine
INTLAPI.Login(INTLChannel.Apple);
UINTLSDKAPI::Login(EINTLLoginChannel::kChannelApple);
Sync client authentication state with the game's backend and wait for the final authentication result.
[Optional] Set up email permissions
Player authorization is required to obtain the email address for Apple, and will not be available if player authorization is refused, see Passing email
and fullName
to the Login
API for more information.
Set up permissions to obtain the email address of players during Apple login, returned as email
in the ChannelInfo
of AuthResult
.
- Email masking can be performed on the returned
email
according to compliance requirements, reach out to the Player Network representative to enable this feature. - The hashed
base64(sha256(email))
can be reported to the backend logs, reach out to the Player Network representative to enable this feature. - Can be used to verify if
email
is present in a player's profile or third-party channel information, reach out to the Player Network representative to enable this feature. - Can be used to enable Private Set Membership (PSM) for Firebase on iOS, see Firebase iOS configurations for more details.
Add
email
to thepermissions
parameter when calling the Login API.Enable email return on Player Network Console by setting return_email to YES, see Configure Third-party Channels for detailed procedures.
Step 3: Test the login function
Search for the keyword "AuthResult" in the Player Network SDK logs to verify if the correct channel name and OpenID are returned. If they are, it indicates a successful configuration and the login function has been added successfully.