From 48f19a3c9a14396406df83e81883fa3aa187df16 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 10:47:37 +0900 Subject: [PATCH 1/9] create strings catalog --- PasswordBox.xcodeproj/project.pbxproj | 6 +- PasswordBox/Resources/Localizable.xcstrings | 75 +++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 PasswordBox/Resources/Localizable.xcstrings diff --git a/PasswordBox.xcodeproj/project.pbxproj b/PasswordBox.xcodeproj/project.pbxproj index ed0e0a9..adde63c 100644 --- a/PasswordBox.xcodeproj/project.pbxproj +++ b/PasswordBox.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 3F13F9C82C1DED720068908E /* EditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F13F9C72C1DED720068908E /* EditView.swift */; }; 3F13F9CB2C1DEE020068908E /* PasswordFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F13F9CA2C1DEE020068908E /* PasswordFormView.swift */; }; 3F1DFECF2C4B552E00BAA193 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */; }; + 3F1DFEDD2C4CA01300BAA193 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */; }; 3F3DE2F82C1DE2500089CB5A /* InfomationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */; }; 3F3DE2FA2C1DE2710089CB5A /* AddView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F92C1DE2710089CB5A /* AddView.swift */; }; 3F6AA4B82C2FDF22008EC918 /* PasswordField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */; }; @@ -68,6 +69,7 @@ 3F13F9C72C1DED720068908E /* EditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditView.swift; sourceTree = ""; }; 3F13F9CA2C1DEE020068908E /* PasswordFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordFormView.swift; sourceTree = ""; }; 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; }; + 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfomationView.swift; sourceTree = ""; }; 3F3DE2F92C1DE2710089CB5A /* AddView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddView.swift; sourceTree = ""; }; 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordField.swift; sourceTree = ""; }; @@ -291,6 +293,7 @@ 3F99FC502C390D65001ED4B2 /* IconStyles.swift */, 3F026F432C3A789500ED696C /* URLs.swift */, 3FEE0F152C3C2EDE0057EE2F /* AppTips.swift */, + 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */, ); path = Resources; sourceTree = ""; @@ -380,7 +383,7 @@ }; buildConfigurationList = 3F8C85922C189D4A0032277E /* Build configuration list for PBXProject "PasswordBox" */; compatibilityVersion = "Xcode 14.0"; - developmentRegion = ja; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -410,6 +413,7 @@ files = ( 3F8C85A22C189D4B0032277E /* Preview Assets.xcassets in Resources */, 3F8C859F2C189D4B0032277E /* Assets.xcassets in Resources */, + 3F1DFEDD2C4CA01300BAA193 /* Localizable.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PasswordBox/Resources/Localizable.xcstrings b/PasswordBox/Resources/Localizable.xcstrings new file mode 100644 index 0000000..01737eb --- /dev/null +++ b/PasswordBox/Resources/Localizable.xcstrings @@ -0,0 +1,75 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "OK" : { + + }, + "PasswordField" : { + + }, + "アイコンとタイトルはこちらから編集することができます。" : { + + }, + "アイコンとタイトルを変更" : { + + }, + "アイコンを選択" : { + + }, + "アプリを使用するには端末の認証が必要です。\n 続けるには**再認証**をしてください" : { + + }, + "アプリ情報" : { + + }, + "アルファベット" : { + + }, + "キャンセル" : { + + }, + "テキストフィールド" : { + + }, + "バージョン" : { + + }, + "パスワードを手動で編集" : { + + }, + "パスワードを自動更新" : { + + }, + "リスト" : { + + }, + "リスト名" : { + + }, + "ログイン認証が必要です" : { + + }, + "再認証する" : { + + }, + "完了" : { + + }, + "情報" : { + + }, + "文字数: %lld" : { + + }, + "編集" : { + + }, + "記号" : { + + }, + "追加" : { + + } + }, + "version" : "1.0" +} \ No newline at end of file From 6b4e9c7ed89a52729f1a1f27fd491b41b0a79f49 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 10:58:09 +0900 Subject: [PATCH 2/9] Translate ContentView --- PasswordBox/ContentView.swift | 8 ++-- PasswordBox/Resources/Localizable.xcstrings | 49 +++++++++++++++++---- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/PasswordBox/ContentView.swift b/PasswordBox/ContentView.swift index b246a44..a6c0b26 100644 --- a/PasswordBox/ContentView.swift +++ b/PasswordBox/ContentView.swift @@ -18,15 +18,15 @@ struct ContentView: View { .cornerRadius(4) .padding(.horizontal, 16) - Text("ログイン認証が必要です") + Text("Login authentication is required") .font(.title) - Text("アプリを使用するには端末の認証が必要です。\n 続けるには**再認証**をしてください") + Text("You must authenticate your device in order to use the application. \n Please **re-authenticate** to continue") .multilineTextAlignment(.center) Button(action: { authenticate() }, label: { - Text("再認証する") + Text("Re-authenticate") .padding() .foregroundColor(.white) .background(.blue) @@ -48,7 +48,7 @@ struct ContentView: View { var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) { - let description = "認証が必要です" + let description = String(localized: "Authentication required") context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: description) { success, authenticationError in DispatchQueue.main.async { diff --git a/PasswordBox/Resources/Localizable.xcstrings b/PasswordBox/Resources/Localizable.xcstrings index 01737eb..1d085b3 100644 --- a/PasswordBox/Resources/Localizable.xcstrings +++ b/PasswordBox/Resources/Localizable.xcstrings @@ -1,11 +1,51 @@ { "sourceLanguage" : "en", "strings" : { + "Authentication required" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "認証が必要です" + } + } + } + }, + "Login authentication is required" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ログイン認証が必要です" + } + } + } + }, "OK" : { }, "PasswordField" : { + }, + "Re-authenticate" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "再認証する" + } + } + } + }, + "You must authenticate your device in order to use the application. \n Please **re-authenticate** to continue" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリを使用するには端末の認証が必要です。続けるには**再認証**をしてください" + } + } + } }, "アイコンとタイトルはこちらから編集することができます。" : { @@ -15,9 +55,6 @@ }, "アイコンを選択" : { - }, - "アプリを使用するには端末の認証が必要です。\n 続けるには**再認証**をしてください" : { - }, "アプリ情報" : { @@ -45,12 +82,6 @@ }, "リスト名" : { - }, - "ログイン認証が必要です" : { - - }, - "再認証する" : { - }, "完了" : { From c8fc1312f59ce0451ef11a280b1f6b7b866a82c2 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 11:06:42 +0900 Subject: [PATCH 3/9] Translate Common --- PasswordBox/Resources/Localizable.xcstrings | 78 +++++++++++++++----- PasswordBox/UI/Common/PasswordField.swift | 4 +- PasswordBox/UI/Common/PasswordFormView.swift | 11 ++- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/PasswordBox/Resources/Localizable.xcstrings b/PasswordBox/Resources/Localizable.xcstrings index 1d085b3..46c5b74 100644 --- a/PasswordBox/Resources/Localizable.xcstrings +++ b/PasswordBox/Resources/Localizable.xcstrings @@ -1,6 +1,16 @@ { "sourceLanguage" : "en", "strings" : { + "alphabet" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アルファベット" + } + } + } + }, "Authentication required" : { "localizations" : { "ja" : { @@ -11,6 +21,26 @@ } } }, + "Automatic Password Update" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを自動更新" + } + } + } + }, + "Edit password manually" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "パスワードを手動で編集" + } + } + } + }, "Login authentication is required" : { "localizations" : { "ja" : { @@ -21,6 +51,16 @@ } } }, + "number of characters: %lld" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "文字数: %lld" + } + } + } + }, "OK" : { }, @@ -37,6 +77,26 @@ } } }, + "symbol" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "記号" + } + } + } + }, + "Text Field" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "テキストフィールド" + } + } + } + }, "You must authenticate your device in order to use the application. \n Please **re-authenticate** to continue" : { "localizations" : { "ja" : { @@ -58,24 +118,12 @@ }, "アプリ情報" : { - }, - "アルファベット" : { - }, "キャンセル" : { - }, - "テキストフィールド" : { - }, "バージョン" : { - }, - "パスワードを手動で編集" : { - - }, - "パスワードを自動更新" : { - }, "リスト" : { @@ -88,15 +136,9 @@ }, "情報" : { - }, - "文字数: %lld" : { - }, "編集" : { - }, - "記号" : { - }, "追加" : { diff --git a/PasswordBox/UI/Common/PasswordField.swift b/PasswordBox/UI/Common/PasswordField.swift index 3be984c..d363bb0 100644 --- a/PasswordBox/UI/Common/PasswordField.swift +++ b/PasswordBox/UI/Common/PasswordField.swift @@ -22,8 +22,8 @@ struct PasswordField: View { .privacySensitive(isShowSecure) .redacted(reason: .privacy) } - .alert("パスワードを手動で編集", isPresented: $isPresented) { - TextField("テキストフィールド", text: $text) + .alert("Edit password manually", isPresented: $isPresented) { + TextField("Text Field", text: $text) Button { print("OK") diff --git a/PasswordBox/UI/Common/PasswordFormView.swift b/PasswordBox/UI/Common/PasswordFormView.swift index 8f1fe19..46bf764 100644 --- a/PasswordBox/UI/Common/PasswordFormView.swift +++ b/PasswordBox/UI/Common/PasswordFormView.swift @@ -39,7 +39,6 @@ struct PasswordFormView: View { .padding() Button(action: { - print("更新します") passwordString = CreatePassword.createPassword( length: passwordLength, isAlphabet, @@ -47,7 +46,7 @@ struct PasswordFormView: View { ) }, label: { - Text("パスワードを自動更新") + Text("Automatic Password Update") .padding() .foregroundColor(.white) .background(.blue) @@ -57,20 +56,20 @@ struct PasswordFormView: View { Section { VStack(spacing: 30) { Stepper(value: $passwordLength, in: 1...100) { - Text("文字数: \(passwordLength)") + Text("number of characters: \(passwordLength)") } Toggle(isOn: $isAlphabet, label: { - Text("アルファベット") + Text("alphabet") }) Toggle(isOn: $isSymbol, label: { - Text("記号") + Text("symbol") }) // TODO: 今後実装 // Toggle(isOn: $isNotice, label: { -// Text("通知") +// Text("notice") // }) } .padding(.horizontal, 20) From 9a6da32ce62b177564e8050387d51106be111a33 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 11:12:45 +0900 Subject: [PATCH 4/9] Translate List --- PasswordBox/Resources/Localizable.xcstrings | 109 ++++++++++++++---- PasswordBox/UI/List/Add/AddView.swift | 6 +- PasswordBox/UI/List/Edit/EditView.swift | 5 +- PasswordBox/UI/List/ListView.swift | 2 +- .../UI/List/SettingIcon/IconView.swift | 4 +- .../UI/List/SettingIcon/SettingIconView.swift | 6 +- 6 files changed, 97 insertions(+), 35 deletions(-) diff --git a/PasswordBox/Resources/Localizable.xcstrings b/PasswordBox/Resources/Localizable.xcstrings index 46c5b74..ea75cc4 100644 --- a/PasswordBox/Resources/Localizable.xcstrings +++ b/PasswordBox/Resources/Localizable.xcstrings @@ -1,6 +1,16 @@ { "sourceLanguage" : "en", "strings" : { + "Add" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "追加" + } + } + } + }, "alphabet" : { "localizations" : { "ja" : { @@ -31,6 +41,36 @@ } } }, + "Cancel" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "キャンセル" + } + } + } + }, + "Completion" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "完了" + } + } + } + }, + "Edit" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "編集" + } + } + } + }, "Edit password manually" : { "localizations" : { "ja" : { @@ -41,6 +81,26 @@ } } }, + "List" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リスト" + } + } + } + }, + "List Name" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "リスト名" + } + } + } + }, "Login authentication is required" : { "localizations" : { "ja" : { @@ -62,10 +122,24 @@ } }, "OK" : { - + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "OK" + } + } + } }, "PasswordField" : { - + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PasswordField" + } + } + } }, "Re-authenticate" : { "localizations" : { @@ -77,6 +151,16 @@ } } }, + "Select Icon" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アイコン選択" + } + } + } + }, "symbol" : { "localizations" : { "ja" : { @@ -112,36 +196,15 @@ }, "アイコンとタイトルを変更" : { - }, - "アイコンを選択" : { - }, "アプリ情報" : { - }, - "キャンセル" : { - }, "バージョン" : { - }, - "リスト" : { - - }, - "リスト名" : { - - }, - "完了" : { - }, "情報" : { - }, - "編集" : { - - }, - "追加" : { - } }, "version" : "1.0" diff --git a/PasswordBox/UI/List/Add/AddView.swift b/PasswordBox/UI/List/Add/AddView.swift index 330afce..4ad236f 100644 --- a/PasswordBox/UI/List/Add/AddView.swift +++ b/PasswordBox/UI/List/Add/AddView.swift @@ -14,16 +14,16 @@ struct AddView: View { var body: some View { NavigationStack { PasswordFormView(title: $title, iconString: $iconString, passwordString: $passwordString, passwordLength: $passwordLength) - .navigationTitle("追加") + .navigationTitle("Add") .toolbar { ToolbarItem(placement: .topBarLeading) { - Button("キャンセル") { + Button("Cancel") { dismiss() } } ToolbarItem(placement: .topBarTrailing) { - Button("完了") { + Button("Completion") { viewModel.add(context, title, iconString, passwordString) dismiss() } diff --git a/PasswordBox/UI/List/Edit/EditView.swift b/PasswordBox/UI/List/Edit/EditView.swift index 895f015..a4328e0 100644 --- a/PasswordBox/UI/List/Edit/EditView.swift +++ b/PasswordBox/UI/List/Edit/EditView.swift @@ -11,10 +11,10 @@ struct EditView: View { var body: some View { NavigationStack { PasswordFormView(title: $entry.title, iconString: $entry.iconString, passwordString: $passwordString, passwordLength: $passwordLength) - .navigationTitle("編集") + .navigationTitle("Edit") .toolbar { ToolbarItem(placement: .topBarTrailing) { - Button("完了") { + Button("Completion") { viewModel.save(context, key: entry.id, passwordString) dismiss() } @@ -23,7 +23,6 @@ struct EditView: View { } .onAppear { load(key: entry.id) - print("entryid: \(entry.id)") } } diff --git a/PasswordBox/UI/List/ListView.swift b/PasswordBox/UI/List/ListView.swift index 598944a..7dbb533 100644 --- a/PasswordBox/UI/List/ListView.swift +++ b/PasswordBox/UI/List/ListView.swift @@ -25,7 +25,7 @@ struct ListView: View { } }) } - .navigationTitle("リスト") + .navigationTitle("List") .toolbar { ToolbarItem(placement: .topBarLeading) { Button { diff --git a/PasswordBox/UI/List/SettingIcon/IconView.swift b/PasswordBox/UI/List/SettingIcon/IconView.swift index 266c396..3a88795 100644 --- a/PasswordBox/UI/List/SettingIcon/IconView.swift +++ b/PasswordBox/UI/List/SettingIcon/IconView.swift @@ -18,7 +18,7 @@ struct IconView: View { .padding(.horizontal, 16) TextField(text: $title, axis: .vertical) { - Text("リスト名") + Text("List Name") } .font(.title) .textFieldStyle(.roundedBorder) @@ -27,7 +27,7 @@ struct IconView: View { } } - // TODO: 検討中 + // TODO: under consideration // Section { // ScrollView(.horizontal, showsIndicators: false) { // HStack { diff --git a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift index 549a523..8be989d 100644 --- a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift +++ b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift @@ -7,16 +7,16 @@ struct SettingIconView: View { var body: some View { NavigationStack { IconView(title: $title, iconString: $iconString) - .navigationTitle("アイコンを選択") + .navigationTitle("Select Icon") .toolbar { ToolbarItem(placement: .topBarLeading) { - Button("キャンセル") { + Button("Cancel") { dismiss() } } ToolbarItem(placement: .topBarTrailing) { - Button("完了") { + Button("Completion") { dismiss() } } From 6e6c57c28734f9d2448cdc4414ae852f3624187e Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 11:22:28 +0900 Subject: [PATCH 5/9] Translate Infomation --- PasswordBox/Resources/AppTips.swift | 4 +- PasswordBox/Resources/Localizable.xcstrings | 115 +++++++++++++++--- PasswordBox/UI/Info/InfomationView.swift | 20 ++- PasswordBox/UI/Info/InfomationViewModel.swift | 2 +- PasswordBox/UI/List/Add/AddView.swift | 2 +- PasswordBox/UI/List/Edit/EditView.swift | 2 +- .../UI/List/SettingIcon/SettingIconView.swift | 2 +- 7 files changed, 113 insertions(+), 34 deletions(-) diff --git a/PasswordBox/Resources/AppTips.swift b/PasswordBox/Resources/AppTips.swift index 28d20df..aa34e29 100644 --- a/PasswordBox/Resources/AppTips.swift +++ b/PasswordBox/Resources/AppTips.swift @@ -3,10 +3,10 @@ import TipKit struct AppTips { struct ChangeIcon: Tip { var title: Text { - Text("アイコンとタイトルを変更") + Text("Change icon and title") } var message: Text? { - Text("アイコンとタイトルはこちらから編集することができます。") + Text("Icons and titles can be edited here.") } } diff --git a/PasswordBox/Resources/Localizable.xcstrings b/PasswordBox/Resources/Localizable.xcstrings index ea75cc4..c4dfcbb 100644 --- a/PasswordBox/Resources/Localizable.xcstrings +++ b/PasswordBox/Resources/Localizable.xcstrings @@ -21,6 +21,16 @@ } } }, + "App Infomation" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリ情報" + } + } + } + }, "Authentication required" : { "localizations" : { "ja" : { @@ -51,7 +61,27 @@ } } }, - "Completion" : { + "Change icon and title" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アイコンとタイトルを変更" + } + } + } + }, + "Contact Us" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "お問い合わせ" + } + } + } + }, + "Done" : { "localizations" : { "ja" : { "stringUnit" : { @@ -81,6 +111,36 @@ } } }, + "Icons and titles can be edited here." : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アイコンとタイトルはこちらから編集することができます。" + } + } + } + }, + "Infomation" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "情報" + } + } + } + }, + "LICENCE" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "ライセンス" + } + } + } + }, "List" : { "localizations" : { "ja" : { @@ -141,6 +201,16 @@ } } }, + "Privacy Policy" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "プライバシーポリシー" + } + } + } + }, "Re-authenticate" : { "localizations" : { "ja" : { @@ -181,30 +251,45 @@ } } }, - "You must authenticate your device in order to use the application. \n Please **re-authenticate** to continue" : { + "unkown" : { "localizations" : { "ja" : { "stringUnit" : { "state" : "translated", - "value" : "アプリを使用するには端末の認証が必要です。続けるには**再認証**をしてください" + "value" : "不明" } } } }, - "アイコンとタイトルはこちらから編集することができます。" : { - - }, - "アイコンとタイトルを変更" : { - - }, - "アプリ情報" : { - + "Version" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "バージョン" + } + } + } }, - "バージョン" : { - + "WebSite" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "Webサイト" + } + } + } }, - "情報" : { - + "You must authenticate your device in order to use the application. \n Please **re-authenticate** to continue" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アプリを使用するには端末の認証が必要です。続けるには**再認証**をしてください" + } + } + } } }, "version" : "1.0" diff --git a/PasswordBox/UI/Info/InfomationView.swift b/PasswordBox/UI/Info/InfomationView.swift index 28fceab..27fd4e9 100644 --- a/PasswordBox/UI/Info/InfomationView.swift +++ b/PasswordBox/UI/Info/InfomationView.swift @@ -2,35 +2,29 @@ import SwiftUI struct InfomationView: View { private let viewModel = InfomationViewModel() - private let contactUsTitle = "お問い合わせ" - private let privacyPolicy = "プライバシーポリシー" - private let releaseNote = "リリースノート" - private let WebSite = "Webサイト" - private let licenceTitle = "LICENCE" var body: some View { List { - Section("情報") { - Link(privacyPolicy, destination: URL.InfomationView.privacyPolicy) + Section("Infomation") { + Link("Privacy Policy", destination: URL.InfomationView.privacyPolicy) .openURLInSafariView() - Link(contactUsTitle, destination: URL.InfomationView.contactURL) + Link("Contact Us", destination: URL.InfomationView.contactURL) .openURLInSafariView() - Link(WebSite, destination: URL.InfomationView.websiteURL) + Link("WebSite", destination: URL.InfomationView.websiteURL) .openURLInSafariView() - NavigationLink(licenceTitle) { + NavigationLink("LICENCE") { LicenseList() - .navigationTitle(licenceTitle) } } Section { - LabeledContent("バージョン", value: viewModel.versionString) + LabeledContent("Version", value: viewModel.versionString) } } - .navigationTitle("アプリ情報") + .navigationTitle("App Infomation") } } diff --git a/PasswordBox/UI/Info/InfomationViewModel.swift b/PasswordBox/UI/Info/InfomationViewModel.swift index 5e8a16d..d7d0f2e 100644 --- a/PasswordBox/UI/Info/InfomationViewModel.swift +++ b/PasswordBox/UI/Info/InfomationViewModel.swift @@ -3,7 +3,7 @@ import SwiftUI struct InfomationViewModel { var versionString: String { let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String - return version ?? "不明" + return version ?? String(localized: "unkown") } } diff --git a/PasswordBox/UI/List/Add/AddView.swift b/PasswordBox/UI/List/Add/AddView.swift index 4ad236f..0924255 100644 --- a/PasswordBox/UI/List/Add/AddView.swift +++ b/PasswordBox/UI/List/Add/AddView.swift @@ -23,7 +23,7 @@ struct AddView: View { } ToolbarItem(placement: .topBarTrailing) { - Button("Completion") { + Button("Done") { viewModel.add(context, title, iconString, passwordString) dismiss() } diff --git a/PasswordBox/UI/List/Edit/EditView.swift b/PasswordBox/UI/List/Edit/EditView.swift index a4328e0..9303996 100644 --- a/PasswordBox/UI/List/Edit/EditView.swift +++ b/PasswordBox/UI/List/Edit/EditView.swift @@ -14,7 +14,7 @@ struct EditView: View { .navigationTitle("Edit") .toolbar { ToolbarItem(placement: .topBarTrailing) { - Button("Completion") { + Button("Done") { viewModel.save(context, key: entry.id, passwordString) dismiss() } diff --git a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift index 8be989d..8871bf3 100644 --- a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift +++ b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift @@ -16,7 +16,7 @@ struct SettingIconView: View { } ToolbarItem(placement: .topBarTrailing) { - Button("Completion") { + Button("Done") { dismiss() } } From e829ac4a86191a7993771335304242996b63b275 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 12:01:58 +0900 Subject: [PATCH 6/9] Store common button titles in Static --- PasswordBox.xcodeproj/project.pbxproj | 4 ++++ PasswordBox/Resources/CommonButtonStrings.swift | 6 ++++++ PasswordBox/UI/List/Add/AddView.swift | 4 ++-- PasswordBox/UI/List/Edit/EditView.swift | 2 +- PasswordBox/UI/List/SettingIcon/SettingIconView.swift | 4 ++-- 5 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 PasswordBox/Resources/CommonButtonStrings.swift diff --git a/PasswordBox.xcodeproj/project.pbxproj b/PasswordBox.xcodeproj/project.pbxproj index adde63c..f3a0992 100644 --- a/PasswordBox.xcodeproj/project.pbxproj +++ b/PasswordBox.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 3F13F9CB2C1DEE020068908E /* PasswordFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F13F9CA2C1DEE020068908E /* PasswordFormView.swift */; }; 3F1DFECF2C4B552E00BAA193 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */; }; 3F1DFEDD2C4CA01300BAA193 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */; }; + 3F1DFEE12C4CB06700BAA193 /* CommonButtonStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */; }; 3F3DE2F82C1DE2500089CB5A /* InfomationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */; }; 3F3DE2FA2C1DE2710089CB5A /* AddView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F92C1DE2710089CB5A /* AddView.swift */; }; 3F6AA4B82C2FDF22008EC918 /* PasswordField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */; }; @@ -70,6 +71,7 @@ 3F13F9CA2C1DEE020068908E /* PasswordFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordFormView.swift; sourceTree = ""; }; 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; }; 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; + 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonButtonStrings.swift; sourceTree = ""; }; 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfomationView.swift; sourceTree = ""; }; 3F3DE2F92C1DE2710089CB5A /* AddView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddView.swift; sourceTree = ""; }; 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordField.swift; sourceTree = ""; }; @@ -294,6 +296,7 @@ 3F026F432C3A789500ED696C /* URLs.swift */, 3FEE0F152C3C2EDE0057EE2F /* AppTips.swift */, 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */, + 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */, ); path = Resources; sourceTree = ""; @@ -452,6 +455,7 @@ 3F026F292C39A2E400ED696C /* EditViewModel.swift in Sources */, 3F6AA4BE2C3130FC008EC918 /* CreatePassword.swift in Sources */, 3F6AA4B82C2FDF22008EC918 /* PasswordField.swift in Sources */, + 3F1DFEE12C4CB06700BAA193 /* CommonButtonStrings.swift in Sources */, 3F99FC4F2C390873001ED4B2 /* Images.swift in Sources */, 3F99FC592C39258B001ED4B2 /* Entry.swift in Sources */, 3F13F9C82C1DED720068908E /* EditView.swift in Sources */, diff --git a/PasswordBox/Resources/CommonButtonStrings.swift b/PasswordBox/Resources/CommonButtonStrings.swift new file mode 100644 index 0000000..cbc0475 --- /dev/null +++ b/PasswordBox/Resources/CommonButtonStrings.swift @@ -0,0 +1,6 @@ +import Foundation + +struct CommonButtonStrings { + static let done: String = .init(localized: "Done") + static let cancel: String = .init(localized: "Cancel") +} diff --git a/PasswordBox/UI/List/Add/AddView.swift b/PasswordBox/UI/List/Add/AddView.swift index 0924255..2382311 100644 --- a/PasswordBox/UI/List/Add/AddView.swift +++ b/PasswordBox/UI/List/Add/AddView.swift @@ -17,13 +17,13 @@ struct AddView: View { .navigationTitle("Add") .toolbar { ToolbarItem(placement: .topBarLeading) { - Button("Cancel") { + Button(CommonButtonStrings.cancel) { dismiss() } } ToolbarItem(placement: .topBarTrailing) { - Button("Done") { + Button(CommonButtonStrings.done) { viewModel.add(context, title, iconString, passwordString) dismiss() } diff --git a/PasswordBox/UI/List/Edit/EditView.swift b/PasswordBox/UI/List/Edit/EditView.swift index 9303996..2688a95 100644 --- a/PasswordBox/UI/List/Edit/EditView.swift +++ b/PasswordBox/UI/List/Edit/EditView.swift @@ -14,7 +14,7 @@ struct EditView: View { .navigationTitle("Edit") .toolbar { ToolbarItem(placement: .topBarTrailing) { - Button("Done") { + Button(CommonButtonStrings.done) { viewModel.save(context, key: entry.id, passwordString) dismiss() } diff --git a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift index 8871bf3..b7e4c54 100644 --- a/PasswordBox/UI/List/SettingIcon/SettingIconView.swift +++ b/PasswordBox/UI/List/SettingIcon/SettingIconView.swift @@ -10,13 +10,13 @@ struct SettingIconView: View { .navigationTitle("Select Icon") .toolbar { ToolbarItem(placement: .topBarLeading) { - Button("Cancel") { + Button(CommonButtonStrings.cancel) { dismiss() } } ToolbarItem(placement: .topBarTrailing) { - Button("Done") { + Button(CommonButtonStrings.done) { dismiss() } } From 0ea666eb5f66a06a28159c994629b31007e34bef Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 12:08:30 +0900 Subject: [PATCH 7/9] Localized date --- PasswordBox/UI/List/CellView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PasswordBox/UI/List/CellView.swift b/PasswordBox/UI/List/CellView.swift index eff2091..27ab72b 100644 --- a/PasswordBox/UI/List/CellView.swift +++ b/PasswordBox/UI/List/CellView.swift @@ -31,10 +31,10 @@ struct CellView: View { let date = entry.date let formatter = DateFormatter() formatter.dateStyle = .medium - formatter.timeStyle = .medium + formatter.timeStyle = .none formatter.timeZone = .current formatter.locale = .current - formatter.dateFormat = "yyyy年MM月dd日" + formatter.doesRelativeDateFormatting = true return formatter.string(from: date) } } From 9f53e6e5a58bbe006899c782624b13d7b1434361 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 12:24:19 +0900 Subject: [PATCH 8/9] Translate InfoPlist --- PasswordBox.xcodeproj/project.pbxproj | 10 ++++-- PasswordBox/Resources/InfoPlist.xcstrings | 42 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 PasswordBox/Resources/InfoPlist.xcstrings diff --git a/PasswordBox.xcodeproj/project.pbxproj b/PasswordBox.xcodeproj/project.pbxproj index f3a0992..253fe19 100644 --- a/PasswordBox.xcodeproj/project.pbxproj +++ b/PasswordBox.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 3F1DFECF2C4B552E00BAA193 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */; }; 3F1DFEDD2C4CA01300BAA193 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */; }; 3F1DFEE12C4CB06700BAA193 /* CommonButtonStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */; }; + 3F1DFEE32C4CB5F300BAA193 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 3F1DFEE22C4CB5F300BAA193 /* InfoPlist.xcstrings */; }; 3F3DE2F82C1DE2500089CB5A /* InfomationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */; }; 3F3DE2FA2C1DE2710089CB5A /* AddView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3DE2F92C1DE2710089CB5A /* AddView.swift */; }; 3F6AA4B82C2FDF22008EC918 /* PasswordField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */; }; @@ -72,6 +73,7 @@ 3F1DFECE2C4B552E00BAA193 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; }; 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonButtonStrings.swift; sourceTree = ""; }; + 3F1DFEE22C4CB5F300BAA193 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; 3F3DE2F72C1DE2500089CB5A /* InfomationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfomationView.swift; sourceTree = ""; }; 3F3DE2F92C1DE2710089CB5A /* AddView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddView.swift; sourceTree = ""; }; 3F6AA4B72C2FDF22008EC918 /* PasswordField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordField.swift; sourceTree = ""; }; @@ -295,8 +297,9 @@ 3F99FC502C390D65001ED4B2 /* IconStyles.swift */, 3F026F432C3A789500ED696C /* URLs.swift */, 3FEE0F152C3C2EDE0057EE2F /* AppTips.swift */, - 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */, 3F1DFEE02C4CB06700BAA193 /* CommonButtonStrings.swift */, + 3F1DFEDC2C4CA01300BAA193 /* Localizable.xcstrings */, + 3F1DFEE22C4CB5F300BAA193 /* InfoPlist.xcstrings */, ); path = Resources; sourceTree = ""; @@ -416,6 +419,7 @@ files = ( 3F8C85A22C189D4B0032277E /* Preview Assets.xcassets in Resources */, 3F8C859F2C189D4B0032277E /* Assets.xcassets in Resources */, + 3F1DFEE32C4CB5F300BAA193 /* InfoPlist.xcstrings in Resources */, 3F1DFEDD2C4CA01300BAA193 /* Localizable.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -633,7 +637,7 @@ DEVELOPMENT_TEAM = B58T472MM3; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_NSFaceIDUsageDescription = "FaceID を使用してアプリへのアクセスを保護し、安全な認証を提供します"; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Use FaceID to secure access to apps and provide secure authentication"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -669,7 +673,7 @@ DEVELOPMENT_TEAM = B58T472MM3; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_NSFaceIDUsageDescription = "FaceID を使用してアプリへのアクセスを保護し、安全な認証を提供します"; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Use FaceID to secure access to apps and provide secure authentication"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; diff --git a/PasswordBox/Resources/InfoPlist.xcstrings b/PasswordBox/Resources/InfoPlist.xcstrings new file mode 100644 index 0000000..50f2bc8 --- /dev/null +++ b/PasswordBox/Resources/InfoPlist.xcstrings @@ -0,0 +1,42 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "CFBundleName" : { + "comment" : "Bundle name", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "PasswordBox" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "PasswordBox" + } + } + } + }, + "NSFaceIDUsageDescription" : { + "comment" : "Privacy - Face ID Usage Description", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Use FaceID to secure access to apps and provide secure authentication" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "FaceIDを使用してアプリへのアクセスを保護し、安全な認証を提供します。" + } + } + } + } + }, + "version" : "1.0" +} \ No newline at end of file From fc4c70059a91ef4d1afe005ce9e40b16ecbd81e6 Mon Sep 17 00:00:00 2001 From: KaitoMuraoka Date: Sun, 21 Jul 2024 12:37:52 +0900 Subject: [PATCH 9/9] add translate Chinese simplified and Franch --- PasswordBox.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PasswordBox.xcodeproj/project.pbxproj b/PasswordBox.xcodeproj/project.pbxproj index 253fe19..f49640c 100644 --- a/PasswordBox.xcodeproj/project.pbxproj +++ b/PasswordBox.xcodeproj/project.pbxproj @@ -395,6 +395,8 @@ en, Base, ja, + "zh-Hans", + fr, ); mainGroup = 3F8C858E2C189D4A0032277E; packageReferences = (