瀏覽代碼

replace all hard coded strings with references to Localizable.strings

cyberta 6 年之前
父節點
當前提交
a6ed5b26ab

+ 2 - 2
deltachat-ios/Controller/AccountSetup/PortSettingsController.swift

@@ -58,7 +58,7 @@ class PortSettingsController: UITableViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
 
-        resetButton = UIBarButtonItem(title: "Reset", style: .plain, target: self, action: #selector(resetButtonPressed))
+        resetButton = UIBarButtonItem(title: String.localized("reset"), style: .plain, target: self, action: #selector(resetButtonPressed))
         navigationItem.rightBarButtonItem = resetButton
         resetButton.isEnabled = false
     }
@@ -111,7 +111,7 @@ class PortSettingsController: UITableViewController {
         if section == 0 {
             return sectionTitle
         } else {
-            return "Custom Port"
+            return String.localized("custom_port")
         }
     }
 

+ 2 - 1
deltachat-ios/Controller/AccountSetup/SecuritySettingsController.swift

@@ -38,7 +38,7 @@ class SecuritySettingsController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        resetButton = UIBarButtonItem(title: "Reset", style: .done, target: self, action: #selector(resetButtonPressed))
+        resetButton = UIBarButtonItem(title: String.localized("reset"), style: .done, target: self, action: #selector(resetButtonPressed))
         resetButton.isEnabled = false
         navigationItem.rightBarButtonItem = resetButton
     }
@@ -130,6 +130,7 @@ class SecurityConverter {
         }
     }
 
+	// TODO: discuss if we want to internationalize OFF and Automatic
     static func convertHexToString(type: SecurityType, hex value: Int) -> String {
         switch type {
         case .IMAPSecurity:

+ 27 - 26
deltachat-ios/Controller/AccountSetupController.swift

@@ -26,7 +26,7 @@ class AccountSetupController: UITableViewController {
     }()
 
     lazy var configProgressAlert: UIAlertController = {
-        let alert = UIAlertController(title: "Configuring Account", message: "\n\n\n", preferredStyle: .alert)
+        let alert = UIAlertController(title: String.localized("configuring_account"), message: "\n\n\n", preferredStyle: .alert)
         // temp workaround: add 3 newlines to let alertbox grow to fit progressview
         let progressView = configProgressIndicator
         progressView.translatesAutoresizingMaskIntoConstraints = false
@@ -35,7 +35,7 @@ class AccountSetupController: UITableViewController {
         progressView.centerYAnchor.constraint(equalTo: alert.view.centerYAnchor, constant: 0).isActive = true
         progressView.heightAnchor.constraint(equalToConstant: 65).isActive = true
         progressView.widthAnchor.constraint(equalToConstant: 65).isActive = true
-        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: loginCancelled(_:)))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: loginCancelled(_:)))
         return alert
     }()
 
@@ -58,20 +58,20 @@ class AccountSetupController: UITableViewController {
 
     private lazy var restoreCell: ActionCell = {
         let cell = ActionCell(frame: .zero)
-        cell.actionTitle = "Restore from backup"
+		cell.actionTitle = String.localized("import_backup_title");
         cell.accessibilityIdentifier = "restoreCell"
         return cell
     }()
 
     lazy var imapServerCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "IMAP Server", placeholder: DCConfig.mailServer ?? DCConfig.configuredMailServer, delegate: self)
+        let cell = TextFieldCell(descriptionID: "login_imap_server", placeholder: DCConfig.mailServer ?? DCConfig.configuredMailServer, delegate: self)
         cell.accessibilityIdentifier = "IMAPServerCell"
         cell.textField.tag = 2
         return cell
     }()
 
     lazy var imapUserCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "IMAP User", placeholder: DCConfig.mailUser ?? DCConfig.configuredMailUser, delegate: self)
+        let cell = TextFieldCell(descriptionID: "login_imap_login", placeholder: DCConfig.mailUser ?? DCConfig.configuredMailUser, delegate: self)
         cell.accessibilityIdentifier = "IMAPUserCell"
         cell.textField.tag = 3
         return cell
