访客登录
配置
- Android
- iOS
- Unity
- Unreal
配置 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<application ...>
<service
android:name="com.garena.sdk.android.login.guest.AccountAuthenticatorService"
android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
....
</application>
</manifest>
创建 authenticator.xml 文件,并放入 res/xml/authenticator.xml 目录中:
<?xml version="1.0" encoding="utf-8"?>
<!--account type should be "com.garena.msdk{your com.garena.sdk.applicationId in the AndroidManifest.xml}{your com.garena.sdk.applicationVariant in the AndroidManifest.xml}"-->
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.garena.msdkXXXXXX"
android:icon="@drawable/app_logo"
android:label="@string/app_name"
android:smallIcon="@drawable/app_logo" />
使用方法
如果 MSDK 检测到当前没有游客账号,会创建一个新的游客账号。之后的游客登录会使用同一个账号,直到该账号成功绑定到其他账号为止。
- Android
- iOS
- Unity
- Unreal
AccountManager accountManager = new AccountManager(activity);
accountManager.login(PlatformType.GUEST, onLoginListener);
[MSDKLoginManager loginWithPlatform:MSDKePlatformGuest completion:^(MSDKLoginRet *loginRet) {
// handle login result
}];
GMSDKHandler.LoginClient.Login(AccountPlatform.Guest, OnLoginCallback);
UMsdkLogin::Login(EPlatform::Guest);
删除游客账号
该 API 会删除当前的游客会话(如果存在)。
- Android
- iOS
- Unity
- Unreal
accountManager.deleteGuest(); // return UID which was deleted
[MSDKLoginManager resetGuest];
GMSDKHandler.LoginClient.DeleteGuest();
UMsdkLogin::DeleteGuest();
检查本地是否存在游客账号
- Android
- iOS
- Unity
- Unreal
accountManager.hasGuestAccount();
[MSDKLoginManager hasGuestAccount];
GMSDKHandler.LoginClient.HasGuestAccount();
UMsdkLogin::HasGuestAccount();
找回游客账号
游客账号支持在卸载后进行恢复。
- Android
- iOS
- Unity
- Unreal
accountManager.findBackGuest(result -> {
if (result.isSuccess()) {
...
accountManager.login(PlatformType.GUEST, onLoginListener)
} else {
...
}
});
如果你看到如下日志
E/com.garena.msdk[5.0.0][com.garena.msdk]java.lang.SecurityException: uid 10456 cannot set user data for accounts of type: com.garena.msdkXXXXXX
It is likely because there are 2 apps in the device which use the same authenticator com.garena.msdkXXXXXX.
第一个安装的应用有权限使用该 authenticator,后安装的应用则没有权限,导致出现该错误。
请完全卸载/清理相关应用的数据后,再安装并尝试。
权限说明
该权限仅适用于 Android MSDK v5.10.2 及以下版本。从 v5.11.0 起,为符合 Google Play 更新后的 照片和视频权限政策 https://support.google.com/googleplay/android-developer/answer/14115180?hl=en&sjid=13871168763281969771-AP ,已不再使用该权限。
对于 Android MSDK v5.10.2 及以下版本: 为了让用户在重新安装游戏后能找回游客账号,MSDK 会请求外部存储或媒体存储权限(仅在 Android 11 及以上 需要)。
因此可能会弹出如下提示框:

你可以通过 msdkConfigs.setPermissionRationaleDialogEnable 来禁用此提示框。
对于 Android MSDK v5.11.0 及以上版本:
在 Android 11 及以上,游客账号存储采用新的本地备份方式,无需任何权限。玩家需要手动选择备份文件来恢复账号。
在 Android 10 及以下,MSDK 可自动读取游客账号文件,玩家无需手动选择备份文件。
从旧版 MSDK 升级到 v5.11.0+ 的影响:
- 已有的游客用户在卸载游戏后将无法恢复账号
- 如果不卸载游戏,则对已有游客账号没有影响
GMSDKHandler.LoginClient.FindBackGuest(rsp =>
{
if (rsp.resultCode == ErrorCode.Success)
{
GMSDKHandler.LoginClient.Login(AccountPlatform.Guest, OnLoginCallback);
}
else
{
...
}
});
跨应用共享游客账号凭证
- Android
- iOS
MSDK 内部已自动实现,无需额外配置。
- 在 Capabilities 和 Entitlements 中配置 App Group。
- 在
Info.plist中添加 AppGroup 字段。
常见问题
- iOS
W在 iOS 上 App Transfer 后游客账号是否会丢失?
App Transfer 指的是将应用从一个 Apple Developer 账号转移到另一个账号。
游客账号数据存储在两个地方:Keychain 和 UserDefaults/Documents。在 App Transfer 过程中,存储在 Keychain 的游客账号数据会丢失。但 UserDefaults/Documents 中的数据会保留,除非应用被卸载。因此在 App Transfer 后:
- 如果玩家直接覆盖安装新版本 —— 游客账号会保留,因为 UserDefaults/Documents 中的数据未被清除。
- 如果玩家卸载旧版本再安装新版本 —— 游客账号会丢失。Keychain 数据会在转移过程中被清除,UserDefaults/Documents 数据会在卸载时被删除。
将 Keychain 数据(登录会话和游客凭证)迁移到目标 Keychain Group
如果你的应用意外与同一 Apple Developer 账号下的其他应用共享了默认的 keychain group,可能会导致游客账号丢失。
同样,如果切换到新的独立 keychain group 而没有迁移,也会导致已有游客账号丢失。
迁移确保所有 keychain 数据会移动到新的、正确的、应用专属的 keychain group,避免游客账号丢失。
步骤 1: 切换到唯一的默认 Keychain Group
默认的 keychain group 是 Keychain Access Groups 中的第一项,建议使用 app bundle id。

配置方法详见 Apple 官方文档: https://developer.apple.com/documentation/xcode/configuring-keychain-sharing?language=objc
步骤 2: 保留之前的默认 Keychain Group
这样可以确保迁移过程中仍能访问之前存储的数据。
步骤 3: 在 Info.plist 中配置 GOPKeychainMigrationDstGroup
将其值设置为新的默认 keychain group(必须与 keychain-access-groups 权限中的第一项完全一致)。
如果该 key 缺失或配置错误,MSDK 将不会触发迁移,可能导致数据丢失。

步骤 4: 在 IPA 文件中验证默认 Keychain Group*
将 .ipa 转换为 .zip 并解压:
mv app.ipa app.zip
unzip app.zip // results in a Payload folder
codesign -d --entitlements :- Payload/{AppName}.app
你应当看到类似如下输出,检查 keychain-access-groups 部分:新的默认 keychain group 应排在第一位,之后是旧的 group。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict>
<key>application-identifier</key>
<string>TT2N7PPCM7.com.garena.beetalk.sdkdemo.BeeTalkSDKDemo.enterprise</string>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.associated-domains</key>
<array><string>applinks:devconnect.garena.com</string></array>
<key>com.apple.developer.team-identifier</key>
<string>TT2N7PPCM7</string><key>com.apple.security.application-groups</key>
<array><string>group.com.garena.beetalk.sdkdemo.enterprise</string></array>
<key>get-task-allow</key><false/>
<key>keychain-access-groups</key>
<array>
<string>TT2N7PPCM7.com.garena.gmsdk.demo</string> <!-- new default keychain group -->
<string>TT2N7PPCM7.*</string> <!-- previous default keychain group -->
</array></dict></plist>