【譯】如何運用 Swift 的屬性包裝器實現應用本地化

如何運用 Swift 的屬性包裝器實現應用本地化

您好,Swift 開發者,在本文中,我想與您分享個人經驗和知識,主要內容有屬性包裝器Property Wrapper)的使用,以及如何簡化代碼並使其易於維護。我會經過幾個主題對此進行說明。html

在 Swift 5.1 中,Apple 引入了屬性包裝器,它可讓咱們在屬性和訪問邏輯(getter 和 setter)之間設置中間層。前端

下面的內容是在 @IBOutlet 變量內部使用屬性包裝器的簡便方法來實現應用本地化。android


優化下面這個基礎版本:ios

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)
    }
  }
}
複製代碼

咱們能夠用屬性包裝器 @Localized 改進代碼,以下:git

class NatureViewController: UIViewController {
  @Localized("natureTitle")
  @IBOutlet private var label: UILabel!
  
  @Localized("saveNatureButton")
  @IBOutlet private var button: UIButton!
}
複製代碼

這代碼看起來很優雅,不是嗎?下面讓咱們建立 @Localized 屬性包裝器。 將 key 當作枚舉來使用會更好,如:@Localized(.natureTitle)github

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

爲了能讓更多的類型可以支持 Localizable 協議, 咱們要實現 UILabelUIButton 的擴展方法。swift

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
  }
}
複製代碼

最後咱們只須要實現 LocalizationKey:後端

enum LocalizationKey: String {
  case 
  natureTitle, 
  saveNatureButton
}

extension LocalizationKey {
  var string: String {
    NSLocalizedString(rawValue, comment: rawValue)
  }
}
複製代碼

咱們能夠直接用 raw 的值來表示相應的 key,String 類型默認遵照這個協議,因此只須要枚舉中的值與 Localizable.strings 中的 key 保持一致就能夠了。app

最終的代碼以下:ide

class NatureViewController: UIViewController {
  @Localized(.natureTitle)
  @IBOutlet private var label: UILabel!
  
  @Localized(.saveNatureButton)
  @IBOutlet private var button: UIButton!
}
複製代碼

本章結束!關於 @Localized 還有一些潛在功能:

  • 格式化字符串數據,並進行動態替換。
  • 可以肯定來自指定的表單和資源包的字符串。

想了解更多關於屬性包裝器的知識,請閱讀官方文檔: Properties - The Swift Programming Language (Swift 5.2)

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索