UILocalNotification本地化失效:切换语言后通知仍显示旧语言
解决UILocalNotification本地化不随系统语言更新的问题
你遇到的核心问题在于:当前你是在调度通知时就把本地化后的静态字符串赋值给了alertTitle/alertBody,这些字符串会被直接存在系统的通知队列里,不会随着后续系统语言的变化而自动重新本地化。所以即使你切换了语言,已经调度好的通知还是会显示之前生成的旧语言内容。
你的临时方案(取消现有通知重新调度)虽然可行,但不够优雅,尤其是当存在大量待发通知时,操作成本很高。其实iOS原生就支持让通知在显示时动态适配当前系统语言,只需要你用对本地化相关的API:
正确的实现方式:使用本地化键而非静态字符串
对于UILocalNotification(iOS 9及更早版本),你需要用以下属性来替代直接设置alertTitle和alertBody:
alertTitleLocalizationKey:对应本地化文件中标题的键alertBodyLocalizationKey:对应本地化文件中内容的键- 如果你的本地化字符串需要参数(比如"%@,你的订单已发货"),可以用
alertTitleLocalizationArgs和alertBodyLocalizationArgs来传递参数数组
另外,通知的操作按钮也可以用alertActionLocalizationKey来设置本地化键,而不是直接写按钮文字。
代码示例
// 创建本地通知 UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:30]; // 使用本地化键,而非直接赋值字符串 notification.alertTitleLocalizationKey = @"notification_title"; notification.alertBodyLocalizationKey = @"notification_body"; // 如果有参数,比如需要插入用户名 notification.alertBodyLocalizationArgs = @[@"John"]; // 操作按钮的本地化 notification.alertActionLocalizationKey = @"notification_action"; // 调度通知 [[UIApplication sharedApplication] scheduleLocalNotification:notification];
对应的Localizable.strings文件(比如英文和法文版本):
英文:
"notification_title" = "Reminder"; "notification_body" = "%@, your order has been shipped!"; "notification_action" = "View";
法文:
"notification_title" = "Rappel"; "notification_body" = "%@, votre commande a été expédiée !"; "notification_action" = "Voir";
针对iOS 10+的补充说明
如果你是在iOS 10及以上版本开发,苹果已经推荐使用UNUserNotificationCenter框架来替代UILocalNotification。对应的本地化方式类似,需要给UNMutableNotificationContent设置:
titleLocalizationKeybodyLocalizationKeytitleLocalizationArgs/bodyLocalizationArgscategoryIdentifier对应的操作按钮本地化(需要在注册通知类别时设置action的titleLocalizationKey)
代码示例
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.titleLocalizationKey = @"notification_title"; content.bodyLocalizationKey = @"notification_body"; content.bodyLocalizationArgs = @[@"John"]; // 创建触发条件 UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:30 repeats:NO]; // 创建请求 UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"order_reminder" content:content trigger:trigger]; // 添加到通知中心 [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { if (error) { NSLog(@"Error scheduling notification: %@", error); } }];
关键注意事项
- 确保你的
Localizable.strings文件已经正确添加到所有目标语言的本地化资源中,并且键名完全匹配。 - 如果你之前已经用静态字符串调度了通知,需要先取消这些旧通知,再用新的本地化键方式重新调度,否则旧通知还是会显示旧语言内容。
- 当用户切换系统语言后,系统会在显示通知时自动读取当前语言对应的本地化字符串,不需要你手动重新调度。
这样做之后,通知就会自动适配用户当前的系统语言,再也不需要手动取消重发啦!
内容的提问来源于stack exchange,提问作者Sébastien Polytech'
相关产品推荐
相关产品推荐

