• Localize Swift Application
  • Dmytro Pylypenko
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: chaingangway
  • Proofreader: Bruce-Pac

How to use Swift’s property wrapper to localize your application

Hello Swift developer, in this article I want to share my experience and knowledge on the use of Property Wrapper and how to simplify code and make it easier to maintain. I’ll illustrate this through a couple of themes.

In Swift 5.1, Apple introduced a property wrapper that lets us set up an intermediate layer between properties and access logic (getters and setters).

The following is a handy way to localize your application using a property wrapper inside the @ibOutlet variable.


Optimize the following base version:

class NatureViewController: UIViewController {
  @IBOutlet private var label: UILabel! {
    didSet {
      label.title = NSLocalizedString("natureTitle", comment: "")}}@IBOutlet private var button: UIButton! {
    didSet {
      button.setTitle(NSLocalizedString("saveNatureButton", comment: ""), for: .normal)
    }
  }
}
Copy the code

We can improve the code with the attribute wrapper @dust, as follows:

class NatureViewController: UIViewController {@Localized("natureTitle")
  @IBOutlet private var label: UILabel!
  
  @Localized("saveNatureButton")
  @IBOutlet private var button: UIButton!
}
Copy the code

This code looks elegant, doesn’t it? Let’s create the @mold property wrapper. It is better to use keys as enumerations, such as @reward (.natureTitle).

@propertyWrapper
struct Localized<T: Localizable> {
  private let key: LocalizationKey
  
  var wrappedValue: T? = nil {
    didSet{ wrappedValue? .set(localization: key)
    }
  }
  
  init(_ key: LocalizationKey) {
    self.key = key
  }
}
Copy the code

To enable more types to support the Localizable protocol, we implement extended methods of UILabel and UIButton.

protocol Localizable {
  func set(localization: LocalizationKey)
}

extension UIButton: Localizable {
  func set(localization key: LocalizationKey) {
    setTitle(key.string, for: .normal)
  }
}

extension UILabel: Localizable {
  func set(localization key: LocalizationKey) {
    text = key.string
  }
}
Copy the code

Finally we just need to implement LocalizationKey:

enum LocalizationKey: String {
  case 
  natureTitle, 
  saveNatureButton
}

extension LocalizationKey {
  var string: String {
    NSLocalizedString(rawValue, comment: rawValue)
  }
}
Copy the code

We can use the raw value to represent the key directly. String complies with this protocol by default, so we only need to match the key in the enumeration to Localizable. Strings.

The final code looks like this:

class NatureViewController: UIViewController {@Localized(.natureTitle)
  @IBOutlet private var label: UILabel!
  
  @Localized(.saveNatureButton)
  @IBOutlet private var button: UIButton!
}
Copy the code

End of chapter! There are some other potential features of @solidification:

  • Format string data and replace it dynamically.
  • The ability to determine strings from the specified form and resource bundle.

To learn more about property wrappers, read The official documentation: Properties – The Swift Programming Language (Swift 5.2)

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.