iosswiftenumslocalization

Enum with localized string in swift


I want to use enumeration with localized string, so I do like this, it works, but the problem of this solution is : I can't get easily enum value from localized string, I must have the key to do it :

let option = DietWithoutResidueOption(rawValue: "NoDiet")

If not I must to call dietWithoutResidueOptionWith method to get enum value... :/

There are a better solution to store directly localizedString and not keys in enum ?

Thanks

Enumeration

  enum DietWithoutResidueOption: String {
  case noDiet = "NoDiet"
  case threeDays = "ThreeDays"
  case fiveDays  = "FiveDays"
  
  private func localizedString() -> String {
    return NSLocalizedString(self.rawValue, comment: "")
  }
  
  static func dietWithoutResidueOptionWith(#localizedString: String) -> DietWithoutResidueOption {
    switch localizedString {
    case DietWithoutResidueOption.threeDays.localizedString():
      return DietWithoutResidueOption.threeDays
    case DietWithoutResidueOption.fiveDays.localizedString():
      return DietWithoutResidueOption.fiveDays
    default:
      return DietWithoutResidueOption.noDiet
    }
  }
}

Localizable.strings

"NoDiet" = "NON, JE N'AI PAS DE RÉGIME";
"ThreeDays" = "OUI, SUR 3 JOURS";
"FiveDays"  = "OUI, SUR 5 JOURS";

call

println(DietWithoutResidueOption.fiveDays.localizedString())

Solution

  • You can use any StringLiteralConvertible, Equatable type for RawValue type of enum.

    So, how about:

    import Foundation
    
    struct LocalizedString: StringLiteralConvertible, Equatable {
    
        let v: String
    
        init(key: String) {
            self.v = NSLocalizedString(key, comment: "")
        }
        init(localized: String) {
            self.v = localized
        }
        init(stringLiteral value:String) {
            self.init(key: value)
        }
        init(extendedGraphemeClusterLiteral value: String) {
            self.init(key: value)
        }
        init(unicodeScalarLiteral value: String) {
            self.init(key: value)
        }
    }
    
    func ==(lhs:LocalizedString, rhs:LocalizedString) -> Bool {
        return lhs.v == rhs.v
    }
    
    enum DietWithoutResidueOption: LocalizedString {
        case NoDiet = "NoDiet"
        case ThreeDays = "ThreeDays"
        case FiveDays  = "FiveDays"
    
        var localizedString: String {
            return self.rawValue.v
        }
    
        init?(localizedString: String) {
            self.init(rawValue: LocalizedString(localized: localizedString))
        }
    }
    

    Using this, you can construct DietWithoutResidueOption by 3 ways:

    let option1 = DietWithoutResidueOption.ThreeDays
    let option2 = DietWithoutResidueOption(rawValue: "ThreeDays") // as Optional
    let option3 = DietWithoutResidueOption(localizedString: "OUI, SUR 3 JOURS")  // as Optional
    

    and extract the localized string with:

    let localized = option1.localizedString