diff --git a/CustomKeyboard/Network/KBNetworkManager.m b/CustomKeyboard/Network/KBNetworkManager.m index f34b957..a3bcc00 100644 --- a/CustomKeyboard/Network/KBNetworkManager.m +++ b/CustomKeyboard/Network/KBNetworkManager.m @@ -52,7 +52,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; parameters:parameters error:&serror]; if (serror || !req) { - if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: @"无效的URL"}]); + if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid URL")}]); return nil; } [self applyHeaders:headers toMutableRequest:req contentType:nil]; @@ -83,7 +83,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; - (BOOL)ensureEnabled:(KBNetworkCompletion)completion { if (!self.isEnabled) { - NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: @"网络未启用(可能未开启完全访问)"}]; + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Network disabled (Full Access may be off)")}]; if (completion) completion(nil, nil, e); return NO; } @@ -127,7 +127,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; } NSData *data = (NSData *)responseObject; if (![data isKindOfClass:[NSData class]]) { - if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:@"无数据"}]); + if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"No data")}]); return; } NSString *ct = nil; @@ -150,7 +150,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; if (looksJSON) { NSError *jsonErr = nil; id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonErr]; - if (jsonErr) { if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:@"JSON解析失败"}]); return; } + if (jsonErr) { if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"Failed to parse JSON")}]); return; } if (completion) completion(json, response, nil); } else { if (completion) completion(data, response, nil); @@ -178,12 +178,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; #pragma mark - Private helpers - (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion { - NSString *msg = @"网络错误"; + NSString *msg = KBLocalized(@"Network error"); switch (code) { - case KBNetworkErrorDisabled: msg = @"网络未启用(可能未开启完全访问)"; break; - case KBNetworkErrorInvalidURL: msg = @"无效的URL"; break; - case KBNetworkErrorInvalidResponse: msg = @"无效的响应"; break; - case KBNetworkErrorDecodeFailed: msg = @"解析失败"; break; + case KBNetworkErrorDisabled: msg = KBLocalized(@"Network disabled (Full Access may be off)"); break; + case KBNetworkErrorInvalidURL: msg = KBLocalized(@"Invalid URL"); break; + case KBNetworkErrorInvalidResponse: msg = KBLocalized(@"Invalid response"); break; + case KBNetworkErrorDecodeFailed: msg = KBLocalized(@"Parse failed"); break; default: break; } NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain diff --git a/CustomKeyboard/View/Function/KBStreamOverlayView.m b/CustomKeyboard/View/Function/KBStreamOverlayView.m index ede0a02..9261753 100644 --- a/CustomKeyboard/View/Function/KBStreamOverlayView.m +++ b/CustomKeyboard/View/Function/KBStreamOverlayView.m @@ -51,7 +51,7 @@ del.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.35]; del.layer.cornerRadius = 14; del.layer.masksToBounds = YES; del.titleLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold]; - [del setTitle:@"删除" forState:UIControlStateNormal]; + [del setTitle:KBLocalized(@"Delete") forState:UIControlStateNormal]; [del setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [del addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside]; _closeButton = del; @@ -77,4 +77,3 @@ - (KBStreamTextView *)textView { return self.textViewInternal; } @end - diff --git a/CustomKeyboard/View/KBFullAccessGuideView.m b/CustomKeyboard/View/KBFullAccessGuideView.m index 22c1cd1..98803f7 100644 --- a/CustomKeyboard/View/KBFullAccessGuideView.m +++ b/CustomKeyboard/View/KBFullAccessGuideView.m @@ -47,7 +47,7 @@ }]; UILabel *title = [UILabel new]; - title.text = @"开启【允许完全访问】,体验完整功能"; + title.text = KBLocalized(@"Turn on Allow Full Access to experience all features"); title.font = [UIFont boldSystemFontOfSize:16]; title.textColor = [UIColor blackColor]; title.textAlignment = NSTextAlignmentCenter; @@ -70,7 +70,7 @@ }]; UILabel *row1 = [UILabel new]; row1.text = AppName; row1.textColor = [UIColor blackColor]; - UILabel *row2 = [UILabel new]; row2.text = @"允许完全访问"; row2.textColor = [UIColor blackColor]; + UILabel *row2 = [UILabel new]; row2.text = KBLocalized(@"Allow Full Access"); row2.textColor = [UIColor blackColor]; [box addSubview:row1]; [box addSubview:row2]; [row1 mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(box).offset(16); make.top.equalTo(box).offset(14); }]; UIView *line = [UIView new]; line.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; @@ -98,7 +98,7 @@ UIButton *go = [UIButton buttonWithType:UIButtonTypeSystem]; go.backgroundColor = [UIColor blackColor]; - [go setTitle:@"去开启" forState:UIControlStateNormal]; + [go setTitle:KBLocalized(@"Go enable") forState:UIControlStateNormal]; [go setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; go.titleLabel.font = [UIFont boldSystemFontOfSize:18]; go.layer.cornerRadius = 12; @@ -168,10 +168,10 @@ // Universal Link(需 AASA/Associated Domains 配置且 KB_UL_BASE 与域名一致) NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=kb_extension", KB_UL_SETTINGS]]; - void (^finish)(BOOL) = ^(BOOL ok){ + void (^finish)(BOOL) = ^(BOOL ok){ if (ok) { [self dismiss]; } else { - NSString *showInfo = [NSString stringWithFormat:@"请按路径:设置→通用→键盘→键盘→%@→允许完全访问",AppName]; + NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"),AppName]; [KBHUD showInfo:showInfo]; } }; diff --git a/CustomKeyboard/View/KBFunctionPasteView.m b/CustomKeyboard/View/KBFunctionPasteView.m index 61caa7b..93b8f8c 100644 --- a/CustomKeyboard/View/KBFunctionPasteView.m +++ b/CustomKeyboard/View/KBFunctionPasteView.m @@ -60,7 +60,7 @@ - (UILabel *)placeholderLabelInternal { if (!_placeholderLabelInternal) { _placeholderLabelInternal = [[UILabel alloc] init]; - _placeholderLabelInternal.text = @"点击粘贴TA的话"; + _placeholderLabelInternal.text = KBLocalized(@"Tap to paste their message"); _placeholderLabelInternal.textColor = [UIColor colorWithRed:0.20 green:0.64 blue:0.54 alpha:1.0]; _placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; } diff --git a/CustomKeyboard/View/KBFunctionView.m b/CustomKeyboard/View/KBFunctionView.m index ea5ecee..161acf2 100644 --- a/CustomKeyboard/View/KBFunctionView.m +++ b/CustomKeyboard/View/KBFunctionView.m @@ -176,7 +176,16 @@ - (void)reloadDemoData { // 演示数据(可由外部替换) - self.itemsInternal = @[@"高情商", @"暖味拉扯", @"风趣幽默", @"撩女生", @"社交惬匿", @"情场高手", @"一枚暖男", @"聊天搭子", @"表达爱意", @"更多话术"]; + self.itemsInternal = @[KBLocalized(@"高情商"), + KBLocalized(@"暖味拉扯"), + KBLocalized(@"风趣幽默"), + KBLocalized(@"撩女生"), + KBLocalized(@"社交惬匿"), + KBLocalized(@"情场高手"), + KBLocalized(@"一枚暖男"), + KBLocalized(@"聊天搭子"), + KBLocalized(@"表达爱意"), + KBLocalized(@"更多话术")]; [self.tagListView setItems:self.itemsInternal]; } @@ -257,7 +266,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/ [self.tagListView setLoading:NO atIndex:self.loadingTagIndex.integerValue]; self.loadingTagIndex = nil; self.loadingTagTitle = nil; } - if (error) { [KBHUD showInfo:@"拉取失败"]; } + if (error) { [KBHUD showInfo:KBLocalized(@"拉取失败")]; } if (self.streamOverlay) { [self.streamOverlay finish]; } }; self.streamFetcher = fetcher; @@ -296,7 +305,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/ // 1) 先判断权限:未开启“完全访问”则走引导逻辑 if (![[KBFullAccessManager shared] hasFullAccess]) { // 未开启完全访问:保持原有引导路径 - [KBHUD showInfo:@"处理中…"]; + [KBHUD showInfo:KBLocalized(@"处理中…")]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self]; return; } @@ -330,7 +339,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/ #pragma clang diagnostic pop } @catch (__unused NSException *e) { bridged = NO; } if (!bridged) { - [KBHUD showInfo:@"请切换到主App完成登录"]; + [KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")]; } }]; }); @@ -362,7 +371,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C return; } - [KBHUD showInfo:@"处理中…"]; + [KBHUD showInfo:KBLocalized(@"处理中…")]; UIInputViewController *ivc = KBFindInputViewController(self); if (!ivc) return; @@ -482,13 +491,13 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C - (void)kb_fullAccessChanged { dispatch_async(dispatch_get_main_queue(), ^{ [self kb_refreshPasteboardMonitor]; }); } -- (void)onTapDelete { + - (void)onTapDelete { NSLog(@"点击:删除"); UIInputViewController *ivc = KBFindInputViewController(self); id proxy = ivc.textDocumentProxy; [proxy deleteBackward]; } -- (void)onTapClear { + - (void)onTapClear { NSLog(@"点击:清空"); // 连续删除:仅清空光标之前的输入(不改动 pasteView 的内容) UIInputViewController *ivc = KBFindInputViewController(self); @@ -505,7 +514,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C guard += count; } } -- (void)onTapSend { + - (void)onTapSend { NSLog(@"点击:发送"); // 发送:插入换行。大多数聊天类 App 会把回车视为“发送” UIInputViewController *ivc = KBFindInputViewController(self); @@ -572,7 +581,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C - (UIButton *)pasteButtonInternal { if (!_pasteButtonInternal) { - _pasteButtonInternal = [self buildRightButtonWithTitle:@"粘贴" color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]]; + _pasteButtonInternal = [self buildRightButtonWithTitle:KBLocalized(@"Paste") color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]]; [_pasteButtonInternal addTarget:self action:@selector(onTapPaste) forControlEvents:UIControlEventTouchUpInside]; } return _pasteButtonInternal; @@ -586,7 +595,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C _deleteButtonInternal.layer.cornerRadius = 12.0; _deleteButtonInternal.layer.masksToBounds = YES; _deleteButtonInternal.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; - [_deleteButtonInternal setTitle:@"删除" forState:UIControlStateNormal]; + [_deleteButtonInternal setTitle:KBLocalized(@"删除") forState:UIControlStateNormal]; [_deleteButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [_deleteButtonInternal addTarget:self action:@selector(onTapDelete) forControlEvents:UIControlEventTouchUpInside]; } @@ -600,16 +609,16 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C _clearButtonInternal.layer.cornerRadius = 12.0; _clearButtonInternal.layer.masksToBounds = YES; _clearButtonInternal.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; - [_clearButtonInternal setTitle:@"清空" forState:UIControlStateNormal]; + [_clearButtonInternal setTitle:KBLocalized(@"Clear") forState:UIControlStateNormal]; [_clearButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [_clearButtonInternal addTarget:self action:@selector(onTapClear) forControlEvents:UIControlEventTouchUpInside]; } return _clearButtonInternal; } -- (UIButton *)sendButtonInternal { + - (UIButton *)sendButtonInternal { if (!_sendButtonInternal) { - _sendButtonInternal = [self buildRightButtonWithTitle:@"发送" color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]]; + _sendButtonInternal = [self buildRightButtonWithTitle:KBLocalized(@"Send") color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]]; [_sendButtonInternal addTarget:self action:@selector(onTapSend) forControlEvents:UIControlEventTouchUpInside]; } return _sendButtonInternal; diff --git a/CustomKeyboard/View/KBKeyboardView.m b/CustomKeyboard/View/KBKeyboardView.m index f9b53d7..3438ba1 100644 --- a/CustomKeyboard/View/KBKeyboardView.m +++ b/CustomKeyboard/View/KBKeyboardView.m @@ -125,7 +125,7 @@ NSArray *r4 = @[ [KBKey keyWithTitle:@"abc" type:KBKeyTypeModeChange], [KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom], [KBKey keyWithTitle:@"space" type:KBKeyTypeSpace], - [KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ]; + [KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ]; return @[r1, r2, r3, r4]; } @@ -159,7 +159,7 @@ NSArray *row4 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeModeChange], [KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom], [KBKey keyWithTitle:@"space" type:KBKeyTypeSpace], - [KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ]; + [KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ]; return @[row1.copy, row2.copy, row3.copy, row4]; } diff --git a/CustomKeyboard/View/KBSettingView.m b/CustomKeyboard/View/KBSettingView.m index f8fa089..77ff8a6 100644 --- a/CustomKeyboard/View/KBSettingView.m +++ b/CustomKeyboard/View/KBSettingView.m @@ -26,7 +26,7 @@ }]; self.titleLabel = [[UILabel alloc] init]; - self.titleLabel.text = @"设置"; + self.titleLabel.text = KBLocalized(@"设置"); self.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; self.titleLabel.textColor = [UIColor blackColor]; [self addSubview:self.titleLabel]; @@ -37,7 +37,7 @@ // 占位内容 UILabel *place = [[UILabel alloc] init]; - place.text = @"这里是设置内容占位"; + place.text = KBLocalized(@"这里是设置内容占位"); place.textColor = [UIColor darkGrayColor]; place.font = [UIFont systemFontOfSize:14]; [self addSubview:place]; @@ -68,4 +68,3 @@ - (UIButton *)backButton { return self.backButtonInternal; } @end - diff --git a/Shared/Localization/en.lproj/Localizable.strings b/Shared/Localization/en.lproj/Localizable.strings index dd69c3e..cb83fc8 100644 --- a/Shared/Localization/en.lproj/Localizable.strings +++ b/Shared/Localization/en.lproj/Localizable.strings @@ -18,3 +18,181 @@ "lang_toggle" = "Toggle Language"; "current_lang" = "Current: %@"; "common_back" = "Back"; + +// Login & account +"Log In" = "Log In"; +"Signed in successfully" = "Signed in successfully"; +"Sign-in failed" = "Sign-in failed"; +"Sign in to unlock all features" = "Sign in to unlock all features"; +"We'll use Apple for a quick, secure sign-in" = "We'll use Apple for a quick, secure sign-in"; +"Sign in with Apple requires iOS 13 or later" = "Sign in with Apple requires iOS 13 or later"; +"需要 iOS13+ 才能使用 Apple 登录" = "Sign in with Apple requires iOS 13 or later"; +"无效的登录凭证" = "Invalid login credential"; +"未返回 token" = "No token returned"; +"保存登录态失败" = "Failed to save login state"; +"请切换到主App完成登录" = "Please switch to the main app to finish signing in"; + +// Generic buttons & tips +"好" = "OK"; +"Confirm" = "Confirm"; +"Cancel" = "Cancel"; +"Close" = "Close"; +"Delete" = "Delete"; +"Clear" = "Clear"; +"Paste" = "Paste"; +"Send" = "Send"; +"Retry" = "Retry"; +"Success" = "Success"; +"Failed" = "Failed"; +"Network error" = "Network error"; +"Saved" = "Saved"; +"Copy Success" = "Copy Success"; + +// Network +"Network unavailable" = "Network unavailable"; +"Network disabled (Full Access may be off)" = "Network disabled (Full Access may be off)"; +"Invalid URL" = "Invalid URL"; +"Invalid response" = "Invalid response"; +"No data" = "No data"; +"Failed to parse JSON" = "Failed to parse JSON"; +"Parse failed" = "Parse failed"; +"未获取到数据" = "No data received"; +"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Request failed\nURL: %@\nStatus: %ld\nError: %@\nUserInfo: %@"; +"响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "Response OK (JSON)\nURL: %@\nStatus: %ld\nContent-Type: %@\nData: %@"; +"响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "Response OK (Data)\nURL: %@\nStatus: %ld\nContent-Type: %@\nData: %@"; +"响应解析失败(JSON)\nURL: %@\n错误: %@" = "Response decode failed (JSON)\nURL: %@\nError: %@"; +"HTTP GET\nURL: %@\nHeaders: %@\n参数: %@" = "HTTP GET\nURL: %@\nHeaders: %@\nParams: %@"; +"无效响应\nURL: %@\n说明: %@" = "Invalid response\nURL: %@\nReason: %@"; +"网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。" = "Network unavailable\nPlease check this app's wireless-data permission or network connection in Settings."; +"Please check this app's wireless-data permission or network connection in Settings." = "Please check this app's wireless-data permission or network connection in Settings."; + +// Permission & guides +"使用引导" = "Usage Guide"; +"Turn on Allow Full Access to experience all features" = "Turn on Allow Full Access to experience all features"; +"Allow Full Access" = "Allow Full Access"; +"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access" = "Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"; +"Go enable" = "Go enable"; +"Open Settings" = "Open Settings"; +"After pasting the conversation in the keyboard, choose a reply style" = "After pasting the conversation in the keyboard, choose a reply style"; +"当前:%@" = "Current: %@"; + +// Home / Tab labels +"Home" = "Home"; +"Shop" = "Shop"; +"Circle" = "Circle"; +"Mine" = "Mine"; +"热门" = "Hot"; +"排行" = "Rank"; + +// Search & history +"Clear history" = "Clear history"; +"Delete all history?" = "Delete all history?"; +"Delete this tag?" = "Delete this tag?"; +"This action cannot be undone" = "This action cannot be undone"; +"Loaded more successfully" = "Loaded more successfully"; + +// Skins & shop +"皮肤中心" = "Skin Center"; +"No skins yet" = "No skins yet"; +"Pull down to refresh" = "Pull down to refresh"; +"下载并应用" = "Download & Apply"; +"已应用,切到键盘查看" = "Applied. Switch to the keyboard to view."; +"应用失败" = "Apply failed"; +"Open agreement" = "Open agreement"; +"购物商城" = "Shop Mall"; + +// Skin sample names +"极光" = "Aurora"; +"雪山" = "Snow Mountain"; +"湖面" = "Lake"; + +// Sample tags & copy +"高情商" = "High EQ"; +"暖味拉扯" = "Ambiguous flirting"; +"风趣幽默" = "Witty & humorous"; +"撩女生" = "Flirt with girls"; +"社交惬匿" = "Relaxed socializing"; +"情场高手" = "Dating expert"; +"一枚暖男" = "Warm-hearted guy"; +"聊天搭子" = "Chat buddy"; +"表达爱意" = "Express love"; +"更多话术" = "More prompts"; +"Tap to paste their message" = "Tap to paste their message"; +"Tap any conversation to paste, then try any reply style~" = "Tap any conversation to paste, then try any reply style~"; +"What are you doing?" = "What are you doing?"; +"I'm going to take a shower." = "I'm going to take a shower."; +"🎉 If you run into any other issues, tap Online Support to get help~" = "🎉 If you run into any other issues, tap Online Support to get help~"; +"👋 Welcome to Key of Love Keyboard" = "👋 Welcome to Key of Love Keyboard"; + +// Payment & IAP +"Payment successful" = "Payment successful"; +"Payment failed" = "Payment failed"; +"购买:%@ Coins %@" = "Purchase: %@ Coins %@"; +"Pay clicked" = "Pay clicked"; + +// Example categories/items +"能力" = "Ability"; +"能力2" = "Ability 2"; +"爱好" = "Hobby"; +"爱好2" = "Hobby 2"; +"队友" = "Teammates"; +"队友2" = "Teammates 2"; +"高级能力" = "Advanced abilities"; +"高级爱好" = "Advanced hobbies"; +"高级队友" = "Advanced teammates"; + +// Example fruits etc. +"果冻橙" = "Jelly orange"; +"芒果" = "Mango"; +"有机水果卷心菜" = "Organic cabbage"; +"水果萝卜" = "Fruit radish"; +"熟冻帝王蟹" = "Cooked king crab"; +"赣南脐橙" = "Gannan navel orange"; +"苹果" = "Apple"; +"胡萝卜" = "Carrot"; +"葡萄" = "Grape"; +"西瓜" = "Watermelon"; +"小龙虾" = "Crawfish"; +"吃烤肉" = "Eat barbecue"; +"吃鸡腿肉" = "Eat chicken drumsticks"; +"吃牛肉" = "Eat beef"; +"各种肉" = "All kinds of meat"; + +// One Piece sample roles +"【剑士】罗罗诺亚·索隆" = "[Swordsman] Roronoa Zoro"; +"【航海士】娜美" = "[Navigator] Nami"; +"【狙击手】乌索普" = "[Sniper] Usopp"; +"【厨师】香吉士" = "[Cook] Sanji"; +"【船医】托尼托尼·乔巴" = "[Doctor] Tony Tony Chopper"; +"【船匠】 弗兰奇" = "[Shipwright] Franky"; +"【音乐家】布鲁克" = "[Musician] Brook"; +"【考古学家】妮可·罗宾" = "[Archaeologist] Nico Robin"; + +// Rubber-series sample moves +"橡胶火箭" = "Gum-Gum Rocket"; +"橡胶火箭炮" = "Gum-Gum Bazooka"; +"橡胶机关枪" = "Gum-Gum Gatling"; +"橡胶子弹" = "Gum-Gum Bullet"; +"橡胶攻城炮" = "Gum-Gum Cannon"; +"橡胶象枪" = "Gum-Gum Elephant Gun"; +"橡胶象枪乱打" = "Gum-Gum Elephant Gatling"; +"橡胶灰熊铳" = "Gum-Gum Grizzly Magnum"; +"橡胶雷神象枪" = "Gum-Gum Thor Elephant Gun"; +"橡胶猿王枪" = "Gum-Gum King Kong Gun"; +"橡胶犀·榴弹炮" = "Gum-Gum Rhino Grenade"; +"橡胶大蛇炮" = "Gum-Gum Great Serpent Cannon"; + +// Misc +"测试" = "Test"; +"暂无数据" = "No data yet"; +"这里是设置内容占位" = "Settings content placeholder"; +"设置" = "Settings"; +"使用引导" = "Usage Guide"; +"螃蟹啊斯柯达积分卡" = "Crab points card"; +"❎不是自己的键盘" = "❎ Not our keyboard"; +"是自己的键盘" = "Our keyboard"; + +// English-only keys with Chinese equivalents +"Change The Nickname" = "Change Nickname"; +"Please Enter The Modified Nickname" = "Please enter the new nickname"; +"Save" = "Save"; diff --git a/Shared/Localization/zh-Hans.lproj/Localizable.strings b/Shared/Localization/zh-Hans.lproj/Localizable.strings index 00a3f7a..ed41ebe 100644 --- a/Shared/Localization/zh-Hans.lproj/Localizable.strings +++ b/Shared/Localization/zh-Hans.lproj/Localizable.strings @@ -18,3 +18,177 @@ "lang_toggle" = "切换语言"; "current_lang" = "当前:%@"; "common_back" = "返回"; + +// 登录与账号 +"登录" = "登录"; +"登录成功" = "登录成功"; +"登录失败" = "登录失败"; +"登录后可使用全部功能" = "登录后可使用全部功能"; +"我们将使用 Apple 进行快速安全登录" = "我们将使用 Apple 进行快速安全登录"; +"Apple 登录需要 iOS 13 及以上版本" = "Apple 登录需要 iOS 13 及以上版本"; +"需要 iOS13+ 才能使用 Apple 登录" = "需要 iOS13+ 才能使用 Apple 登录"; +"无效的登录凭证" = "无效的登录凭证"; +"未返回 token" = "未返回 token"; +"保存登录态失败" = "保存登录态失败"; +"请切换到主App完成登录" = "请切换到主App完成登录"; + +// 通用按钮与提示 +"好" = "好"; +"确定" = "确定"; +"取消" = "取消"; +"关闭" = "关闭"; +"删除" = "删除"; +"清空" = "清空"; +"粘贴" = "粘贴"; +"发送" = "发送"; +"重试" = "重试"; +"成功" = "成功"; +"失败" = "失败"; +"网络错误" = "网络错误"; +"已保存" = "已保存"; +"复制成功" = "复制成功"; + +// 网络相关 +"网络不可用" = "网络不可用"; +"网络未启用(可能未开启完全访问)" = "网络未启用(可能未开启完全访问)"; +"无效的URL" = "无效的URL"; +"无效的响应" = "无效的响应"; +"无数据" = "无数据"; +"JSON解析失败" = "JSON解析失败"; +"解析失败" = "解析失败"; +"未获取到数据" = "未获取到数据"; +"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@"; +"响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@"; +"响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@"; +"响应解析失败(JSON)\nURL: %@\n错误: %@" = "响应解析失败(JSON)\nURL: %@\n错误: %@"; +"HTTP GET\nURL: %@\nHeaders: %@\n参数: %@" = "HTTP GET\nURL: %@\nHeaders: %@\n参数: %@"; +"无效响应\nURL: %@\n说明: %@" = "无效响应\nURL: %@\n说明: %@"; +"网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。" = "网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。"; +"请在“设置”中检查本应用的无线数据权限或网络连接。" = "请在“设置”中检查本应用的无线数据权限或网络连接。"; + +// 权限与引导 +"使用引导" = "使用引导"; +"开启【允许完全访问】,体验完整功能" = "开启【允许完全访问】,体验完整功能"; +"允许完全访问" = "允许完全访问"; +"请按路径:设置→通用→键盘→键盘→%@→允许完全访问" = "请按路径:设置→通用→键盘→键盘→%@→允许完全访问"; +"去开启" = "去开启"; +"去设置" = "去设置"; +"网络未启用(可能未开启完全访问)" = "网络未启用(可能未开启完全访问)"; +"在键盘粘贴对话后,选择回复方式" = "在键盘粘贴对话后,选择回复方式"; +"当前:%@" = "当前:%@"; + +// 首页 / Tab 文案 +"首页" = "首页"; +"商城" = "商城"; +"社区" = "社区"; +"我的" = "我的"; +"热门" = "热门"; +"排行" = "排行"; + +// 搜索与历史 +"清空历史" = "清空历史"; +"是否删除所有历史记录?" = "是否删除所有历史记录?"; +"删除该标签?" = "删除该标签?"; +"删除后不可恢复" = "删除后不可恢复"; +"加载更多成功" = "加载更多成功"; + +// 皮肤与商城 +"皮肤中心" = "皮肤中心"; +"暂无皮肤" = "暂无皮肤"; +"下拉刷新试试" = "下拉刷新试试"; +"下载并应用" = "下载并应用"; +"已应用,切到键盘查看" = "已应用,切到键盘查看"; +"应用失败" = "应用失败"; +"跳转协议" = "跳转协议"; +"购物商城" = "购物商城"; + +// 皮肤示例名称 +"极光" = "极光"; +"雪山" = "雪山"; +"湖面" = "湖面"; + +// 示例标签与文案 +"高情商" = "高情商"; +"暖味拉扯" = "暖味拉扯"; +"风趣幽默" = "风趣幽默"; +"撩女生" = "撩女生"; +"社交惬匿" = "社交惬匿"; +"情场高手" = "情场高手"; +"一枚暖男" = "一枚暖男"; +"聊天搭子" = "聊天搭子"; +"表达爱意" = "表达爱意"; +"更多话术" = "更多话术"; +"点击粘贴TA的话" = "点击粘贴TA的话"; +"点击任一对话去粘贴,选择任意回复方式去试用吧~" = "点击任一对话去粘贴,选择任意回复方式去试用吧~"; +"在干嘛?" = "在干嘛?"; +"我去洗澡了" = "我去洗澡了"; +"🎉 如您遇到其他问题,可点击在线客服帮您解决~" = "🎉 如您遇到其他问题,可点击在线客服帮您解决~"; +"👋 欢迎使用『Lovekey 键盘』" = "👋 欢迎使用『Lovekey 键盘』"; + +// 支付与内购 +"支付成功" = "支付成功"; +"支付失败" = "支付失败"; +"购买:%@ Coins %@" = "购买:%@ Coins %@"; +"Pay clicked" = "Pay clicked"; + +// 示例商品/分类 +"能力" = "能力"; +"能力2" = "能力2"; +"爱好" = "爱好"; +"爱好2" = "爱好2"; +"队友" = "队友"; +"队友2" = "队友2"; +"高级能力" = "高级能力"; +"高级爱好" = "高级爱好"; +"高级队友" = "高级队友"; + +// 示例水果等 +"果冻橙" = "果冻橙"; +"芒果" = "芒果"; +"有机水果卷心菜" = "有机水果卷心菜"; +"水果萝卜" = "水果萝卜"; +"熟冻帝王蟹" = "熟冻帝王蟹"; +"赣南脐橙" = "赣南脐橙"; +"苹果" = "苹果"; +"胡萝卜" = "胡萝卜"; +"葡萄" = "葡萄"; +"西瓜" = "西瓜"; +"小龙虾" = "小龙虾"; +"吃烤肉" = "吃烤肉"; +"吃鸡腿肉" = "吃鸡腿肉"; +"吃牛肉" = "吃牛肉"; +"各种肉" = "各种肉"; + +// One Piece 示例角色 +"【剑士】罗罗诺亚·索隆" = "【剑士】罗罗诺亚·索隆"; +"【航海士】娜美" = "【航海士】娜美"; +"【狙击手】乌索普" = "【狙击手】乌索普"; +"【厨师】香吉士" = "【厨师】香吉士"; +"【船医】托尼托尼·乔巴" = "【船医】托尼托尼·乔巴"; +"【船匠】 弗兰奇" = "【船匠】 弗兰奇"; +"【音乐家】布鲁克" = "【音乐家】布鲁克"; +"【考古学家】妮可·罗宾" = "【考古学家】妮可·罗宾"; + +// 橡胶系列示例文案 +"橡胶火箭" = "橡胶火箭"; +"橡胶火箭炮" = "橡胶火箭炮"; +"橡胶机关枪" = "橡胶机关枪"; +"橡胶子弹" = "橡胶子弹"; +"橡胶攻城炮" = "橡胶攻城炮"; +"橡胶象枪" = "橡胶象枪"; +"橡胶象枪乱打" = "橡胶象枪乱打"; +"橡胶灰熊铳" = "橡胶灰熊铳"; +"橡胶雷神象枪" = "橡胶雷神象枪"; +"橡胶猿王枪" = "橡胶猿王枪"; +"橡胶犀·榴弹炮" = "橡胶犀·榴弹炮"; +"橡胶大蛇炮" = "橡胶大蛇炮"; + +// 其它 +"测试" = "测试"; +"暂无数据" = "暂无数据"; +"这里是设置内容占位" = "这里是设置内容占位"; +"设置" = "设置"; +"使用引导" = "使用引导"; +"螃蟹啊斯柯达积分卡" = "螃蟹啊斯柯达积分卡"; +"❎不是自己的键盘" = "❎不是自己的键盘"; +"是自己的键盘" = "是自己的键盘"; diff --git a/keyBoard/AppDelegate.m b/keyBoard/AppDelegate.m index 62ef8c9..e8bdaf9 100644 --- a/keyBoard/AppDelegate.m +++ b/keyBoard/AppDelegate.m @@ -174,9 +174,9 @@ static NSString * const kKBKeyboardExtensionBundleId = @"com.loveKey.nyx.CustomK // 交给 VM 统一处理 Apple 登录 + 服务端登录 [[KBLoginVM shared] signInWithAppleFromViewController:KB_CURRENT_NAV completion:^(BOOL success, NSError * _Nullable error) { if (success) { - [KBHUD showInfo:@"登录成功"]; + [KBHUD showInfo:KBLocalized(@"Signed in successfully")]; } else { - NSString *msg = error.localizedDescription ?: @"登录失败"; + NSString *msg = error.localizedDescription ?: KBLocalized(@"Sign-in failed"); [KBHUD showInfo:msg]; } }]; @@ -281,17 +281,17 @@ static BOOL KBIsKeyboardEnabled(void) { return; } - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"网络不可用" - message:@"请在“设置”中检查本应用的无线数据权限或网络连接。" + UIAlertController *alert = [UIAlertController alertControllerWithTitle:KBLocalized(@"Network unavailable") + message:KBLocalized(@"Please check this app's wireless-data permission or network connection in Settings.") preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction *settings = [UIAlertAction actionWithTitle:@"去设置" + UIAlertAction *settings = [UIAlertAction actionWithTitle:KBLocalized(@"Open Settings") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [self kb_openAppSettings]; // 你已经实现好的跳设置方法 }]; - UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" + UIAlertAction *cancel = [UIAlertAction actionWithTitle:KBLocalized(@"Cancel") style:UIAlertActionStyleCancel handler:nil]; diff --git a/keyBoard/Class/Base/V/BaseTableView.m b/keyBoard/Class/Base/V/BaseTableView.m index ff1e49f..231e61c 100644 --- a/keyBoard/Class/Base/V/BaseTableView.m +++ b/keyBoard/Class/Base/V/BaseTableView.m @@ -53,7 +53,7 @@ _useEmptyDataSet = YES; // 默认开启 _emptyShouldAllowScroll = YES; // 默认允许滚动 _emptyVerticalOffset = 0; // 默认不偏移 - _emptyTitleText = @"暂无数据"; // 默认标题 + _emptyTitleText = KBLocalized(@"暂无数据"); // 默认标题 #if KB_HAS_DZN self.emptyDataSetSource = self; @@ -148,7 +148,7 @@ self.useEmptyDataSet = NO; // 默认文案 - NSString *t = title ?: @"暂无数据"; + NSString *t = title ?: KBLocalized(@"暂无数据"); LYEmptyView *ev = nil; if (buttonTitle.length > 0) { diff --git a/keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m b/keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m index 3c75ad2..454a166 100644 --- a/keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m +++ b/keyBoard/Class/Base/V/UIScrollView+KBEmptyView.m @@ -22,7 +22,7 @@ tapHandler:(KBEmptyAction)tapHandler buttonHandler:(KBEmptyAction)buttonHandler { #if KB_HAS_LY - NSString *t = title ?: @"暂无数据"; + NSString *t = title ?: KBLocalized(@"暂无数据"); LYEmptyView *ev = nil; if (buttonTitle.length > 0) { @@ -87,4 +87,3 @@ } @end - diff --git a/keyBoard/Class/Base/VC/BaseTabBarController.m b/keyBoard/Class/Base/VC/BaseTabBarController.m index 91e865a..d875cc9 100644 --- a/keyBoard/Class/Base/VC/BaseTabBarController.m +++ b/keyBoard/Class/Base/VC/BaseTabBarController.m @@ -31,29 +31,29 @@ // 首页 HomeMainVC *home = [[HomeMainVC alloc] init]; BaseNavigationController *navHome = [[BaseNavigationController alloc] initWithRootViewController:home]; - navHome.tabBarItem = [self tabItemWithTitle:@"首页" + navHome.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Home") image:@"tab_home" selectedImg:@"tab_home_selected"]; // 商城 KBShopVC *shop = [[KBShopVC alloc] init]; BaseNavigationController *navShop = [[BaseNavigationController alloc] initWithRootViewController:shop]; - navShop.tabBarItem = [self tabItemWithTitle:@"商城" + navShop.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Shop") image:@"tab_shop" selectedImg:@"tab_shop_selected"]; // 社区 KBCommunityVC *community = [[KBCommunityVC alloc] init]; - community.title = @"社区"; + community.title = KBLocalized(@"社区"); BaseNavigationController *navCommunity = [[BaseNavigationController alloc] initWithRootViewController:community]; - navCommunity.tabBarItem = [self tabItemWithTitle:@"社区" + navCommunity.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Circle") image:@"tab_shequ" selectedImg:@"tab_shequ_selected"]; // 我的 MyVC *my = [[MyVC alloc] init]; BaseNavigationController *navMy = [[BaseNavigationController alloc] initWithRootViewController:my]; - navMy.tabBarItem = [self tabItemWithTitle:@"我的" + navMy.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Mine") image:@"tab_my" selectedImg:@"tab_my_selected"]; diff --git a/keyBoard/Class/Common/V/KBAlert.m b/keyBoard/Class/Common/V/KBAlert.m index ee1a196..7ccebcb 100644 --- a/keyBoard/Class/Common/V/KBAlert.m +++ b/keyBoard/Class/Common/V/KBAlert.m @@ -94,7 +94,7 @@ static __weak UIViewController *sDefaultPresenter = nil; // 可选外部指定 [self _markFinishedAndContinue]; return; } - NSString *ok = button ?: (NSLocalizedString(@"OK", nil).length ? NSLocalizedString(@"OK", nil) : @"好"); + NSString *ok = button ?: (NSLocalizedString(@"OK", nil).length ? NSLocalizedString(@"OK", nil) : KBLocalized(@"好")); UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"") message:(message ?: @"") preferredStyle:UIAlertControllerStyleAlert]; @@ -138,8 +138,8 @@ static inline void KBSetActionTitleColor(UIAlertAction *action, UIColor *color) [self enqueuePresent:^{ UIViewController *vc = [self presentingVC]; if (!vc) { [self _markFinishedAndContinue]; return; } - NSString *ok = okTitle ?: @"确定"; - NSString *cancel = cancelTitle ?: @"取消"; + NSString *ok = okTitle ?: KBLocalized(@"Confirm"); + NSString *cancel = cancelTitle ?: KBLocalized(@"Cancel"); UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"") message:(message ?: @"") preferredStyle:UIAlertControllerStyleAlert]; @@ -175,8 +175,8 @@ static inline void KBSetActionTitleColor(UIAlertAction *action, UIColor *color) [self enqueuePresent:^{ UIViewController *vc = [self presentingVC]; if (!vc) { [self _markFinishedAndContinue]; return; } - NSString *ok = okTitle ?: @"确定"; - NSString *cancel = cancelTitle ?: @"取消"; + NSString *ok = okTitle ?: KBLocalized(@"Confirm"); + NSString *cancel = cancelTitle ?: KBLocalized(@"Cancel"); UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"") message:(message ?: @"") preferredStyle:UIAlertControllerStyleAlert]; diff --git a/keyBoard/Class/Common/V/KBHUD.m b/keyBoard/Class/Common/V/KBHUD.m index 2d1f399..b21f6b7 100644 --- a/keyBoard/Class/Common/V/KBHUD.m +++ b/keyBoard/Class/Common/V/KBHUD.m @@ -169,10 +169,10 @@ static __weak UIView *sContainerView = nil; // 缺省承载视图( + (void)showSuccess:(NSString *)status { // 简单起见,使用文字模式;如需图标,可替换为自定义勾勾图片 - [self _showText:status ?: @"成功" icon:nil]; + [self _showText:status ?: KBLocalized(@"Success") icon:nil]; } -+ (void)showError:(NSString *)status { [self _showText:status ?: @"失败" icon:nil]; } ++ (void)showError:(NSString *)status { [self _showText:status ?: KBLocalized(@"Failed") icon:nil]; } + (void)dismiss { [self onMain:^{ [sHUD hideAnimated:YES]; }]; } diff --git a/keyBoard/Class/Guard/V/KBGuideTopCell.m b/keyBoard/Class/Guard/V/KBGuideTopCell.m index e839946..25f5c2b 100644 --- a/keyBoard/Class/Guard/V/KBGuideTopCell.m +++ b/keyBoard/Class/Guard/V/KBGuideTopCell.m @@ -113,7 +113,7 @@ _titleLabel.numberOfLines = 0; _titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _titleLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0]; - _titleLabel.text = @"👋 欢迎使用『Lovekey 键盘』"; + _titleLabel.text = KBLocalized(@"👋 Welcome to Key of Love Keyboard"); } return _titleLabel; } @@ -124,7 +124,7 @@ _descLabel.numberOfLines = 0; _descLabel.font = [UIFont systemFontOfSize:14]; _descLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0]; - _descLabel.text = @"点击任一对话去粘贴,选择任意回复方式去试用吧~"; + _descLabel.text = KBLocalized(@"Tap any conversation to paste, then try any reply style~"); } return _descLabel; } @@ -137,7 +137,7 @@ _q1Label = [UILabel new]; _q1Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _q1Label.textColor = [UIColor blackColor]; - _q1Label.text = @"在干嘛?"; + _q1Label.text = KBLocalized(@"What are you doing?"); } return _q1Label; } @@ -147,10 +147,9 @@ _q2Label = [UILabel new]; _q2Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _q2Label.textColor = [UIColor blackColor]; - _q2Label.text = @"我去洗澡了"; + _q2Label.text = KBLocalized(@"I'm going to take a shower."); } return _q2Label; } @end - diff --git a/keyBoard/Class/Guard/VC/KBGuideVC.m b/keyBoard/Class/Guard/VC/KBGuideVC.m index d822819..2e11c65 100644 --- a/keyBoard/Class/Guard/VC/KBGuideVC.m +++ b/keyBoard/Class/Guard/VC/KBGuideVC.m @@ -39,7 +39,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) { - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0]; - self.title = @"使用引导"; +// self.title = KBLocalized(@"使用引导"); [self.view addSubview:self.tableView]; [self.view addSubview:self.inputBar]; @@ -176,7 +176,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) { // 1. 插入我方消息 [self.items addObject:@{ @"type": @(KBGuideItemTypeUser), @"text": text ?: @"" }]; // 2. 紧跟一条固定客服消息 - NSString *reply = @"🎉 如您遇到其他问题,可点击在线客服帮您解决~"; + NSString *reply = KBLocalized(@"🎉 If you run into any other issues, tap Online Support to get help~"); [self.items addObject:@{ @"type": @(KBGuideItemTypeKF), @"text": reply }]; // 刷新并滚动到底部 @@ -273,7 +273,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) { self.kb_lastInputModeIdentifier = currId; BOOL isMine = [currId rangeOfString:KB_KEYBOARD_EXTENSION_BUNDLE_ID].location != NSNotFound; - [KBHUD showInfo:(isMine ? @"是自己的键盘" : @"❎不是自己的键盘")]; + [KBHUD showInfo:(isMine ? KBLocalized(@"是自己的键盘") : KBLocalized(@"❎不是自己的键盘"))]; } /// 当权限满足时,尽力激活输入框,从而触发键盘挂载与输入法检测 @@ -368,7 +368,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) { _textField.delegate = self; _textField.returnKeyType = UIReturnKeySend; // 回车发送 _textField.font = [UIFont systemFontOfSize:15]; - _textField.placeholder = @"在键盘粘贴对话后,选择回复方式"; + _textField.placeholder = KBLocalized(@"After pasting the conversation in the keyboard, choose a reply style"); _textField.backgroundColor = [UIColor whiteColor]; _textField.layer.cornerRadius = 10; _textField.layer.masksToBounds = YES; UIView *pad = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 36)]; diff --git a/keyBoard/Class/Home/VC/FunctionTest/KBLangTestVC.m b/keyBoard/Class/Home/VC/FunctionTest/KBLangTestVC.m index 0c212c1..cdf33b0 100644 --- a/keyBoard/Class/Home/VC/FunctionTest/KBLangTestVC.m +++ b/keyBoard/Class/Home/VC/FunctionTest/KBLangTestVC.m @@ -46,7 +46,8 @@ self.title = KBLocalized(@"lang_test_title"); NSString *code = [KBLocalizationManager shared].currentLanguageCode ?: @""; NSString *fmt = KBLocalized(@"current_lang"); - self.label.text = [NSString stringWithFormat:fmt.length ? fmt : @"当前:%@", code]; + NSString *fallback = KBLocalized(@"当前:%@"); + self.label.text = [NSString stringWithFormat:fmt.length ? fmt : fallback, code]; [self.toggleBtn setTitle:KBLocalized(@"lang_toggle") forState:UIControlStateNormal]; } @@ -57,4 +58,3 @@ } @end - diff --git a/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m b/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m index 5a097bd..5fb75ff 100644 --- a/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m +++ b/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m @@ -17,7 +17,7 @@ if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { self.selectionStyle = UITableViewCellSelectionStyleNone; _applyBtn = [UIButton buttonWithType:UIButtonTypeSystem]; - [_applyBtn setTitle:@"下载并应用" forState:UIControlStateNormal]; + [_applyBtn setTitle:KBLocalized(@"Download & Apply") forState:UIControlStateNormal]; _applyBtn.layer.cornerRadius = 6; _applyBtn.layer.borderWidth = 1; _applyBtn.layer.borderColor = [UIColor colorWithWhite:0.85 alpha:1].CGColor; [self.contentView addSubview:_applyBtn]; @@ -41,14 +41,14 @@ - (void)viewDidLoad { [super viewDidLoad]; - self.title = @"皮肤中心"; + self.title = KBLocalized(@"皮肤中心"); self.view.backgroundColor = [UIColor whiteColor]; // 绝对 URL 的测试皮肤图片(无需 KB_BASE_URL)。 // 说明:使用 picsum.photos 的固定 id,稳定可直接访问。 self.skins = @[ - @{ @"id": @"aurora", @"name": @"极光", @"img": @"https://picsum.photos/id/1018/1600/900.jpg" }, - @{ @"id": @"alps", @"name": @"雪山", @"img": @"https://picsum.photos/id/1016/1600/900.jpg" }, - @{ @"id": @"lake", @"name": @"湖面", @"img": @"https://picsum.photos/id/1039/1600/900.jpg" }, + @{ @"id": @"aurora", @"name": KBLocalized(@"极光"), @"img": @"https://picsum.photos/id/1018/1600/900.jpg" }, + @{ @"id": @"alps", @"name": KBLocalized(@"雪山"), @"img": @"https://picsum.photos/id/1016/1600/900.jpg" }, + @{ @"id": @"lake", @"name": KBLocalized(@"湖面"), @"img": @"https://picsum.photos/id/1039/1600/900.jpg" }, ]; self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleInsetGrouped]; @@ -124,7 +124,7 @@ payload = UIImageJPEGRepresentation(img, 0.9); } BOOL ok = (payload.length > 0) ? [[KBSkinManager shared] applyImageSkinWithData:payload skinId:skin[@"id"] name:skin[@"name"]] : NO; - [KBHUD showInfo:(ok ? @"已应用,切到键盘查看" : @"应用失败")]; + [KBHUD showInfo:(ok ? KBLocalized(@"已应用,切到键盘查看") : KBLocalized(@"应用失败"))]; }); }]; } diff --git a/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m b/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m index 8cfc30a..5c2f855 100644 --- a/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m +++ b/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m @@ -38,7 +38,7 @@ self.tableView.tableHeaderView = header; [self.view addSubview:self.tableView]; - self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), @"皮肤中心" ]; + self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心") ]; dispatch_async(dispatch_get_main_queue(), ^{ [self.textView becomeFirstResponder]; }); @@ -50,7 +50,7 @@ - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; self.title = KBLocalized(@"home_title"); - self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), @"皮肤中心" ]; + self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心") ]; [self.tableView reloadData]; } diff --git a/keyBoard/Class/Home/VC/HomeRankVC.m b/keyBoard/Class/Home/VC/HomeRankVC.m index 3fa2921..4f3a531 100644 --- a/keyBoard/Class/Home/VC/HomeRankVC.m +++ b/keyBoard/Class/Home/VC/HomeRankVC.m @@ -23,7 +23,12 @@ [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor clearColor]; - self.titles = @[@"螃蟹啊斯柯达积分卡", @"小龙虾", @"苹果", @"胡萝卜", @"葡萄", @"西瓜"]; + self.titles = @[KBLocalized(@"螃蟹啊斯柯达积分卡"), + KBLocalized(@"小龙虾"), + KBLocalized(@"苹果"), + KBLocalized(@"胡萝卜"), + KBLocalized(@"葡萄"), + KBLocalized(@"西瓜")]; [self.view addSubview:self.myCategoryView]; [self.view addSubview:self.listContainerView]; self.listContainerView.scrollView.scrollEnabled = false; diff --git a/keyBoard/Class/Home/VC/HomeSheetVC.m b/keyBoard/Class/Home/VC/HomeSheetVC.m index 8279b77..94bcaab 100644 --- a/keyBoard/Class/Home/VC/HomeSheetVC.m +++ b/keyBoard/Class/Home/VC/HomeSheetVC.m @@ -137,7 +137,7 @@ // 两个按钮 self.hotButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [self.hotButton setTitle:@"热门" forState:UIControlStateNormal]; + [self.hotButton setTitle:KBLocalized(@"热门") forState:UIControlStateNormal]; [self.hotButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal]; [self.hotButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected]; self.hotButton.titleLabel.font = [UIFont boldSystemFontOfSize:16]; @@ -146,7 +146,7 @@ [self.topBar addSubview:self.hotButton]; self.rankButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [self.rankButton setTitle:@"排行" forState:UIControlStateNormal]; + [self.rankButton setTitle:KBLocalized(@"排行") forState:UIControlStateNormal]; [self.rankButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal]; [self.rankButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected]; self.rankButton.titleLabel.font = [UIFont boldSystemFontOfSize:16]; diff --git a/keyBoard/Class/Login/V/KBLoginPopView.m b/keyBoard/Class/Login/V/KBLoginPopView.m index 1f11dcc..74b6b6e 100644 --- a/keyBoard/Class/Login/V/KBLoginPopView.m +++ b/keyBoard/Class/Login/V/KBLoginPopView.m @@ -71,7 +71,7 @@ }]; } else { UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem]; - [btn setTitle:@"需要 iOS13+ 才能使用 Apple 登录" forState:UIControlStateNormal]; + [btn setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal]; btn.enabled = NO; btn.layer.cornerRadius = 8.0; btn.layer.borderWidth = 1.0; @@ -100,7 +100,7 @@ - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = @"登录后可使用全部功能"; + _titleLabel.text = KBLocalized(@"Sign in to unlock all features"); _titleLabel.font = [UIFont boldSystemFontOfSize:18]; _titleLabel.textColor = [UIColor blackColor]; _titleLabel.textAlignment = NSTextAlignmentCenter; @@ -112,7 +112,7 @@ - (UILabel *)descLabel { if (!_descLabel) { _descLabel = [UILabel new]; - _descLabel.text = @"我们将使用 Apple 进行快速安全登录"; + _descLabel.text = KBLocalized(@"We'll use Apple for a quick, secure sign-in"); _descLabel.font = [UIFont systemFontOfSize:14]; _descLabel.textColor = [UIColor colorWithWhite:0.2 alpha:0.8]; _descLabel.textAlignment = NSTextAlignmentCenter; @@ -140,4 +140,3 @@ } @end - diff --git a/keyBoard/Class/Login/VC/LoginViewController.m b/keyBoard/Class/Login/VC/LoginViewController.m index ee9e78c..acbe5ce 100644 --- a/keyBoard/Class/Login/VC/LoginViewController.m +++ b/keyBoard/Class/Login/VC/LoginViewController.m @@ -68,7 +68,7 @@ - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = @"登录"; + _titleLabel.text = KBLocalized(@"Log In"); _titleLabel.font = [UIFont boldSystemFontOfSize:24]; _titleLabel.textAlignment = NSTextAlignmentCenter; } @@ -107,7 +107,7 @@ - (UIButton *)compatHintButton { if (!_compatHintButton) { _compatHintButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [_compatHintButton setTitle:@"需要 iOS13+ 才能使用 Apple 登录" forState:UIControlStateNormal]; + [_compatHintButton setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal]; _compatHintButton.enabled = NO; } return _compatHintButton; diff --git a/keyBoard/Class/Login/VM/KBLoginVM.m b/keyBoard/Class/Login/VM/KBLoginVM.m index 44ca4fe..ab4f287 100644 --- a/keyBoard/Class/Login/VM/KBLoginVM.m +++ b/keyBoard/Class/Login/VM/KBLoginVM.m @@ -30,7 +30,7 @@ [[AppleSignInManager shared] signInFromViewController:presenter completion:^(ASAuthorizationAppleIDCredential * _Nullable credential, NSError * _Nullable error) { if (error) { if (completion) completion(NO, error); return; } if (![credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { - if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"无效的登录凭证"}]); + if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-1 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"无效的登录凭证")}]); return; } @@ -54,7 +54,7 @@ self.currentUser = user; NSString *token = user.token ?: [self.class tokenFromResponseObject:jsonOrData]; if (token.length == 0) { - if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"未返回 token"}]); + if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"未返回 token")}]); return; } @@ -63,7 +63,7 @@ refreshToken:nil expiryDate:nil userIdentifier:cred.user]; - if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: @"保存登录态失败"}]); + if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"保存登录态失败")}]); }]; }]; } diff --git a/keyBoard/Class/Manager/AppleSignInManager.m b/keyBoard/Class/Manager/AppleSignInManager.m index 7553c4b..197e6fa 100644 --- a/keyBoard/Class/Manager/AppleSignInManager.m +++ b/keyBoard/Class/Manager/AppleSignInManager.m @@ -45,7 +45,7 @@ static NSString * const kKBAppleUserIdentifierKey = @"com.company.keyboard.apple [controller performRequests]; } else { if (completion) { - NSError *err = [NSError errorWithDomain:@"AppleSignIn" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Apple 登录需要 iOS 13 及以上版本"}]; + NSError *err = [NSError errorWithDomain:@"AppleSignIn" code:-1 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Sign in with Apple requires iOS 13 or later")}]; completion(nil, err); } } diff --git a/keyBoard/Class/Me/V/KBChangeNicknamePopView.m b/keyBoard/Class/Me/V/KBChangeNicknamePopView.m index 04d8db6..7c7a084 100644 --- a/keyBoard/Class/Me/V/KBChangeNicknamePopView.m +++ b/keyBoard/Class/Me/V/KBChangeNicknamePopView.m @@ -120,7 +120,7 @@ - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = @"Change The Nickname"; + _titleLabel.text = KBLocalized(@"Change The Nickname"); _titleLabel.textColor = [UIColor blackColor]; _titleLabel.font = [UIFont systemFontOfSize:22 weight:UIFontWeightBold]; } @@ -141,7 +141,7 @@ [_closeButton setTitleColor:[UIColor colorWithWhite:0.3 alpha:1] forState:UIControlStateNormal]; _closeButton.tintColor = [UIColor colorWithWhite:0.3 alpha:1]; [_closeButton addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside]; - _closeButton.accessibilityLabel = @"关闭"; + _closeButton.accessibilityLabel = KBLocalized(@"Close"); } return _closeButton; } @@ -161,7 +161,7 @@ _textField.clearButtonMode = UITextFieldViewModeWhileEditing; _textField.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; _textField.textColor = [UIColor blackColor]; - _textField.placeholder = @"Please Enter The Modified Nickname"; + _textField.placeholder = KBLocalized(@"Please Enter The Modified Nickname"); } return _textField; } @@ -169,7 +169,7 @@ - (UIButton *)saveButton { if (!_saveButton) { _saveButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_saveButton setTitle:@"Save" forState:UIControlStateNormal]; + [_saveButton setTitle:KBLocalized(@"Save") forState:UIControlStateNormal]; [_saveButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; _saveButton.titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold]; _saveButton.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0]; @@ -180,4 +180,3 @@ } @end - diff --git a/keyBoard/Class/Me/V/KBMyKeyboardCell.m b/keyBoard/Class/Me/V/KBMyKeyboardCell.m index 28ecaae..9608f33 100644 --- a/keyBoard/Class/Me/V/KBMyKeyboardCell.m +++ b/keyBoard/Class/Me/V/KBMyKeyboardCell.m @@ -160,7 +160,7 @@ _minusTapArea = [[UIControl alloc] init]; _minusTapArea.backgroundColor = [UIColor clearColor]; // 提高命中率:即使轻微偏离也能点中 - _minusTapArea.accessibilityLabel = @"删除"; + _minusTapArea.accessibilityLabel = KBLocalized(@"Delete"); } return _minusTapArea; } diff --git a/keyBoard/Class/Me/V/MySkinCell.m b/keyBoard/Class/Me/V/MySkinCell.m index 3581f74..b4a6e91 100644 --- a/keyBoard/Class/Me/V/MySkinCell.m +++ b/keyBoard/Class/Me/V/MySkinCell.m @@ -91,7 +91,7 @@ }]; [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.equalTo(self.cardView); - make.height.equalTo(self.cardView.mas_width).multipliedBy(0.66); // 接近截图比例 + make.height.mas_equalTo(KBFit(126)); }]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.cardView).offset(12); diff --git a/keyBoard/Class/Me/VC/KBMyKeyBoardVC.m b/keyBoard/Class/Me/VC/KBMyKeyBoardVC.m index 2a9c24e..a28979e 100644 --- a/keyBoard/Class/Me/VC/KBMyKeyBoardVC.m +++ b/keyBoard/Class/Me/VC/KBMyKeyBoardVC.m @@ -163,23 +163,10 @@ static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId"; if (!self) { return; } NSIndexPath *tapIndexPath = [weakCV indexPathForCell:tappedCell]; if (!tapIndexPath) { return; } -// [KBAlert confirmTitle:@"删除该标签?" message:@"删除后不可恢复" completion:^(BOOL ok) { -// if (!ok) { return; } -// // 更新数据源并删除 item -// if (tapIndexPath.section < self.dataSourceArray.count) { -// NSMutableArray *section = self.dataSourceArray[tapIndexPath.section]; -// if (tapIndexPath.item < section.count) { -// [section removeObjectAtIndex:tapIndexPath.item]; -// [self.collectionView performBatchUpdates:^{ -// [self.collectionView deleteItemsAtIndexPaths:@[tapIndexPath]]; -// } completion:nil]; -// } -// } -// }]; - [KBAlert confirmTitle:@"删除该标签?" - message:@"删除后不可恢复" - ok:@"确定" - cancel:@"取消" + [KBAlert confirmTitle:KBLocalized(@"Delete this tag?") + message:KBLocalized(@"This action cannot be undone") + ok:KBLocalized(@"Confirm") + cancel:KBLocalized(@"Cancel") okColor:[UIColor redColor] cancelColor:[UIColor blackColor] completion:^(BOOL ok) { @@ -229,7 +216,7 @@ static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId"; - (void)onSave { // 这里只做示意:保存当前顺序 NSLog(@"保存顺序: %@", self.dataSourceArray); - [KBHUD showInfo:@"已保存"]; + [KBHUD showInfo:KBLocalized(@"Saved")]; } #pragma mark - Lazy UI diff --git a/keyBoard/Class/Me/VC/KBPersonInfoVC.m b/keyBoard/Class/Me/VC/KBPersonInfoVC.m index 8e43b0a..e167163 100644 --- a/keyBoard/Class/Me/VC/KBPersonInfoVC.m +++ b/keyBoard/Class/Me/VC/KBPersonInfoVC.m @@ -176,7 +176,7 @@ NSString *userID = self.items[2][@"value"]; if (userID.length == 0) return; UIPasteboard.generalPasteboard.string = userID; - [KBHUD showInfo:@"复制成功"]; + [KBHUD showInfo:KBLocalized(@"Copy Success")]; } } diff --git a/keyBoard/Class/Me/VC/KBSkinDetailVC.m b/keyBoard/Class/Me/VC/KBSkinDetailVC.m index af1f55a..8d77406 100644 --- a/keyBoard/Class/Me/VC/KBSkinDetailVC.m +++ b/keyBoard/Class/Me/VC/KBSkinDetailVC.m @@ -55,11 +55,8 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { make.left.equalTo(self.view).offset(15); make.right.equalTo(self.view).offset(-15); make.height.mas_equalTo([KBSkinBottomActionView preferredHeight]); - if (@available(iOS 11.0, *)) { - make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom); - } else { - make.bottom.equalTo(self.view); - } + make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-10); + }]; // 列表底部距离操作条顶部 10 diff --git a/keyBoard/Class/Me/VC/MySkinVC.m b/keyBoard/Class/Me/VC/MySkinVC.m index 932d4e3..5354c6b 100644 --- a/keyBoard/Class/Me/VC/MySkinVC.m +++ b/keyBoard/Class/Me/VC/MySkinVC.m @@ -61,9 +61,9 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; // 空态视图(LYEmptyView)统一样式 + 重试按钮 KBWeakSelf [self.collectionView kb_makeDefaultEmptyViewWithImage:nil - title:@"暂无皮肤" - detail:@"下拉刷新试试" - buttonTitle:@"重试" + title:KBLocalized(@"No skins yet") + detail:KBLocalized(@"Pull down to refresh") + buttonTitle:KBLocalized(@"Retry") tapHandler:nil buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }]; [self.collectionView kb_setLYAutoShowEnabled:NO]; // 采用手动控制显隐 @@ -224,7 +224,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; CGFloat spacing = 12; CGFloat W = UIScreen.mainScreen.bounds.size.width; CGFloat itemW = floor((W - inset * 2 - spacing) / 2.0); - CGFloat itemH = itemW * 0.82f; // 接近截图比例 + CGFloat itemH = KBFit(168); // 接近截图比例 layout.itemSize = CGSizeMake(itemW, itemH); layout.minimumInteritemSpacing = spacing; layout.minimumLineSpacing = spacing; diff --git a/keyBoard/Class/Network/KBNetworkManager.m b/keyBoard/Class/Network/KBNetworkManager.m index 71d5124..e814bcb 100644 --- a/keyBoard/Class/Network/KBNetworkManager.m +++ b/keyBoard/Class/Network/KBNetworkManager.m @@ -62,7 +62,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; parameters:parameters error:&serror]; if (serror || !req) { - if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: @"无效的URL"}]); + if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid URL")}]); return nil; } [self applyHeaders:headers toMutableRequest:req contentType:nil]; @@ -109,7 +109,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; - (BOOL)ensureEnabled:(KBNetworkCompletion)completion { if (!self.isEnabled) { - NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: @"网络未启用(可能未开启完全访问)"}]; + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Network disabled (Full Access may be off)")}]; if (completion) completion(nil, nil, e); return NO; } @@ -162,12 +162,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; } NSData *data = (NSData *)responseObject; if (![data isKindOfClass:[NSData class]]) { -#if DEBUG - KBLOG(@"无效响应\nURL: %@\n说明: %@", req.URL.absoluteString, @"未获取到数据"); -#endif - if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:@"无数据"}]); - return; - } + #if DEBUG + KBLOG(@"无效响应\nURL: %@\n说明: %@", req.URL.absoluteString, KBLocalized(@"未获取到数据")); + #endif + if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"No data")}]); + return; + } NSString *ct = nil; if ([response isKindOfClass:[NSHTTPURLResponse class]]) { ct = ((NSHTTPURLResponse *)response).allHeaderFields[@"Content-Type"]; @@ -189,12 +189,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; NSError *jsonErr = nil; id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonErr]; if (jsonErr) { -#if DEBUG + #if DEBUG KBLOG(@"响应解析失败(JSON)\nURL: %@\n错误: %@", req.URL.absoluteString, jsonErr.localizedDescription); -#endif - if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:@"JSON解析失败"}]); + #endif + if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"Failed to parse JSON")}]); return; } #if DEBUG @@ -243,20 +243,20 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network"; #pragma mark - Private helpers -- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion { - NSString *msg = @"网络错误"; - switch (code) { - case KBNetworkErrorDisabled: msg = @"网络未启用(可能未开启完全访问)"; break; - case KBNetworkErrorInvalidURL: msg = @"无效的URL"; break; - case KBNetworkErrorInvalidResponse: msg = @"无效的响应"; break; - case KBNetworkErrorDecodeFailed: msg = @"解析失败"; break; - default: break; + - (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion { + NSString *msg = KBLocalized(@"Network error"); + switch (code) { + case KBNetworkErrorDisabled: msg = KBLocalized(@"Network disabled (Full Access may be off)"); break; + case KBNetworkErrorInvalidURL: msg = KBLocalized(@"Invalid URL"); break; + case KBNetworkErrorInvalidResponse: msg = KBLocalized(@"Invalid response"); break; + case KBNetworkErrorDecodeFailed: msg = KBLocalized(@"Parse failed"); break; + default: break; + } + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain + code:code + userInfo:@{NSLocalizedDescriptionKey: msg}]; + if (completion) completion(nil, nil, e); } - NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain - code:code - userInfo:@{NSLocalizedDescriptionKey: msg}]; - if (completion) completion(nil, nil, e); -} @end diff --git a/keyBoard/Class/Pay/M/IAPVerifyTransactionObj.m b/keyBoard/Class/Pay/M/IAPVerifyTransactionObj.m index b277af3..e0cd440 100644 --- a/keyBoard/Class/Pay/M/IAPVerifyTransactionObj.m +++ b/keyBoard/Class/Pay/M/IAPVerifyTransactionObj.m @@ -42,12 +42,12 @@ __weak typeof(self) weakSelf = self; [self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) { [KBHUD dismiss]; - [KBHUD showInfo:(sta == ERROR_CODE ? @"支付失败" : @"支付成功")]; + [KBHUD showInfo:(sta == ERROR_CODE ? KBLocalized(@"Payment failed") : KBLocalized(@"Payment successful"))]; if (sta == SUCCESS_CODE) { [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - if (handler) handler(@"成功", nil); + if (handler) handler(KBLocalized(@"Success"), nil); } else { - if (handler) handler(@"失败", nil); + if (handler) handler(KBLocalized(@"Failed"), nil); } (void)weakSelf; // keep self during block life if needed }]; @@ -68,4 +68,3 @@ } @end - diff --git a/keyBoard/Class/Pay/VC/KBJfPay.m b/keyBoard/Class/Pay/VC/KBJfPay.m index ed3f1ef..5a525f6 100644 --- a/keyBoard/Class/Pay/VC/KBJfPay.m +++ b/keyBoard/Class/Pay/VC/KBJfPay.m @@ -254,7 +254,7 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId"; } - (void)agreementButtonAction{ - [KBHUD showInfo:@"跳转协议"]; + [KBHUD showInfo:KBLocalized(@"Open agreement")]; } #pragma mark - Lazy UI diff --git a/keyBoard/Class/Pay/VC/KBVipPay.m b/keyBoard/Class/Pay/VC/KBVipPay.m index 6bdccd2..e75f55f 100644 --- a/keyBoard/Class/Pay/VC/KBVipPay.m +++ b/keyBoard/Class/Pay/VC/KBVipPay.m @@ -127,10 +127,10 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId"; #pragma mark - Bottom Actions - (void)onTapPayButton { // TODO: 接入支付,这里仅做 UI - [KBHUD showInfo:@"Pay clicked"]; + [KBHUD showInfo:KBLocalized(@"Pay clicked")]; } - (void)agreementButtonAction{ - [KBHUD showInfo:@"跳转协议"]; + [KBHUD showInfo:KBLocalized(@"Open agreement")]; } #pragma mark - UICollectionView DataSource diff --git a/keyBoard/Class/Pay/VM/PayVM.m b/keyBoard/Class/Pay/VM/PayVM.m index 42ddd16..062f01a 100644 --- a/keyBoard/Class/Pay/VM/PayVM.m +++ b/keyBoard/Class/Pay/VM/PayVM.m @@ -18,12 +18,12 @@ if (needShow) { [KBHUD dismiss]; } if (error) { - if (completion) completion(ERROR_CODE, error.localizedDescription ?: @"网络错误"); + if (completion) completion(ERROR_CODE, error.localizedDescription ?: KBLocalized(@"Network error")); return; } NSInteger sta = [self.class extractStatusFromResponseObject:jsonOrData response:response]; - NSString *msg = [self.class extractMessageFromResponseObject:jsonOrData] ?: (sta == SUCCESS_CODE ? @"OK" : @"失败"); + NSString *msg = [self.class extractMessageFromResponseObject:jsonOrData] ?: (sta == SUCCESS_CODE ? @"OK" : KBLocalized(@"Failed")); if (completion) completion(sta, msg); }]; } @@ -62,4 +62,3 @@ } @end - diff --git a/keyBoard/Class/Search/V/KBSearchSectionHeader.m b/keyBoard/Class/Search/V/KBSearchSectionHeader.m index 220e97f..ab4fe6a 100644 --- a/keyBoard/Class/Search/V/KBSearchSectionHeader.m +++ b/keyBoard/Class/Search/V/KBSearchSectionHeader.m @@ -44,10 +44,10 @@ - (void)tapTrash { // 弹出确认框:是否删除所有历史记录 __weak typeof(self) weakSelf = self; - [KBAlert confirmTitle:@"清空历史" - message:@"是否删除所有历史记录?" - ok:@"确定" - cancel:@"取消" + [KBAlert confirmTitle:KBLocalized(@"Clear history") + message:KBLocalized(@"Delete all history?") + ok:KBLocalized(@"Confirm") + cancel:KBLocalized(@"Cancel") okColor:weakSelf.confirmColor cancelColor:weakSelf.cancelColor completion:^(BOOL ok) { diff --git a/keyBoard/Class/Search/VC/KBSearchVC.m b/keyBoard/Class/Search/VC/KBSearchVC.m index 68110f9..f4b9d28 100644 --- a/keyBoard/Class/Search/VC/KBSearchVC.m +++ b/keyBoard/Class/Search/VC/KBSearchVC.m @@ -83,7 +83,12 @@ typedef NS_ENUM(NSInteger, KBSearchSection) { }]; // 初始化测试数据 - self.historyWords = [@[@"果冻橙", @"芒果", @"有机水果卷心菜", @"水果萝卜", @"熟冻帝王蟹", @"赣南脐橙"] mutableCopy]; + self.historyWords = [@[KBLocalized(@"果冻橙"), + KBLocalized(@"芒果"), + KBLocalized(@"有机水果卷心菜"), + KBLocalized(@"水果萝卜"), + KBLocalized(@"熟冻帝王蟹"), + KBLocalized(@"赣南脐橙")] mutableCopy]; self.recommendItems = @[ @{@"title":@"Dopamine", @"price":@"20"}, @{@"title":@"Dopamine", @"price":@"20"}, diff --git a/keyBoard/Class/Shop/VC/KBShopItemVC.m b/keyBoard/Class/Shop/VC/KBShopItemVC.m index 9a9e79c..5c6ea17 100644 --- a/keyBoard/Class/Shop/VC/KBShopItemVC.m +++ b/keyBoard/Class/Shop/VC/KBShopItemVC.m @@ -38,7 +38,7 @@ if (self.isNeedFooter) { self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [weakSelf.dataSource addObject:@"加载更多成功"]; // 模拟新增一条 + [weakSelf.dataSource addObject:KBLocalized(@"Loaded more successfully")]; // 模拟新增一条 [weakSelf.collectionView reloadData]; [weakSelf.collectionView.mj_footer endRefreshing]; }); diff --git a/keyBoard/Class/Shop/VC/KBShopVC.m b/keyBoard/Class/Shop/VC/KBShopVC.m index 2a0bfc3..be800a5 100644 --- a/keyBoard/Class/Shop/VC/KBShopVC.m +++ b/keyBoard/Class/Shop/VC/KBShopVC.m @@ -76,7 +76,10 @@ static const CGFloat JXheightForHeaderInSection = 50; self.view.backgroundColor = [UIColor whiteColor]; self.navigationController.navigationBar.translucent = false; self.edgesForExtendedLayout = UIRectEdgeNone; - _titles = @[@"能力", @"爱好", @"队友",@"能力2", @"爱好2", @"队友2",@"能力", @"爱好", @"队友",@"能力2", @"爱好2", @"队友2"]; + _titles = @[KBLocalized(@"能力"), KBLocalized(@"爱好"), KBLocalized(@"队友"), + KBLocalized(@"能力2"), KBLocalized(@"爱好2"), KBLocalized(@"队友2"), + KBLocalized(@"能力"), KBLocalized(@"爱好"), KBLocalized(@"队友"), + KBLocalized(@"能力2"), KBLocalized(@"爱好2"), KBLocalized(@"队友2")]; _userHeaderView = [[KBShopHeadView alloc] init]; _categoryView = (JXCategoryTitleView *)[[KBCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, JXheightForHeaderInSection)]; @@ -130,8 +133,8 @@ static const CGFloat JXheightForHeaderInSection = 50; __weak typeof(self)weakSelf = self; self.pagerView.mainTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - self.categoryView.titles = @[@"高级能力", @"高级爱好", @"高级队友"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.categoryView.titles = @[KBLocalized(@"高级能力"), KBLocalized(@"高级爱好"), KBLocalized(@"高级队友")]; self.categoryView.defaultSelectedIndex = 0; [self.categoryView reloadData]; [self.pagerView reloadData]; @@ -147,7 +150,7 @@ static const CGFloat JXheightForHeaderInSection = 50; self.naviBGView.frame = CGRectMake(0, 0, KB_SCREEN_WIDTH, KB_NAV_TOTAL_HEIGHT); [self.view addSubview:self.naviBGView]; UILabel *naviTitleLabel = [[UILabel alloc] init]; - naviTitleLabel.text = @"商城"; + naviTitleLabel.text = KBLocalized(@"商城"); naviTitleLabel.textAlignment = NSTextAlignmentCenter; naviTitleLabel.frame = CGRectMake(0, KB_STATUSBAR_HEIGHT, self.view.bounds.size.width, 44); [self.naviBGView addSubview:naviTitleLabel]; @@ -192,11 +195,18 @@ static const CGFloat JXheightForHeaderInSection = 50; list.isNeedHeader = self.isNeedHeader; list.isNeedFooter = self.isNeedFooter; if (index == 0) { - list.dataSource = @[@"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮", @"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮"].mutableCopy; + list.dataSource = @[KBLocalized(@"橡胶火箭"), KBLocalized(@"橡胶火箭炮"), KBLocalized(@"橡胶机关枪"), KBLocalized(@"橡胶子弹"), + KBLocalized(@"橡胶攻城炮"), KBLocalized(@"橡胶象枪"), KBLocalized(@"橡胶象枪乱打"), KBLocalized(@"橡胶灰熊铳"), + KBLocalized(@"橡胶雷神象枪"), KBLocalized(@"橡胶猿王枪"), KBLocalized(@"橡胶犀·榴弹炮"), KBLocalized(@"橡胶大蛇炮"), + KBLocalized(@"橡胶火箭"), KBLocalized(@"橡胶火箭炮"), KBLocalized(@"橡胶机关枪"), KBLocalized(@"橡胶子弹"), + KBLocalized(@"橡胶攻城炮"), KBLocalized(@"橡胶象枪"), KBLocalized(@"橡胶象枪乱打"), KBLocalized(@"橡胶灰熊铳"), + KBLocalized(@"橡胶雷神象枪"), KBLocalized(@"橡胶猿王枪"), KBLocalized(@"橡胶犀·榴弹炮"), KBLocalized(@"橡胶大蛇炮")].mutableCopy; }else if (index == 1) { - list.dataSource = @[@"吃烤肉", @"吃鸡腿肉", @"吃牛肉", @"各种肉"].mutableCopy; + list.dataSource = @[KBLocalized(@"吃烤肉"), KBLocalized(@"吃鸡腿肉"), KBLocalized(@"吃牛肉"), KBLocalized(@"各种肉")].mutableCopy; }else { - list.dataSource = @[@"【剑士】罗罗诺亚·索隆", @"【航海士】娜美", @"【狙击手】乌索普", @"【厨师】香吉士", @"【船医】托尼托尼·乔巴", @"【船匠】 弗兰奇", @"【音乐家】布鲁克", @"【考古学家】妮可·罗宾"].mutableCopy; + list.dataSource = @[KBLocalized(@"【剑士】罗罗诺亚·索隆"), KBLocalized(@"【航海士】娜美"), KBLocalized(@"【狙击手】乌索普"), + KBLocalized(@"【厨师】香吉士"), KBLocalized(@"【船医】托尼托尼·乔巴"), KBLocalized(@"【船匠】 弗兰奇"), + KBLocalized(@"【音乐家】布鲁克"), KBLocalized(@"【考古学家】妮可·罗宾")].mutableCopy; } return list; } diff --git a/keyBoard/ViewController.m b/keyBoard/ViewController.m index d974212..90bdb2c 100644 --- a/keyBoard/ViewController.m +++ b/keyBoard/ViewController.m @@ -20,7 +20,7 @@ - (void)setupTextField { CGRect frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 200)/2, ([UIScreen mainScreen].bounds.size.height - 200)/2, 200, 200); self.textView = [[UITextView alloc] initWithFrame:frame]; - self.textView.text = @"测试"; + self.textView.text = KBLocalized(@"测试"); self.textView.layer.borderColor = [UIColor blackColor].CGColor; self.textView.layer.borderWidth = 0.5; [self.view addSubview:self.textView];