从 Application Support Directory 中的 plist 中读取翻译

Reading translations from a plist in Application Support Directory

我从远程服务器检索翻译并将其保存在

Application\ Support/Translation/Translation.plist

我基本上想在我的应用程序中使用类似

的东西

translate(input: "hello")

为了将 hello 翻译成保存在我的 plist 文件中的翻译。我创建了一个函数,但在阅读内容时总是得到 nil。谁知道我做错了什么?

import Foundation

open class Translations {

    static func translate(input: String) -> String {

        var translations: [String: String] = [:] //Translation data
        let documentsDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
        let directoryURL = documentsDirectory?.appendingPathComponent("Translation")
        let file = directoryURL?.appendingPathComponent("Translation").appendingPathExtension("plist")

        if let plistXML = FileManager.default.contents(atPath: (file?.absoluteString)!) {
            do {//convert the data to a dictionary and handle errors.
                translations = try PropertyListSerialization.propertyList(from: plistXML, options: [], format: nil) as! [String:String]

            } catch {
                print("Error reading plist: \(error)")
            }
        }

        guard let translation = translations[input] else {
            return input
        }

        return translation
    }
}

您正在从 Documents 目录中读取,正如您之前在 post 中所说,您的文件不在该目录中。而是在 Application Support 目录中。 尽量确保您从同一位置保存和读取。

我还建议使用 String 的扩展来简化翻译,例如:

extension String {
    var translated: String {
        return Translation.default?.translate(self) ?? self
    }
}

那么你可以简单地做:

"SomeText".translated

这就是我实现翻译的方式:

    public final class Translation {
  static let `default`: Translation? = Translation()

  let translations: [String: String]

  init?() {
    guard let documentsURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first else {
      return nil
    }
    let translationURL = documentsURL.appendingPathComponent("Translation").appendingPathComponent("Translation").appendingPathExtension("plist")

    do {
      let data = try Data(contentsOfURL: translationURL)
      let propertyList = try PropertyListSerialization(from: data, options: [], format: nil)

      if let list = propertyList as? [String: String] {
        translations = list
      } else {
        return nil
      }
    } catch {
      // Handle error
      return nil
    }
  }

  func translate(_ input: String) -> String {
    guard let translated = translations[input] else {
      return input
    }
    return translated
  }
}

这样做的好处是您不必每次都从磁盘读取 propertyList 以 运行 进行翻译。请记住,一旦应用 运行ning.

,我的这个实现不提供任何刷新数据的支持

或者,您可以将 init 代码移动到一个单独的方法,并删除 init 方法的可空性。然后,每当下载新的 propertyList 时,您可以简单地调用 -refresh() 或任何您真正想要的。