Skip to content
This repository has been archived by the owner on Oct 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #25 from unnamedd/enhancement/convert-localized-in…
Browse files Browse the repository at this point in the history
…to-enum

Implemented convertion from NSLocalizedString into structured enums
  • Loading branch information
florianbuerger authored Jul 14, 2017
2 parents aafb193 + f7e5f16 commit 8354201
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 82 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ excluded:
disabled_rules:
- line_length
- todo
- nesting

# limit whitespace only lines to 2
vertical_whitespace:
Expand Down
4 changes: 4 additions & 0 deletions Brisk iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
17FE32401F0823E700410D7A /* RadarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17FE323F1F0823E700410D7A /* RadarViewController.swift */; };
17FE32421F08242200410D7A /* RadarViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17FE32411F08242200410D7A /* RadarViewController.storyboard */; };
4F99F8269819ADC732093605 /* Pods_Brisk_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A915B61BA11353854A4BE2B5 /* Pods_Brisk_iOSTests.framework */; };
9152421B1F115C4D003AF58D /* Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9152421A1F115C4D003AF58D /* Localizable.swift */; };
917CF7C81F10A7D9003B6ED3 /* QuickAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 917CF7C71F10A7D9003B6ED3 /* QuickAction.swift */; };
EF10474BFAB5B59C56ACD32C /* Pods_Brisk_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C52D9F97E0E2AAFF61975C9 /* Pods_Brisk_iOS.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -109,6 +110,7 @@
17FE323F1F0823E700410D7A /* RadarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadarViewController.swift; sourceTree = "<group>"; };
17FE32411F08242200410D7A /* RadarViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = RadarViewController.storyboard; sourceTree = "<group>"; };
8F534FD145EF44018C445D92 /* Pods-Brisk iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Brisk iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Brisk iOS/Pods-Brisk iOS.debug.xcconfig"; sourceTree = "<group>"; };
9152421A1F115C4D003AF58D /* Localizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localizable.swift; sourceTree = "<group>"; };
917CF7C71F10A7D9003B6ED3 /* QuickAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuickAction.swift; sourceTree = "<group>"; };
93EBA6EB32449AB7DAF50130 /* Pods-Brisk iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Brisk iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Brisk iOSTests/Pods-Brisk iOSTests.release.xcconfig"; sourceTree = "<group>"; };
A915B61BA11353854A4BE2B5 /* Pods_Brisk_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Brisk_iOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -258,6 +260,7 @@
17FE32381F08223B00410D7A /* Dictionary+Validation.swift */,
17FE323A1F08228800410D7A /* OpenRadar.swift */,
17C1A7A11F085159004FD1EC /* Choice.swift */,
9152421A1F115C4D003AF58D /* Localizable.swift */,
917CF7C71F10A7D9003B6ED3 /* QuickAction.swift */,
);
path = Model;
Expand Down Expand Up @@ -546,6 +549,7 @@
17FE322C1F081E6700410D7A /* User.swift in Sources */,
17FE32401F0823E700410D7A /* RadarViewController.swift in Sources */,
17C1A79C1F084A12004FD1EC /* SingleChoiceTableViewController.swift in Sources */,
9152421B1F115C4D003AF58D /* Localizable.swift in Sources */,
17FE322A1F081E4F00410D7A /* LoginError.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
6 changes: 4 additions & 2 deletions Brisk iOS/Login/LoginCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ final class LoginCoordinator {
// MARK: - Private

fileprivate func showError(_ error: LoginError) {
let alert = UIAlertController(title: NSLocalizedString("Global.Error", comment: ""), message: error.localizedDescription, preferredStyle: .alert)
let cancel = UIAlertAction(title: NSLocalizedString("Global.Error.TryAgain", comment: ""), style: .cancel) { [weak self] _ in
let global = Localizable.Global.self

let alert = UIAlertController(title: global.error.localized, message: error.localizedDescription, preferredStyle: .alert)
let cancel = UIAlertAction(title: global.tryAgain.localized, style: .cancel) { [weak self] _ in
self?.loginController?.dismiss(animated: true, completion: nil)
}
alert.addAction(cancel)
Expand Down
3 changes: 2 additions & 1 deletion Brisk iOS/Login/LoginError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ enum LoginError: Error {
extension LoginError: LocalizedError {
var errorDescription: String? {
switch self {
case .invalidEmail: return NSLocalizedString("LoginError.InvalidEmail", comment: "")
case .invalidEmail:
return Localizable.Login.Error.invalidEmail.localized
}
}
}
90 changes: 90 additions & 0 deletions Brisk iOS/Model/Localizable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Foundation

public typealias Localize = String
protocol LocalizeRepresentable: RawRepresentable {
var localized: String { get }
}


enum Localizable {
enum Global: Localize, LocalizeRepresentable {
case error = "Global.Error"
case tryAgain = "Global.Error.TryAgain"
case success = "Global.Success"
case failed = "Global.Failed"
case required = "Global.Required"
case optional = "Global.Optional"
case dismiss = "Global.Dismiss"
case cancel = "Global.Cancel"
}

enum Login {
enum Error: Localize, LocalizeRepresentable {
case invalidEmail = "LoginError.InvalidEmail"
}
}

enum Radar: Localize, LocalizeRepresentable {
case product = "Radar.Product"
case area = "Radar.Area"
case version = "Radar.Version"
case classification = "Radar.Classification"
case reproducibility = "Radar.Reproducibility"
case configuration = "Radar.Configuration"
case title = "Radar.Title"
case description = "Radar.Description"
case steps = "Radar.Steps"
case expected = "Radar.Expected"
case actual = "Radar.Actual"
case notes = "Radar.Notes"
case attachament = "Radar.Attachment"
case noAttachaments = "Radar.Attachment.NoAttachments"

enum Placeholder: Localize, LocalizeRepresentable {
case description = "Radar.Description.Placeholder"
case steps = "Radar.Steps.Placeholder"
case expected = "Radar.Expected.Placeholder"
case actual = "Radar.Actual.Placeholder"
case notes = "Radar.Notes.Placeholder"
}

enum View {
enum Title: Localize, LocalizeRepresentable {
case duplicate = "RadarView.Title.Duplicate"
case new = "RadarView.Title.New"
}
}

enum Post: Localize, LocalizeRepresentable {
case success = "Radar.Post.Success"
}

enum TwoFactor: Localize, LocalizeRepresentable {
case title = "Radar.TwoFactorAuth.Title"
case message = "Radar.TwoFactorAuth.Message"
case submit = "Radar.TwoFactorAuth.Submit"
}
}

enum Settings {
enum OpenRadar: Localize, LocalizeRepresentable {
case placeholder = "Settings.OpenradarPlaceholder"
case confirm = "Settings.Openradar.Confirm"
case message = "Settings.Openradar.Message"
case clear = "Settings.Openradar.Clear"
}

enum AppleRadar: Localize, LocalizeRepresentable {
case placeholder = "Settings.AppleRadarPlaceholder"
case confirm = "Settings.AppleRadar.Confirm"
case message = "Settings.AppleRadar.Message"
case logout = "Settings.AppleRadar.Logout"
}
}
}

extension LocalizeRepresentable where RawValue == Localize {
var localized: String {
return NSLocalizedString(rawValue, comment: "")
}
}
43 changes: 22 additions & 21 deletions Brisk iOS/Radar/RadarCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ final class RadarCoordinator: NSObject {
if let radar = radar {
self.radar = ViewModel(radar)
controller.duplicateOf = duplicateOf
controller.title = NSLocalizedString("RadarView.Title.Duplicate", comment: "")
controller.title = Localizable.Radar.View.Title.duplicate.localized
} else {
controller.title = NSLocalizedString("RadarView.Title.New", comment: "")
controller.title = Localizable.Radar.View.Title.new.localized
}
controller.radar = self.radar
root.viewControllers = [controller]
Expand Down Expand Up @@ -167,7 +167,7 @@ extension RadarCoordinator: RadarViewDelegate {
}

func versionTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Version", comment: ""), content: radar.version, placeholder: "") { [unowned self] (text) in
showEnterDetails(title: Localizable.Radar.version.localized, content: radar.version, placeholder: "") { [unowned self] (text) in
self.radar.version = text
}
}
Expand All @@ -185,53 +185,53 @@ extension RadarCoordinator: RadarViewDelegate {
}

func configurationTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Configuration", comment: ""), content: radar.configuration, placeholder: "") { [unowned self] (text) in
showEnterDetails(title: Localizable.Radar.configuration.localized, content: radar.configuration, placeholder: "") { [unowned self] (text) in
self.radar.configuration = text
}
}

func titleTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Title", comment: ""), content: radar.title, placeholder: "") { [unowned self] (text) in
showEnterDetails(title: Localizable.Radar.title.localized, content: radar.title, placeholder: "") { [unowned self] (text) in
self.radar.title = text
}
}

func descriptionTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Description", comment: ""),
showEnterDetails(title: Localizable.Radar.description.localized,
content: radar.description,
placeholder: NSLocalizedString("Radar.Description.Placeholder", comment: "")) { [unowned self] (text) in
placeholder: Localizable.Radar.Placeholder.description.localized) { [unowned self] (text) in
self.radar.description = text
}
}

func stepsTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Steps", comment: ""),
showEnterDetails(title: Localizable.Radar.steps.localized,
content: radar.steps,
placeholder: NSLocalizedString("Radar.Steps.Placeholder", comment: "")) { [unowned self] (text) in
placeholder:Localizable.Radar.Placeholder.steps.localized) { [unowned self] (text) in
self.radar.steps = text
}
}

func expectedTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Expected", comment: ""),
showEnterDetails(title: Localizable.Radar.expected.localized,
content: radar.expected,
placeholder: NSLocalizedString("Radar.Expected.Placeholder", comment: "")) { [unowned self] (text) in
placeholder: Localizable.Radar.Placeholder.expected.localized) { [unowned self] (text) in
self.radar.expected = text
}
}

func actualTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Actual", comment: ""),
showEnterDetails(title: Localizable.Radar.actual.localized,
content: radar.actual,
placeholder: NSLocalizedString("Radar.Actual.Placeholder", comment: "")) { [unowned self] (text) in
placeholder: Localizable.Radar.Placeholder.actual.localized) { [unowned self] (text) in
self.radar.actual = text
}
}

func notesTapped() {
showEnterDetails(title: NSLocalizedString("Radar.Notes", comment: ""),
showEnterDetails(title: Localizable.Radar.notes.localized,
content: radar.notes,
placeholder: NSLocalizedString("Radar.Notes.Placeholder", comment: "")) { [unowned self] (text) in
placeholder: Localizable.Radar.Placeholder.notes.localized) { [unowned self] (text) in
self.radar.notes = text
}
}
Expand Down Expand Up @@ -292,22 +292,23 @@ extension RadarCoordinator: APIObserver {
}

func didFail(with error: SonarError) {

radarViewController?.hideLoading()
let alert = UIAlertController(title: NSLocalizedString("Global.Error", comment: ""), message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("Global.Dismiss", comment: ""), style: .cancel))
let alert = UIAlertController(title: Localizable.Global.error.localized, message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: Localizable.Global.dismiss.localized, style: .cancel))
radarViewController?.present(alert, animated: true)
}

func didPostToAppleRadar() {
radarViewController?.hideLoading()
let delay = 3.0
radarViewController?.showSuccess(message: NSLocalizedString("Radar.Post.Success", comment: ""), autoDismissAfter: delay)
radarViewController?.showSuccess(message: Localizable.Radar.Post.success.localized, autoDismissAfter: delay)
finish()
}

func didPostToOpenRadar() {
radarViewController?.hideLoading()
radarViewController?.showSuccess(message: NSLocalizedString("Radar.Post.Success", comment: ""))
radarViewController?.showSuccess(message: Localizable.Radar.Post.success.localized)
finish()
}
}
Expand All @@ -317,15 +318,15 @@ extension RadarCoordinator: APIObserver {

extension RadarCoordinator: TwoFactorAuthenticationHandler {
func askForCode(completion: @escaping (String) -> Void) {
let alert = UIAlertController(title: NSLocalizedString("Radar.TwoFactorAuth.Title", comment: ""), message: NSLocalizedString("Radar.TwoFactorAuth.Message", comment: ""), preferredStyle: .alert)
let alert = UIAlertController(title: Localizable.Radar.TwoFactor.title.localized, message: Localizable.Radar.TwoFactor.message.localized, preferredStyle: .alert)
alert.addTextField { (field) in
field.keyboardType = .numberPad
let bodyDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
field.font = UIFont(descriptor: bodyDescriptor, size: bodyDescriptor.pointSize)
field.autocorrectionType = .no
field.enablesReturnKeyAutomatically = true
}
alert.addAction(UIAlertAction(title: NSLocalizedString("Radar.TwoFactorAuth.Submit", comment: ""), style: .default, handler: { _ in
alert.addAction(UIAlertAction(title: Localizable.Radar.TwoFactor.submit.localized, style: .default, handler: { _ in
guard let field = alert.textFields?.first else { preconditionFailure() }
guard let text = field.text, text.isNotEmpty else {
self.askForCode(completion: completion)
Expand Down
98 changes: 49 additions & 49 deletions Brisk iOS/Radar/RadarViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,59 +83,59 @@ final class RadarViewController: UITableViewController, StoryboardBacked, Loadin
switch indexPath.section {
case 0:
switch indexPath.row {
case 0:
left = NSLocalizedString("Radar.Product", comment: "")
right = radar.product.name
case 1:
left = NSLocalizedString("Radar.Area", comment: "")
right = radar.area?.name ?? ""
selectable = Area.areas(for: radar.product).isNotEmpty
case 2:
left = NSLocalizedString("Radar.Version", comment: "")
right = radar.version
case 3:
left = NSLocalizedString("Radar.Classification", comment: "")
right = radar.classification.name
case 4:
left = NSLocalizedString("Radar.Reproducibility", comment: "")
right = radar.reproducibility.name
case 5:
left = NSLocalizedString("Radar.Configuration", comment: "")
right = radar.configuration
rightPlaceholder = NSLocalizedString("Global.Optional", comment: "")
case 0:
left = Localizable.Radar.product.localized
right = radar.product.name
case 1:
left = Localizable.Radar.area.localized
right = radar.area?.name ?? ""
selectable = Area.areas(for: radar.product).isNotEmpty
case 2:
left = Localizable.Radar.version.localized
right = radar.version
case 3:
left = Localizable.Radar.classification.localized
right = radar.classification.name
case 4:
left = Localizable.Radar.reproducibility.localized
right = radar.reproducibility.name
case 5:
left = Localizable.Radar.configuration.localized
right = radar.configuration
rightPlaceholder = Localizable.Global.optional.localized
default: break
}
case 1:
switch indexPath.row {
case 0:
left = NSLocalizedString("Radar.Title", comment: "")
right = radar.title
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
case 1:
left = NSLocalizedString("Radar.Description", comment: "")
right = radar.description
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
case 2:
left = NSLocalizedString("Radar.Steps", comment: "")
right = radar.steps
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
case 3:
left = NSLocalizedString("Radar.Expected", comment: "")
right = radar.expected
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
case 4:
left = NSLocalizedString("Radar.Actual", comment: "")
right = radar.actual
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
case 5:
left = NSLocalizedString("Radar.Notes", comment: "")
right = radar.notes
rightPlaceholder = NSLocalizedString("Global.Required", comment: "")
default: break
}
switch indexPath.row {
case 0:
left = Localizable.Radar.title.localized
right = radar.title
rightPlaceholder = Localizable.Global.required.localized
case 1:
left = Localizable.Radar.description.localized
right = radar.description
rightPlaceholder = Localizable.Global.required.localized
case 2:
left = Localizable.Radar.steps.localized
right = radar.steps
rightPlaceholder = Localizable.Global.required.localized
case 3:
left = Localizable.Radar.expected.localized
right = radar.expected
rightPlaceholder = Localizable.Global.required.localized
case 4:
left = Localizable.Radar.actual.localized
right = radar.actual
rightPlaceholder = Localizable.Global.required.localized
case 5:
left = Localizable.Radar.notes.localized
right = radar.notes
rightPlaceholder = Localizable.Global.required.localized
default: break
}
case 2:
left = NSLocalizedString("Radar.Attachment", comment: "")
right = "No attachments"
left = Localizable.Radar.attachament.localized
right = Localizable.Radar.noAttachaments.localized
selectable = false // not implemented yet

default: break
Expand Down
Loading

0 comments on commit 8354201

Please sign in to comment.