本地化系统(Locale)是 AliPlayerKit 的国际化支撑模块。它通过统一的语言管理器 LocaleManager,提供自动跟随系统语言、手动语言切换、自定义 Provider 注入等核心能力,使播放器 UI 文案能够灵活适配多语言场景。
概念介绍
什么是 LocaleManager?
LocaleManager 是 AliPlayerKit 的内置国际化管理单例,负责播放器所有 UI 文案(按钮文本、错误提示、设置项标题等)的本地化查询。它采用解析链(Resolution Chain)机制,按优先级逐级查找翻译:
Custom Provider → activeBundle(手动/系统) → sdkBundle fallback → Key 本身核心价值
价值 | 说明 |
零配置可用 | 内置中/英两种语言,自动跟随系统语言,无需任何初始化 |
灵活切换 | 支持跟随系统和手动指定两种模式,满足不同业务需求 |
可扩展 | 通过 |
实时通知 | 语言切换后通过 |
语言模式
模式 | 枚举值 | 说明 |
跟随系统(默认) |
| 自动使用系统首选语言 |
手动指定 |
| 使用开发者指定的语言代码 |
功能特性
默认行为(零配置)
AliPlayerKit 开箱即用,无需编写任何代码即可支持多语言:
内置简体中文和英文两种语言。
播放器 UI 文案自动跟随系统语言切换,无需任何初始化或 API 调用。
用户在系统「设置 → 通用 → 语言与地区」中切换语言后,播放器文案自动切换。
如果系统语言不在内置支持范围内,自动回退到默认语言(简体中文)。
内置语言
语言 | 语言代码 | 资源目录 |
简体中文(默认) |
|
|
英文 |
|
|
对于大多数只需要中英文支持的应用,无需调用任何 API,集成 AliPlayerKit 即可。
内置文案Key分类
分类 | Key 常量前缀 | 示例 Key |
播放状态 |
|
|
底部控制栏 |
|
|
倍速提示 |
| 倍速播放中提示文案 |
设置菜单 |
|
|
镜像模式 |
|
|
缩放模式 |
|
|
日志面板 |
|
|
横屏提示 |
|
|
通用 |
| 通用"未知"文案 |
所有 Key 常量定义在 LocaleKeys.h 中,使用类型化常量确保编译期检查和 IDE 自动补全。
使用方式
跟随系统语言(默认,无需代码)
集成 AliPlayerKit 后,播放器文案自动根据系统语言显示对应翻译:
// 无需任何配置,播放器 UI 文案自动跟随系统语言
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
// 此时如系统为英文,所有 UI 文案自动显示英文手动指定语言
当需要在应用内提供语言切换入口、不跟随系统语言时:
// 强制切换到英文
[AliPlayerKit setLanguageCode:@"en"];
// 强制切换到简体中文
[AliPlayerKit setLanguageCode:@"zh-Hans"];调用 setLanguageCode: 后,localeMode 自动切换为 LocaleModeManual,并发送 LocaleDidChangeNotification 通知,已绑定的插槽会自动刷新文案。
恢复跟随系统
手动指定语言后,如需恢复为跟随系统:
// 清除手动设定,localeMode 恢复为 LocaleModeSystem
[AliPlayerKit resetLocaleToSystemLanguage];查询当前语言
// 获取当前生效的语言代码
NSString *currentLang = [AliPlayerKit currentLanguageCode];
NSLog(@"当前语言: %@", currentLang); // 如 "zh-Hans" 或 "en"监听语言变更
通过 NSNotification 监听语言切换事件:
// 注册通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(localeDidChange:)
name:LocaleDidChangeNotification
object:nil];
// 处理语言变更
- (void)localeDidChange:(NSNotification *)notification {
NSString *newLanguage = notification.userInfo[LocaleLanguageCodeKey];
NSLog(@"语言已切换为: %@", newLanguage);
// 刷新自定义 UI 文案
[self refreshCustomUI];
}
// 不再需要时移除
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:LocaleDidChangeNotification
object:nil];
}自定义开发
LocaleProvider 协议
LocaleProvider 定义了自定义翻译的注入接口:
@protocol LocaleProvider <NSObject>
@optional
/// 为指定 key 返回本地化字符串。
/// 返回 nil 表示不处理此 key,由 SDK 内部 fallback 继续解析。
- (nullable NSString *)localizedStringForKey:(NSString *)key;
@endlocalizedStringForKey: 是 @optional 方法。LocaleManager 在调用前会通过 respondsToSelector: 检查。
注入自定义 Provider
通过实现 LocaleProvider 协议,可以在不修改资源文件的情况下自定义任何翻译:
// 1. 定义自定义 Provider
@interface MyLocaleProvider : NSObject <LocaleProvider>
@end
@implementation MyLocaleProvider
- (nullable NSString *)localizedStringForKey:(NSString *)key {
// 自定义特定 key 的翻译
if ([key isEqualToString:LocaleKeyPlayStateLoading]) {
return @"视频缓冲中,请稍候...";
}
if ([key isEqualToString:LocaleKeySettingSpeed]) {
return @"播放倍率";
}
// 返回 nil 表示不处理此 key,由 SDK fallback 链继续解析
return nil;
}
@end
// 2. 注入 Provider
MyLocaleProvider *provider = [[MyLocaleProvider alloc] init];
[AliPlayerKit setLocaleProvider:provider];LocaleManager 以弱引用持有 Provider,调用方需自行保持 Provider 实例的生命周期。
新增语言支持
当需要新增 AliPlayerKit 尚未内置的语言(如日语)时,通过自定义 Provider 实现全量翻译:
@interface JapaneseLocaleProvider : NSObject <LocaleProvider>
@property (nonatomic, strong) NSDictionary<NSString *, NSString *> *translations;
@end
@implementation JapaneseLocaleProvider
- (instancetype)init {
self = [super init];
if (self) {
_translations = @{
LocaleKeyPlayStateLoading: @"読み込み中...",
LocaleKeyPlayStateErrorCodeLabel: @"エラーコード",
LocaleKeyPlayStateErrorMessageLabel: @"エラーメッセージ",
LocaleKeyBottomBarSpeed: @"速度",
LocaleKeyBottomBarQuality: @"画質",
LocaleKeySettingMenuTitle: @"設定",
LocaleKeySettingSpeed: @"再生速度",
LocaleKeySettingLoop: @"ループ再生",
LocaleKeySettingMute: @"ミュート",
LocaleKeySettingQuality: @"画質",
// ... 全量翻译所有 LocaleKeys.h 中的 key
};
}
return self;
}
- (nullable NSString *)localizedStringForKey:(NSString *)key {
return self.translations[key];
}
@end
// 注入日语 Provider(需自行持有实例)
self.jaProvider = [[JapaneseLocaleProvider alloc] init];
[AliPlayerKit setLocaleProvider:self.jaProvider];覆盖已有翻译
仅需覆盖部分翻译时,Provider 只返回需要修改的 key,其余返回 nil 由 SDK 处理:
- (nullable NSString *)localizedStringForKey:(NSString *)key {
// 仅覆盖"加载中"提示文案
if ([key isEqualToString:LocaleKeyPlayStateLoading]) {
return @"精彩即将呈现...";
}
return nil; // 其他 key 使用 SDK 内置翻译
}移除自定义 Provider
// 移除 Provider,恢复使用 SDK 内置翻译
[AliPlayerKit setLocaleProvider:nil];设计说明
字符串解析链(Resolution Chain)
LocaleManager 内部按以下优先级查找翻译:
优先级 | 来源 | 说明 |
1(最高) | Custom Provider | 实现 |
2 | activeBundle | 当前激活的语言 Bundle(Manual 模式为手动指定语言,System 模式为系统语言) |
3 | sdkBundle fallback | 当 activeBundle 与 sdkBundle 不同时,回退到 SDK Bundle 查询 |
4(最低) | Key fallback | 直接返回 key 本身 |
线程安全
LocaleManager 内部使用串行队列(dispatch_queue_t)保护所有状态读写:
操作 | 线程安全机制 |
属性读取( |
|
语言切换方法( |
|
通知发送 |
|
Provider 持有 | 弱引用( |
通知机制
通知名 | 触发时机 | userInfo |
| 语言模式或语言代码变化时 |
|
触发场景:
调用
setLanguageCode:切换手动语言调用
resetLocaleToSystemLanguage恢复系统跟随调用
setLocaleProvider:注入/移除 Provider
API 速查
AliPlayerKit 类方法
方法 | 说明 |
| 手动指定语言代码(如 |
| 恢复跟随系统语言, |
| 注入/移除自定义翻译 Provider(弱引用持有),传 |
| 获取当前生效的语言代码 |
LocaleManager实例方法
方法/属性 | 说明 |
| 获取单例实例 |
| 当前语言代码( |
| 当前语言模式( |
| 当前注入的 Provider( |
| 设置手动语言代码 |
| 注入自定义 Provider |
| 重置为跟随系统 |
| 按解析链查询本地化字符串 |
LocaleProvider 协议
方法 | 必选 | 说明 |
|
| 为指定 key 返回翻译,返回 nil 表示降级到 SDK 内置翻译 |
SDK内部使用的宏
宏 | 用法 | 说明 |
|
| 获取本地化字符串 |
|
| 获取格式化本地化字符串 |
通知常量
常量 | 类型 | 说明 |
|
| 语言变更通知名 |
|
| 通知 userInfo 中的新语言代码 Key |
相关文件
文件 | 说明 |
| 本地化管理器(单例) |
| 自定义翻译 Provider 协议 |
| 所有本地化 Key 常量定义 |
| SDK 内部使用的便捷宏 |
| 聚合头文件 |
| 全局 API 入口(Locale 相关类方法) |
| 简体中文翻译文件 |
| 英文翻译文件 |
完整API请参见API参考。
最佳实践
选择合适的方案
场景 | 推荐方案 | 说明 |
仅需中英文 | 无需任何操作 | 内置中英文,自动跟随系统语言 |
新增整套语言 |
| 实现协议,返回所有 key 的翻译 |
覆盖部分文案 |
| 仅处理需要覆盖的 key,其余返回 nil |
强制指定语言 |
| 不跟随系统,由应用自行控制 |
运行时动态切换 |
| 切换后通过通知刷新自定义 UI |
注意事项
事项 | 说明 |
Provider 生命周期 | Provider 以弱引用持有,调用方需自行保持 Provider 实例不被释放 |
全量翻译 | 新增语言时建议翻译所有 |
语言代码规范 | 使用 Apple 标准 lproj 命名(如 |
通知线程 |
|
插槽自动刷新 | 内置插槽监听语言变更通知并自动刷新文案,自定义插槽需自行监听 |
示例参考
PlayerKitUsages/UsageLocaleSystem 模块提供了完整的本地化系统使用示例,包含语言切换、自定义 Provider 注入和变更通知监听。