@@ -79,7 +79,7 @@ class AccountSetupController: UITableViewController {
 
     lazy var imapPortCell: UITableViewCell = {
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
-        cell.textLabel?.text = "IMAP Port"
+        cell.textLabel?.text = String.localized("login_imap_port")
         cell.accessoryType = .disclosureIndicator
         cell.detailTextLabel?.text = DCConfig.mailPort ?? DCConfig.configuredMailPort
         cell.accessibilityIdentifier = "IMAPPortCell"
@@ -90,7 +90,7 @@ class AccountSetupController: UITableViewController {
     lazy var imapSecurityCell: UITableViewCell = {
         let text = "\(DCConfig.getImapSecurity())"
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
-        cell.textLabel?.text = "IMAP Security"
+        cell.textLabel?.text = String.localized("login_imap_security")
         // let cell = TextFieldCell(description: "IMAP Security", placeholder: text, delegate: self)
         cell.accessibilityIdentifier = "IMAPSecurityCell"
         cell.accessoryType = .disclosureIndicator
@@ -100,14 +100,14 @@ class AccountSetupController: UITableViewController {
     }()
 
     lazy var smtpServerCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "SMTP Server", placeholder: DCConfig.sendServer ?? DCConfig.configuredSendServer, delegate: self)
+        let cell = TextFieldCell(descriptionID: "login_smtp_server", placeholder: DCConfig.sendServer ?? DCConfig.configuredSendServer, delegate: self)
         cell.accessibilityIdentifier = "SMTPServerCell"
         cell.textField.tag = 4
         return cell
     }()
 
     lazy var smtpUserCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "SMTP User", placeholder: DCConfig.sendUser ?? DCConfig.configuredSendUser, delegate: self)
+        let cell = TextFieldCell(descriptionID: "login_smtp_login", placeholder: DCConfig.sendUser ?? DCConfig.configuredSendUser, delegate: self)
         cell.accessibilityIdentifier = "SMTPUserCell"
         cell.textField.tag = 5
         return cell
@@ -115,7 +115,7 @@ class AccountSetupController: UITableViewController {
 
     lazy var smtpPortCell: UITableViewCell = {
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
-        cell.textLabel?.text = "SMTP Port"
+        cell.textLabel?.text = String.localized("login_smtp_port")
         cell.accessoryType = .disclosureIndicator
         cell.detailTextLabel?.text = DCConfig.sendPort ?? DCConfig.configuredSendPort
         cell.accessibilityIdentifier = "SMTPPortCell"
@@ -124,7 +124,7 @@ class AccountSetupController: UITableViewController {
     }()
 
     lazy var smtpPasswordCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "SMTP Password", placeholder: "*************", delegate: self)
+        let cell = TextFieldCell(descriptionID: "login_smtp_password", placeholder: "*************", delegate: self)
 		cell.textField.textContentType = UITextContentType.password
 		cell.textField.isSecureTextEntry = true
         cell.accessibilityIdentifier = "SMTPPasswordCell"
@@ -135,7 +135,7 @@ class AccountSetupController: UITableViewController {
     lazy var smtpSecurityCell: UITableViewCell = {
         let security = "\(DCConfig.getSmtpSecurity())"
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
-        cell.textLabel?.text = "SMTP Security"
+        cell.textLabel?.text = String.localized("login_smtp_security")
         cell.detailTextLabel?.text = security
         cell.accessibilityIdentifier = "SMTPSecurityCell"
         cell.accessoryType = .disclosureIndicator
@@ -145,7 +145,7 @@ class AccountSetupController: UITableViewController {
 
     // this loginButton can be enabled and disabled
     private lazy var loginButton: UIBarButtonItem = {
-        let button = UIBarButtonItem(title: "Login", style: .done, target: self, action: #selector(loginButtonPressed))
+        let button = UIBarButtonItem(title: String.localized("login_title"), style: .done, target: self, action: #selector(loginButtonPressed))
         button.isEnabled = dc_is_configured(mailboxPointer) == 0
         return button
     }()
@@ -177,7 +177,7 @@ class AccountSetupController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "Login to your server"
+        title = String.localized("login_header")
         // navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(closeButtonPressed))
         navigationItem.rightBarButtonItem = loginButton
     }
@@ -235,7 +235,7 @@ class AccountSetupController: UITableViewController {
 
     override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
         if section == 2 {
-            return "Advanced"
+            return String.localized("menu_advanced")
         } else {
             return nil
         }
@@ -260,10 +260,10 @@ class AccountSetupController: UITableViewController {
 
     override func tableView(_: UITableView, titleForFooterInSection section: Int) -> String? {
         if section == 0 {
-            return "There are no Delta Chat servers, your data stays on your device!"
+            return String.localized("login_no_servers_hint")
         } else if section == 2 {
             if advancedSectionShowing {
-                return "For known email providers additional settings are setup automatically. Sometimes IMAP needs to be enabled in the web frontend. Consult your email provider or friends for help"
+                return String.localized("login_subheader")
             } else {
                 return nil
             }
@@ -287,6 +287,7 @@ class AccountSetupController: UITableViewController {
         }
     }
 
+	// FIXME: replace if-else-if with switch-case
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         guard let tappedCell = tableView.cellForRow(at: indexPath) else { return }
         // handle tap on password -> show oAuthDialogue
@@ -322,7 +323,7 @@ class AccountSetupController: UITableViewController {
         // set flag before delete/insert operation, because cellForRowAt will be triggered and uses this flag
         advancedSectionShowing = willShow
 
-        button.text = willShow ? "Hide" : "Show"
+		button.text = String.localized(willShow ? "hide" : "pref_notifications_show")
 
         if willShow {
             tableView.insertRows(at: advancedIndexPaths, with: .fade)
@@ -516,8 +517,8 @@ class AccountSetupController: UITableViewController {
                 return
             }
 
-            let alert = UIAlertController(title: "Can not restore", message: "No Backup found", preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
+            let alert = UIAlertController(title: String.localized("import_backup_title"), message: String.localizedStringWithFormat(String.localized("import_backup_no_backup_found"), "DUMMYPATH TBD"), preferredStyle: .alert)
+            alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel, handler: { _ in
 
             }))
             present(alert, animated: true, completion: nil)
@@ -585,7 +586,7 @@ class AdvancedSectionHeader: UIView {
 
     private var label: UILabel = {
         let label = UILabel()
-        label.text = "ADVANCED"
+        label.text = String.localized("menu_advanced").uppercased()
         label.font = UIFont.systemFont(ofSize: 15)
         label.textColor = UIColor.darkGray
         return label
@@ -596,7 +597,7 @@ class AdvancedSectionHeader: UIView {
      */
     private lazy var toggleButton: UILabel = {
         let label = UILabel()
-        label.text = "Show"
+        label.text = String.localized("pref_notifications_show")
         label.font = UIFont.systemFont(ofSize: 15, weight: .medium)
         label.textColor = UIColor.systemBlue
         return label
@@ -637,7 +638,7 @@ extension AccountSetupController {
 
     func showProgressHud() {
         configProgressAlert.actions[0].isEnabled = true
-        configProgressAlert.title = "Configuring Account"
+        configProgressAlert.title = String.localized("configuring_account")
         configProgressAlert.message = "\n\n\n"	// workaround to create space for progress indicator
         configProgressIndicator.alpha = 1
         configProgressIndicator.value = 0
@@ -646,7 +647,7 @@ extension AccountSetupController {
     }
 
     func updateProgressHud(error message: String?) {
-        configProgressAlert.title = "Unable to Login!"
+        configProgressAlert.title = String.localized("login_error_title")
         configProgressAlert.message = message
         configProgressIndicator.alpha = 0
     }
@@ -654,8 +655,8 @@ extension AccountSetupController {
     func updateProgressHudSuccess(callback: (()->())?) {
         configProgressAlert.actions[0].isEnabled = false
         configProgressIndicator.alpha = 0
-        configProgressAlert.title = "Login Successful!"
-        configProgressAlert.message = "You are ready to use Delta Chat."
+		configProgressAlert.title = String.localized("login_successful_title")
+        configProgressAlert.message = String.localized("login_successful_message")
         loginButton.isEnabled = dc_is_configured(mailboxPointer) == 0
         DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
             self.configProgressAlert.dismiss(animated: true) {

+ 5 - 5
deltachat-ios/Controller/ChatListController.swift

@@ -74,7 +74,7 @@ class ChatListController: UIViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "Chats"
+        title = String.localized("pref_chats")
         navigationController?.navigationBar.prefersLargeTitles = true
 
         newButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.compose, target: self, action: #selector(didPressNewChat))
@@ -171,7 +171,7 @@ extension ChatListController: UITableViewDataSource, UITableViewDelegate {
         }
 
         // assigning swipe by delete to chats
-        let delete = UITableViewRowAction(style: .destructive, title: "Delete") { [unowned self] _, indexPath in
+        let delete = UITableViewRowAction(style: .destructive, title: String.localized("global_menu_edit_delete_desktop")) { [unowned self] _, indexPath in
             let chatId = chatList.getChatId(index: row)
 			self.showDeleteChatConfirmationAlert(chatId: chatId)
         }
@@ -183,14 +183,14 @@ extension ChatListController: UITableViewDataSource, UITableViewDelegate {
 extension ChatListController {
 	private func showDeleteChatConfirmationAlert(chatId: Int) {
 		let alert = UIAlertController(
-			title: "Do you want to delete the chat?",
+			title: String.localized("ask_delete_chat_desktop"),
 			message: nil,
 			preferredStyle: .alert
 		)
-		alert.addAction(UIAlertAction(title: "Delete", style: .default, handler: { action in
+		alert.addAction(UIAlertAction(title: String.localized("global_menu_edit_delete_desktop"), style: .default, handler: { action in
 			self.deleteChat(chatId: chatId)
 		}))
-		alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
+		alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
 		self.present(alert, animated: true, completion: nil)
 	}
 	

+ 8 - 8
deltachat-ios/Controller/ChatViewController.swift

@@ -249,14 +249,14 @@ class ChatViewController: MessagesViewController {
 
         if disableWriting {
             menuItems = [
-                UIMenuItem(title: "Start Chat", action: #selector(MessageCollectionViewCell.messageStartChat(_:))),
-                UIMenuItem(title: "Dismiss", action: #selector(MessageCollectionViewCell.messageDismiss(_:))),
-                UIMenuItem(title: "Block", action: #selector(MessageCollectionViewCell.messageBlock(_:))),
+				UIMenuItem(title: String.localized("start_chat"), action: #selector(MessageCollectionViewCell.messageStartChat(_:))),
+                UIMenuItem(title: String.localized("dismiss"), action: #selector(MessageCollectionViewCell.messageDismiss(_:))),
+                UIMenuItem(title: String.localized("menu_block_contact"), action: #selector(MessageCollectionViewCell.messageBlock(_:))),
             ]
         } else {
             // Configures the UIMenu which is shown when selecting a message
             menuItems = [
-                UIMenuItem(title: "Info", action: #selector(MessageCollectionViewCell.messageInfo(_:))),
+                UIMenuItem(title: String.localized("info"), action: #selector(MessageCollectionViewCell.messageInfo(_:))),
             ]
         }
 
@@ -298,7 +298,7 @@ class ChatViewController: MessagesViewController {
     private func configureMessageInputBar() {
         messageInputBar.delegate = self
         messageInputBar.inputTextView.tintColor = DCColors.primary
-        messageInputBar.inputTextView.placeholder = "Message"
+        messageInputBar.inputTextView.placeholder = String.localized("chat_input_placeholder")
         messageInputBar.isTranslucent = true
         messageInputBar.separatorLine.isHidden = true
         messageInputBar.inputTextView.tintColor = DCColors.primary
@@ -757,12 +757,12 @@ extension ChatViewController: MessagesLayoutDelegate {
 
     private func showClipperOptions() {
         let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
-        let photoAction = PhotoPickerAlertAction(title: "Photo", style: .default, handler: photoButtonPressed(_:))
-        let videoAction = PhotoPickerAlertAction(title: "Video", style: .default, handler: videoButtonPressed(_:))
+        let photoAction = PhotoPickerAlertAction(title: String.localized("photo"), style: .default, handler: photoButtonPressed(_:))
+        let videoAction = PhotoPickerAlertAction(title: String.localized("video"), style: .default, handler: videoButtonPressed(_:))
 
         alert.addAction(photoAction)
         alert.addAction(videoAction)
-        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
         self.present(alert, animated: true, completion: nil)
     }
 

+ 7 - 7
deltachat-ios/Controller/ContactDetailViewController.swift

@@ -19,7 +19,7 @@ class ContactDetailViewController: UITableViewController {
 
     private var notificationsCell: UITableViewCell = {
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
-        cell.textLabel?.text = "Notifications"
+        cell.textLabel?.text = String.localized("pref_notifications")
         cell.accessibilityIdentifier = CellIdentifiers.notification.rawValue
         cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
         cell.selectionStyle = .none
@@ -31,7 +31,7 @@ class ContactDetailViewController: UITableViewController {
         let cell = ActionCell()
         cell.accessibilityIdentifier = CellIdentifiers.chat.rawValue
         cell.actionColor = SystemColor.blue.uiColor
-        cell.actionTitle = "Chat with \(contact.name)"
+        cell.actionTitle = String.localizedStringWithFormat(String.localized("ask_start_chat_with"), contact.name)
         cell.selectionStyle = .none
         return cell
     }()
@@ -39,7 +39,7 @@ class ContactDetailViewController: UITableViewController {
     private lazy var blockContactCell: ActionCell = {
         let cell = ActionCell()
         cell.accessibilityIdentifier = CellIdentifiers.block.rawValue
-        cell.actionTitle = contact.isBlocked ? "Unblock Contact" : "Block Contact"
+        cell.actionTitle = contact.isBlocked ? String.localized("menu_unblock_contact") : String.localized("menu_block_contact")
         cell.actionColor = contact.isBlocked ? SystemColor.blue.uiColor : UIColor.red
         cell.selectionStyle = .none
         return cell
@@ -56,8 +56,8 @@ class ContactDetailViewController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editButtonPressed))
-        self.title = "Contact Info"
+        navigationItem.rightBarButtonItem = UIBarButtonItem(title: String.localized("global_menu_edit_desktop"), style: .plain, target: self, action: #selector(editButtonPressed))
+        self.title = String.localized("contact_detail_title_desktop")
     }
 
     override func viewWillAppear(_ animated: Bool) {
@@ -132,13 +132,13 @@ class ContactDetailViewController: UITableViewController {
     }
 
     private func updateBlockContactCell() {
-        blockContactCell.actionTitle = contact.isBlocked ? "Unblock Contact" : "Block Contact"
+        blockContactCell.actionTitle = contact.isBlocked ? String.localized("menu_unblock_contact") : String.localized("menu_block_contact")
         blockContactCell.actionColor = contact.isBlocked ? SystemColor.blue.uiColor : UIColor.red
     }
 
     private func showNotificationSetup() {
         let notificationSetupAlert = UIAlertController(title: "Notifications Setup is not implemented yet", message: "But you get an idea where this is going", preferredStyle: .actionSheet)
-        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
+        let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil)
         notificationSetupAlert.addAction(cancelAction)
         present(notificationSetupAlert, animated: true, completion: nil)
     }

+ 6 - 6
deltachat-ios/Controller/ContactListController.swift

@@ -120,7 +120,7 @@ class ContactListController: UITableViewController {
             } else {
                 cell = ActionCell(style: .default, reuseIdentifier: "actionCell")
             }
-            cell.actionTitle = "Import Device Contacts"
+            cell.actionTitle = String.localized("import_contacts")
             return cell
         } else {
 
@@ -166,7 +166,7 @@ class ContactListController: UITableViewController {
         let contactId = contactByIndexPath(indexPath).contact.id
 
         // assigning swipe by delete to chats
-        let edit = UITableViewRowAction(style: .default, title: "Edit") {
+        let edit = UITableViewRowAction(style: .default, title: String.localized("global_menu_edit_desktop")) {
             [unowned self] _, indexPath in
             if self.searchController.isActive {
                 self.searchController.dismiss(animated: false) {
@@ -224,14 +224,14 @@ extension ContactListController: ContactListDelegate {
 
     private func showSettingsAlert() {
         let alert = UIAlertController(
-            title: "Import Contacts from to your device",
-            message: "To chat with contacts from your device open the settings menu and enable the Contacts option",
+            title: String.localized("import_contacts"),
+            message: String.localized("import_contacts_message"),
             preferredStyle: .alert
         )
-        alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { _ in
+        alert.addAction(UIAlertAction(title: String.localized("open_settings"), style: .default) { _ in
             UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
         })
-        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel) { _ in
         })
         present(alert, animated: true)
     }

+ 1 - 1
deltachat-ios/Controller/EditContactController.swift

@@ -7,7 +7,7 @@ class EditContactController: NewContactController {
     // the email field)
     init(contactIdForUpdate: Int) {
         super.init()
-        title = "Edit Contact"
+        title = String.localized("edit_contact")
 
         let contact = DCContact(id: contactIdForUpdate)
         nameCell.textField.text = contact.name

+ 2 - 2
deltachat-ios/Controller/EditSettingsController.swift

@@ -6,13 +6,13 @@ class EditSettingsController: UITableViewController {
     private var statusCellBackup: String?
 
     private lazy var displayNameCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "Display Name", placeholder: "Display Name")
+        let cell = TextFieldCell(description: String.localized("display_name"), placeholder: String.localized("display_name"))
         cell.setText(text: DCConfig.displayname ?? nil)
         return cell
     }()
 
     private lazy var statusCell: TextFieldCell = {
-        let cell = TextFieldCell(description: "Status", placeholder: "Your Status")
+        let cell = TextFieldCell(description: String.localized("status"), placeholder: String.localized("your_status"))
         cell.setText(text: DCConfig.selfstatus ?? nil)
         return cell
     }()

+ 8 - 8
deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -41,13 +41,13 @@ class GroupChatDetailViewController: UIViewController {
 
     private func showNotificationSetup() {
         let notificationSetupAlert = UIAlertController(title: "Notifications Setup is not implemented yet", message: "But you get an idea where this is going", preferredStyle: .actionSheet)
-        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
+        let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil)
         notificationSetupAlert.addAction(cancelAction)
         present(notificationSetupAlert, animated: true, completion: nil)
     }
 
     private lazy var editBarButtonItem: UIBarButtonItem = {
-        UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editButtonPressed))
+        UIBarButtonItem(title: String.localized("global_menu_edit_desktop"), style: .plain, target: self, action: #selector(editButtonPressed))
     }()
 
     private var groupMembers: [DCContact] = []
@@ -56,7 +56,7 @@ class GroupChatDetailViewController: UIViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "Group Info"
+        title = String.localized("group_info")
         chatDetailTable.delegate = self
         chatDetailTable.dataSource = self
         navigationItem.rightBarButtonItem = editBarButtonItem
@@ -91,7 +91,7 @@ class GroupChatDetailViewController: UIViewController {
 extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSource {
     func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
         if section == 1 {
-            return "Members:"
+            return String.localized("tab_members")
         }
         return nil
     }
@@ -143,13 +143,13 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 
         if section == 0 {
             let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
-            cell.textLabel?.text = "Notifications"
+            cell.textLabel?.text = String.localized("pref_notifications")
             cell.selectionStyle = .none
             return cell
         } else if section == 1 {
             if row == 0 {
                 let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as! ActionCell
-                cell.actionTitle = "Add Members"
+                cell.actionTitle = String.localized("group_add_members")
                 return cell
             } else {
                 let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactCell
@@ -162,7 +162,7 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
             }
         } else if section == 2 {
             let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as! ActionCell
-            cell.actionTitle = "Leave Group"
+            cell.actionTitle = String.localized("menu_leave_group")
             cell.actionColor = UIColor.red
             return cell
         }
@@ -203,7 +203,7 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 
         // assigning swipe by delete to members (except for current user)
         if section == 1, row >= staticCellCountMemberSection, groupMembers[row - staticCellCountMemberSection].id != currentUser?.id {
-            let delete = UITableViewRowAction(style: .destructive, title: "Delete") { [unowned self] _, indexPath in
+            let delete = UITableViewRowAction(style: .destructive, title: String.localized("global_menu_edit_delete_desktop")) { [unowned self] _, indexPath in
 
                 let memberId = self.groupMembers[row - self.staticCellCountMemberSection].id
                 let success = dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(memberId))

+ 4 - 4
deltachat-ios/Controller/GroupMembersViewController.swift

@@ -5,9 +5,9 @@ class NewGroupViewController: GroupMembersViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "New Group"
+        title = String.localized("menu_new_group")
         navigationController?.navigationBar.prefersLargeTitles = false
-        let groupCreationNextButton = UIBarButtonItem(title: "Next", style: .done, target: self, action: #selector(nextButtonPressed))
+        let groupCreationNextButton = UIBarButtonItem(title: String.localized("next"), style: .done, target: self, action: #selector(nextButtonPressed))
         navigationItem.rightBarButtonItem = groupCreationNextButton
         contactIds = Utils.getContactIds()
     }
@@ -25,7 +25,7 @@ class AddGroupMembersViewController: GroupMembersViewController {
     private var chatId: Int?
 
     private lazy var resetButton: UIBarButtonItem = {
-        let button = UIBarButtonItem(title: "Reset", style: .plain, target: self, action: #selector(resetButtonPressed))
+        let button = UIBarButtonItem(title: String.localized("reset"), style: .plain, target: self, action: #selector(resetButtonPressed))
         button.isEnabled = false
         return button
     }()
@@ -71,7 +71,7 @@ class AddGroupMembersViewController: GroupMembersViewController {
         super.viewDidLoad()
         super.contactIds = memberCandidateIds
         super.navigationItem.rightBarButtonItem = resetButton
-        title = "Add Group Members"
+        title = String.localized("group_add_members")
         // Do any additional setup after loading the view.
     }
 

+ 2 - 2
deltachat-ios/Controller/GroupNameController.swift

@@ -21,7 +21,7 @@ class GroupNameController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "New Group"
+        title = String.localized("menu_new_group")
         doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonPressed))
         navigationItem.rightBarButtonItem = doneButton
         tableView.bounces = false
@@ -88,7 +88,7 @@ class GroupNameController: UITableViewController {
 
     override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
         if section == 1 {
-            return "Group Members"
+            return String.localized("in_this_group_desktop")
         } else {
             return nil
         }

+ 1 - 1
deltachat-ios/Controller/MessageInfoViewController.swift

@@ -15,7 +15,7 @@ class MessageInfoViewController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "Message Info"
+        title = String.localized("menu_message_details")
         // Uncomment the following line to preserve selection between presentations
         // self.clearsSelectionOnViewWillAppear = false
 

+ 17 - 17
deltachat-ios/Controller/NewChatViewController.swift

@@ -9,7 +9,7 @@ class NewChatViewController: UITableViewController {
         let searchController = UISearchController(searchResultsController: nil)
         searchController.searchResultsUpdater = self
         searchController.obscuresBackgroundDuringPresentation = false
-        searchController.searchBar.placeholder = "Search Contact"
+        searchController.searchBar.placeholder = String.localized("search_contact")
         return searchController
     }()
 
@@ -61,7 +61,7 @@ class NewChatViewController: UITableViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
 
-        title = "New Chat"
+        title = String.localized("menu_new_chat")
 
         deviceContactHandler.importDeviceContacts()
         navigationItem.searchController = searchController
@@ -104,7 +104,7 @@ class NewChatViewController: UITableViewController {
     }
 
     override func viewWillDisappear(_: Bool) {
-        title = "Chats" /* hack: when navigating to chatView (removing this viewController), there was a delayed backButton update (showing 'New Chat' for a moment) */
+        title = String.localized("pref_chats") /* hack: when navigating to chatView (removing this viewController), there was a delayed backButton update (showing 'New Chat' for a moment) */
     }
 
     override func viewDidDisappear(_ animated: Bool) {
@@ -158,7 +158,7 @@ class NewChatViewController: UITableViewController {
                 } else {
                     cell = UITableViewCell(style: .default, reuseIdentifier: "newContactCell")
                 }
-                cell.textLabel?.text = "New Group"
+                cell.textLabel?.text = String.localized("menu_new_group")
                 cell.textLabel?.textColor = view.tintColor
 
                 return cell
@@ -171,7 +171,7 @@ class NewChatViewController: UITableViewController {
                 } else {
                     cell = UITableViewCell(style: .default, reuseIdentifier: "scanGroupCell")
                 }
-                cell.textLabel?.text = "Scan Group QR Code"
+                cell.textLabel?.text = String.localized("qrscan_title")
                 cell.textLabel?.textColor = view.tintColor
 
                 return cell
@@ -185,7 +185,7 @@ class NewChatViewController: UITableViewController {
                 } else {
                     cell = UITableViewCell(style: .default, reuseIdentifier: "newContactCell")
                 }
-                cell.textLabel?.text = "New Contact"
+                cell.textLabel?.text = String.localized("menu_new_contact")
                 cell.textLabel?.textColor = view.tintColor
 
                 return cell
@@ -208,7 +208,7 @@ class NewChatViewController: UITableViewController {
                 } else {
                     cell = ActionCell(style: .default, reuseIdentifier: "actionCell")
                 }
-                cell.actionTitle = "Import Device Contacts"
+                cell.actionTitle = String.localized("import_contacts")
                 return cell
             }
         } else {
@@ -240,8 +240,8 @@ class NewChatViewController: UITableViewController {
                 if UIImagePickerController.isSourceTypeAvailable(.camera) {
                     coordinator?.showQRCodeController()
                 } else {
-                    let alert = UIAlertController(title: "Camera is not available", message: nil, preferredStyle: .alert)
-                    alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
+                    let alert = UIAlertController(title: String.localized("chat_camera_unavailable"), message: nil, preferredStyle: .alert)
+                    alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel, handler: { _ in
                         self.dismiss(animated: true, completion: nil)
                     }))
                     present(alert, animated: true, completion: nil)
@@ -295,7 +295,7 @@ class NewChatViewController: UITableViewController {
         return searchController.searchBar.text?.isEmpty ?? true
     }
 
-    private func filterContentForSearchText(_ searchText: String, scope _: String = "All") {
+    private func filterContentForSearchText(_ searchText: String, scope _: String = String.localized("pref_show_emails_all")) {
         let contactsWithHighlights: [ContactWithSearchResults] = contacts.map { contact in
             let indexes = contact.contact.contains(searchText: searchText)
             return ContactWithSearchResults(contact: contact.contact, indexesToHighlight: indexes)
@@ -314,7 +314,7 @@ extension NewChatViewController: QrCodeReaderDelegate {
         logger.info("got ver: \(check)")
 
         if dc_lot_get_state(check) == DC_QR_ASK_VERIFYGROUP {
-            hud = ProgressHud("Synchronizing Account", in: view)
+            hud = ProgressHud(String.localized("synchronizing_account"), in: view)
             DispatchQueue.global(qos: .userInitiated).async {
                 let id = dc_join_securejoin(mailboxPointer, code)
 
@@ -326,8 +326,8 @@ extension NewChatViewController: QrCodeReaderDelegate {
                 }
             }
         } else {
-            let alert = UIAlertController(title: "Not a valid group QR Code", message: code, preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
+            let alert = UIAlertController(title: String.localized("invalid_qr_code"), message: code, preferredStyle: .alert)
+            alert.addAction(UIAlertAction(title: String.localized("OK"), style: .cancel, handler: { _ in
                 self.dismiss(animated: true, completion: nil)
             }))
             present(alert, animated: true, completion: nil)
@@ -352,14 +352,14 @@ extension NewChatViewController: ContactListDelegate {
 
     private func showSettingsAlert() {
         let alert = UIAlertController(
-            title: "Import Contacts from to your device",
-            message: "To chat with contacts from your device open the settings menu and enable the Contacts option",
+            title: String.localized("import_contacts"),
+            message: String.localized("import_contacts_message"),
             preferredStyle: .alert
         )
-        alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { _ in
+        alert.addAction(UIAlertAction(title: String.localized("open_settings"), style: .default) { _ in
             UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
         })
-        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel) { _ in
         })
         present(alert, animated: true)
     }

+ 1 - 1
deltachat-ios/Controller/NewContactController.swift

@@ -38,7 +38,7 @@ class NewContactController: UITableViewController {
         emailCell.textField.returnKeyType = .next
         nameCell.textField.returnKeyType = .done
 
-        title = "New Contact"
+        title = String.localized("menu_new_contact")
         doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(saveContactButtonPressed))
         doneButton?.isEnabled = false
         navigationItem.rightBarButtonItem = doneButton

+ 5 - 3
deltachat-ios/Controller/ProfileViewController.swift

@@ -33,7 +33,7 @@ class ProfileViewController: UITableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "My Profile"
+        title = String.localized("my_profile")
     }
 
     override func viewWillAppear(_: Bool) {
@@ -75,7 +75,9 @@ class ProfileViewController: UITableViewController {
         if indexPath.section == 0 {
             if row == 0 {
                 if let fingerprint = self.fingerprint {
-                    cell.textLabel?.text = "Fingerprint: \(fingerprint)"
+					//FIXME: this formatting is not correct for r-t-l languages
+					//keeping it simple for now as it is not clear if we will show the FP this way
+                    cell.textLabel?.text = String.localized("qrscan_fingerprint_label") + ": \(fingerprint)"
                     cell.textLabel?.textAlignment = .center
                 }
             }
@@ -145,7 +147,7 @@ class ProfileViewController: UITableViewController {
                 }
                 contactCell.setVerified(isVerified: contact.isVerified)
             } else {
-                contactCell.nameLabel.text = "No Account set up"
+                contactCell.nameLabel.text = String.localized("no_account_setup")
             }
             return contactCell
         }

+ 28 - 24
deltachat-ios/Controller/SettingsController.swift

@@ -25,7 +25,7 @@ internal final class SettingsViewController: QuickTableViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        title = "Settings"
+        title = String.localized("menu_settings")
         documentInteractionController.delegate = self as? UIDocumentInteractionControllerDelegate
     }
 
@@ -94,39 +94,44 @@ internal final class SettingsViewController: QuickTableViewController {
 
     private func setTable() {
         var backupRows = [
-            TapActionRow(text: "Create backup", action: { [weak self] in self?.createBackup($0) }),
+            TapActionRow(text: String.localized("create_backup"), action: { [weak self] in self?.createBackup($0) }),
         ]
 
-        let deleteRow = TapActionRow(text: "Delete Account", action: { [weak self] in self?.deleteAccount($0) })
+        let deleteRow = TapActionRow(text: String.localized("delete_account"), action: { [weak self] in self?.deleteAccount($0) })
 
         tableContents = [
             Section(
-                title: "User Details",
+                title: String.localized("user_details"),
                 rows: [
-                    NavigationRow(text: "Display Name", detailText: .value1(DCConfig.displayname ?? ""), action: { [weak self] in self?.editNameAndStatus($0)}),
-                    NavigationRow(text: "Status", detailText: .value1(DCConfig.selfstatus ?? ""), action: { [weak self] in self?.editNameAndStatus($0)}),
-                    TapActionRow(text: "Configure my Account", action: { [weak self] in self?.presentAccountSetup($0) }),
+					//FIXME: fix action callback!
+                    NavigationRow(text: String.localized("display_name"), detailText: .value1(DCConfig.displayname ?? ""), action: {
+						[weak self] in self?.editNameAndStatus($0, option: SettingsEditOption.DISPLAYNAME)
+					}),
+					NavigationRow(text: String.localized("status"), detailText: .value1(DCConfig.selfstatus ?? ""), action: {
+						[weak self] in self?.editNameAndStatus($0, option: SettingsEditOption.STATUS)
+					}),
+                    TapActionRow(text: String.localized("configure_my_account"), action: { [weak self] in self?.presentAccountSetup($0) }),
                 ]
             ),
             Section(
-                title: "Flags",
+                title: String.localized("flags"),
                 rows: [
-                    SwitchRow(text: "E2EE enabled", switchValue: DCConfig.e2eeEnabled, action: editCell(key: SVC.e2eeEnabled)),
-                    SwitchRow(text: "Read Receipts", switchValue: DCConfig.mdnsEnabled, action: editCell(key: SVC.readReceipts)),
-                    SwitchRow(text: "Watch Inbox", switchValue: DCConfig.inboxWatch, action: editCell(key: SVC.watchMvBox)),
-                    SwitchRow(text: "Watch Sentbox", switchValue: DCConfig.sentboxWatch, action: editCell(key: SVC.watchSentbox)),
-                    SwitchRow(text: "Watch Mvbox", switchValue: DCConfig.mvboxWatch, action: editCell(key: SVC.watchMvBox)),
-                    SwitchRow(text: "Move to Mvbox", switchValue: DCConfig.mvboxMove, action: editCell(key: SVC.MvToMvbox)),
-                    SwitchRow(text: "Save Mime Headers", switchValue: DCConfig.saveMimeHeaders, action: editCell(key: SVC.SaveMimeHeaders))
+                    SwitchRow(text: String.localized("autocrypt_prefer_e2ee"), switchValue: DCConfig.e2eeEnabled, action: editCell(key: SVC.e2eeEnabled)),
+                    SwitchRow(text: String.localized("pref_read_receipts"), switchValue: DCConfig.mdnsEnabled, action: editCell(key: SVC.readReceipts)),
+                    SwitchRow(text: String.localized("pref_watch_inbox_folder"), switchValue: DCConfig.inboxWatch, action: editCell(key: SVC.watchMvBox)),
+                    SwitchRow(text: String.localized("pref_watch_sent_folder"), switchValue: DCConfig.sentboxWatch, action: editCell(key: SVC.watchSentbox)),
+                    SwitchRow(text: String.localized("pref_watch_mvbox_folder"), switchValue: DCConfig.mvboxWatch, action: editCell(key: SVC.watchMvBox)),
+                    SwitchRow(text: String.localized("pref_auto_folder_moves"), switchValue: DCConfig.mvboxMove, action: editCell(key: SVC.MvToMvbox)),
+                    SwitchRow(text: String.localized("save_mime_headers"), switchValue: DCConfig.saveMimeHeaders, action: editCell(key: SVC.SaveMimeHeaders))
                 ]
             ),
 
             Section(
-                title: "Backup",
+                title: String.localized("pref_backup"),
                 rows: backupRows
             ),
 
-            Section(title: "Danger", rows: [
+            Section(title: String.localized("danger"), rows: [
                 deleteRow,
             ]),
         ]
@@ -169,7 +174,7 @@ internal final class SettingsViewController: QuickTableViewController {
         let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
         if !documents.isEmpty {
             logger.info("create backup in \(documents)")
-            hudHandler.showBackupHud("Creating Backup")
+            hudHandler.showBackupHud(String.localized("creating_backup"))
             DispatchQueue.main.async {
                 dc_imex(mailboxPointer, DC_IMEX_EXPORT_BACKUP, documents[0], nil)
             }
@@ -179,7 +184,7 @@ internal final class SettingsViewController: QuickTableViewController {
     }
 
     private func configure(_: Row) {
-        hudHandler.showBackupHud("Configuring account")
+        hudHandler.showBackupHud(String.localized("configuring_account"))
         dc_configure(mailboxPointer)
     }
 
@@ -191,9 +196,9 @@ internal final class SettingsViewController: QuickTableViewController {
 
         let dbfile = appDelegate.dbfile()
         let dburl = URL(fileURLWithPath: dbfile, isDirectory: false)
-        let alert = UIAlertController(title: "Delete Account", message: "Are you sure you wante to delete your account data?", preferredStyle: .actionSheet)
+        let alert = UIAlertController(title: String.localized("delete_account"), message: String.localized("delete_account_message"), preferredStyle: .actionSheet)
 
-        alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { _ in
+        alert.addAction(UIAlertAction(title: String.localized("delete"), style: .destructive, handler: { _ in
             appDelegate.stop()
             appDelegate.close()
             do {
@@ -211,7 +216,7 @@ internal final class SettingsViewController: QuickTableViewController {
             self.dismiss(animated: false, completion: nil)
             self.coordinator?.showLoginController()
         }))
-        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
         present(alert, animated: true, completion: nil)
     }
 
@@ -219,8 +224,7 @@ internal final class SettingsViewController: QuickTableViewController {
         coordinator?.showAccountSetupController()
     }
 
-    private func editNameAndStatus(_ row: Row) {
-        guard let option = SettingsEditOption(rawValue: row.text) else { return }
+	private func editNameAndStatus(_ row: Row, option: SettingsEditOption) {
         coordinator?.showEditSettingsController(option: option)
     }
 }

+ 13 - 13
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -27,7 +27,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = ContactListController()
         let nav = DCNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "contacts")
-        nav.tabBarItem = UITabBarItem(title: "Contacts", image: settingsImage, tag: 0)
+        nav.tabBarItem = UITabBarItem(title: String.localized("contacts_title"), image: settingsImage, tag: 0)
         let coordinator = ContactListCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -35,11 +35,11 @@ class AppCoordinator: NSObject, Coordinator {
     }()
 
     private lazy var mailboxController: UIViewController = {
-        let controller = MailboxViewController(chatId: Int(DC_CHAT_ID_DEADDROP), title: "Mailbox")
+        let controller = MailboxViewController(chatId: Int(DC_CHAT_ID_DEADDROP), title: String.localized("mailbox"))
         controller.disableWriting = true
         let nav = DCNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "message")
-        nav.tabBarItem = UITabBarItem(title: "Mailbox", image: settingsImage, tag: 1)
+        nav.tabBarItem = UITabBarItem(title: String.localized("mailbox"), image: settingsImage, tag: 1)
         let coordinator = MailboxCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -50,7 +50,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = ProfileViewController()
         let nav = DCNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "report_card")
-        nav.tabBarItem = UITabBarItem(title: "My Profile", image: settingsImage, tag: 2)
+        nav.tabBarItem = UITabBarItem(title: String.localized("my_profile"), image: settingsImage, tag: 2)
         let coordinator = ProfileCoordinator(rootViewController: nav)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -61,7 +61,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = ChatListController()
         let nav = DCNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "chat")
-        nav.tabBarItem = UITabBarItem(title: "Chats", image: settingsImage, tag: 3)
+        nav.tabBarItem = UITabBarItem(title: String.localized("pref_chats"), image: settingsImage, tag: 3)
         let coordinator = ChatListCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -72,7 +72,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = SettingsViewController()
         let nav = DCNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "settings")
-        nav.tabBarItem = UITabBarItem(title: "Settings", image: settingsImage, tag: 4)
+        nav.tabBarItem = UITabBarItem(title: String.localized("menu_settings"), image: settingsImage, tag: 4)
         let coordinator = SettingsCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -251,7 +251,7 @@ class AccountSetupCoordinator: Coordinator {
     func showImapPortOptions() {
         let currentMailPort = DCConfig.mailPort ?? DCConfig.configuredMailPort
         let currentPort = Int(currentMailPort)
-        let portSettingsController = PortSettingsController(sectionTitle: "IMAP Port", ports: [143, 993], currentPort: currentPort)
+        let portSettingsController = PortSettingsController(sectionTitle: String.localized("login_imap_port"), ports: [143, 993], currentPort: currentPort)
         portSettingsController.onDismiss = {
             port in
             DCConfig.mailPort = port
@@ -262,7 +262,7 @@ class AccountSetupCoordinator: Coordinator {
     func showImapSecurityOptions() {
         let currentSecurityOption = DCConfig.getImapSecurity()
         let convertedOption = SecurityConverter.convertHexToString(type: .IMAPSecurity, hex: currentSecurityOption)
-        let securitySettingsController = SecuritySettingsController(title: "IMAP Security", options: ["Automatic", "SSL / TLS", "STARTTLS", "OFF"], selectedOption: convertedOption)
+        let securitySettingsController = SecuritySettingsController(title: String.localized("login_imap_security"), options: ["Automatic", "SSL / TLS", "STARTTLS", "OFF"], selectedOption: convertedOption)
         securitySettingsController.onDismiss = {
             option in
             if let secValue = SecurityValue(rawValue: option) {
@@ -276,7 +276,7 @@ class AccountSetupCoordinator: Coordinator {
     func showSmtpPortsOptions() {
         let currentMailPort = DCConfig.sendPort ?? DCConfig.configuredSendPort
         let currentPort = Int(currentMailPort)
-        let portSettingsController = PortSettingsController(sectionTitle: "SMTP Port", ports: [25, 465, 587], currentPort: currentPort)
+        let portSettingsController = PortSettingsController(sectionTitle: String.localized("login_smtp_port"), ports: [25, 465, 587], currentPort: currentPort)
         portSettingsController.onDismiss = {
             port in
             DCConfig.sendPort = port
@@ -287,7 +287,7 @@ class AccountSetupCoordinator: Coordinator {
     func showSmptpSecurityOptions() {
         let currentSecurityOption = DCConfig.getSmtpSecurity()
         let convertedOption = SecurityConverter.convertHexToString(type: .SMTPSecurity, hex: currentSecurityOption)
-        let securitySettingsController = SecuritySettingsController(title: "IMAP Security", options: ["Automatic", "SSL / TLS", "STARTTLS", "OFF"], selectedOption: convertedOption)
+        let securitySettingsController = SecuritySettingsController(title: String.localized("login_imap_security"), options: ["Automatic", "SSL / TLS", "STARTTLS", "OFF"], selectedOption: convertedOption)
         securitySettingsController.onDismiss = {
             option in
             if let secValue = SecurityValue(rawValue: option) {
@@ -467,8 +467,8 @@ class ChatViewCoordinator: NSObject, Coordinator {
 
             navigationController.present(cameraViewController, animated: true, completion: nil)
         } else {
-            let alert = UIAlertController(title: "Camera is not available", message: nil, preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
+            let alert = UIAlertController(title: String.localized("chat_camera_unavailable"), message: nil, preferredStyle: .alert)
+            alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel, handler: { _ in
                 self.navigationController.dismiss(animated: true, completion: nil)
             }))
             navigationController.present(alert, animated: true, completion: nil)
@@ -496,7 +496,7 @@ class ChatViewCoordinator: NSObject, Coordinator {
     private func presentVideoLibrary() {
         if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
             let videoPicker = UIImagePickerController()
-            videoPicker.title = "Videos"
+            videoPicker.title = String.localized("videos")
             videoPicker.delegate = self
             videoPicker.sourceType = .photoLibrary
             videoPicker.mediaTypes = [kUTTypeMovie as String, kUTTypeVideo as String]

+ 4 - 4
deltachat-ios/Handler/HudHandler.swift

@@ -12,7 +12,7 @@ class HudHandler {
     func setHudProgress(_ progress: Int) {
         if let hud = self.backupHud {
             hud.progress = Float(progress) / 1000.0
-            hud.detailTextLabel.text = "\(progress / 10)% Complete"
+            hud.detailTextLabel.text = "\(progress / 10)% \(String.localized("complete"))"
         }
     }
 
@@ -21,7 +21,7 @@ class HudHandler {
             let hud = JGProgressHUD(style: .dark)
             hud.vibrancyEnabled = true
             hud.indicatorView = JGProgressHUDPieIndicatorView()
-            hud.detailTextLabel.text = "0% Complete"
+            hud.detailTextLabel.text = "0% \(String.localized("complete"))"
             hud.textLabel.text = text
             hud.show(in: self.view)
             self.backupHud = hud
@@ -33,7 +33,7 @@ class HudHandler {
             DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
                 UIView.animate(
                     withDuration: 0.1, animations: {
-                        hud.textLabel.text = message ?? "Error"
+                        hud.textLabel.text = message ?? String.localized("error")
                         hud.detailTextLabel.text = nil
                         hud.indicatorView = JGProgressHUDErrorIndicatorView()
                     }
@@ -50,7 +50,7 @@ class HudHandler {
             DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
                 UIView.animate(
                     withDuration: 0.1, animations: {
-                        hud.textLabel.text = "Success"
+                        hud.textLabel.text = String.localized("success")
                         hud.detailTextLabel.text = nil
                         hud.indicatorView = JGProgressHUDSuccessIndicatorView()
                     }

+ 4 - 0
deltachat-ios/Helper/Extensions.swift

@@ -46,6 +46,10 @@ extension String {
         }
         return attributedText
     }
+
+	static func localized(_ stringID: String) -> String {
+		return NSLocalizedString(stringID, comment: "")
+	}
 }
 
 extension URL {

+ 3 - 2
deltachat-ios/Helper/Utils.swift

@@ -155,13 +155,14 @@ struct Utils {
 }
 
 class DateUtils {
-
+	// TODO: refactor that, it's an improper way for localizations, use stringsdict instead
+	// blocked by: converting androids plurals xml entries to stringsdict
     static func getBriefRelativeTimeSpanString(timeStamp: Int) -> String {
         let unixTime = Int(Date().timeIntervalSince1970)
         let seconds = unixTime - timeStamp
 
         if seconds < 60 {
-            return "Now"	// under one minute
+            return String.localized("now")	// under one minute
         } else if seconds < 3600 {
             let mins = seconds / 60
             let minTitle = mins > 1 ? "mins" : "min"

+ 1 - 1
deltachat-ios/View/GroupNameCell.swift

@@ -15,7 +15,7 @@ class GroupLabelCell: UITableViewCell {
 
     lazy var inputField: UITextField = {
         let textField = UITextField()
-        textField.placeholder = "Group Name"
+        textField.placeholder = String.localized("group_name")
         textField.borderStyle = .none
         textField.becomeFirstResponder()
         textField.autocorrectionType = .no

+ 5 - 5
deltachat-ios/View/ProgressHud.swift

@@ -7,7 +7,7 @@ class ProgressHud {
         DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
             UIView.animate(
                 withDuration: 0.1, animations: {
-                    self.hud.textLabel.text = message ?? "Error"
+                    self.hud.textLabel.text = message ?? String.localized("error")
                     self.hud.detailTextLabel.text = nil
                     self.hud.indicatorView = JGProgressHUDErrorIndicatorView()
                 }
@@ -23,7 +23,7 @@ class ProgressHud {
         DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
             UIView.animate(
                 withDuration: 0.1, animations: {
-                    self.hud.textLabel.text = message ?? "Success"
+                    self.hud.textLabel.text = message ?? String.localized("success")
                     self.hud.indicatorView = JGProgressHUDSuccessIndicatorView()
                 }
             )
@@ -34,15 +34,15 @@ class ProgressHud {
 
     func progress(_ progress: Int) {
         hud.progress = Float(progress) / 1000.0
-        hud.detailTextLabel.text = "\(progress / 10)% Complete"
-    }
+		hud.detailTextLabel.text = "\(progress / 10)% \(String.localized("complete"))"
+	}
 
     init(_ text: String, in view: UIView) {
         hud = JGProgressHUD(style: .dark)
         hud.vibrancyEnabled = true
         hud.indicatorView = JGProgressHUDPieIndicatorView()
 
-        hud.detailTextLabel.text = "0% Complete"
+        hud.detailTextLabel.text = "0% " + String.localized("complete")
         hud.textLabel.text = text
         hud.show(in: view)
     }

+ 9 - 5
deltachat-ios/View/TextFieldCell.swift

@@ -26,6 +26,10 @@ class TextFieldCell: UITableViewCell {
         setupViews()
         textField.delegate = delegate
     }
+	
+	convenience init(descriptionID: String, placeholder: String, delegate: UITextFieldDelegate? = nil) {
+		self.init(description: String.localized(descriptionID), placeholder: placeholder, delegate: delegate)
+	}
 
     required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
@@ -72,7 +76,7 @@ class TextFieldCell: UITableViewCell {
     }
 
     static func makeEmailCell(delegate: UITextFieldDelegate? = nil) -> TextFieldCell {
-        let cell = TextFieldCell(description: "Email", placeholder: "you@example.com")
+		let cell = TextFieldCell(description: String.localized("email_address"), placeholder: "you@example.com")
         cell.textField.keyboardType = .emailAddress
         // switch off quicktype
         cell.textField.autocorrectionType = .no
@@ -82,14 +86,14 @@ class TextFieldCell: UITableViewCell {
     }
 
     static func makePasswordCell(delegate _: UITextFieldDelegate? = nil) -> TextFieldCell {
-        let cell = TextFieldCell(description: "Password", placeholder: "your IMAP password")
+		let cell = TextFieldCell(description: String.localized("password"), placeholder: String.localized("imap_password"))
         cell.textField.textContentType = UITextContentType.password
         cell.textField.isSecureTextEntry = true
         return cell
     }
 
     static func makeNameCell(delegate: UITextFieldDelegate? = nil) -> TextFieldCell {
-        let cell = TextFieldCell(description: "Name", placeholder: "new contacts nickname")
+        let cell = TextFieldCell(description: String.localized("name_desktop"), placeholder: String.localized("contact_nickname"))
         cell.textField.autocapitalizationType = .words
         cell.textField.autocorrectionType = .no
         // .namePhonePad doesn't support autocapitalization
@@ -101,8 +105,8 @@ class TextFieldCell: UITableViewCell {
         return cell
     }
 
-    static func makeConfigCell(label: String, placeholder: String, delegate: UITextFieldDelegate? = nil) -> TextFieldCell {
-        let cell = TextFieldCell(description: label, placeholder: placeholder)
+    static func makeConfigCell(labelID: String, placeholderID: String, delegate: UITextFieldDelegate? = nil) -> TextFieldCell {
+		let cell = TextFieldCell(description: String.localized(labelID), placeholder: String.localized(placeholderID))
         cell.textField.autocapitalizationType = .words
         cell.textField.autocorrectionType = .no
         // .namePhonePad doesn't support autocapitalization