从应用程序支持目录中的plist中读取翻译

时间:2017-04-28 08:54:51

标签: ios swift dictionary plist

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

  

Application \ Support / Translation / Translation.plist

我在我的应用程序中基本上想要做的是使用像

这样的东西

translate(input: "hello")

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

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
    }
}

1 个答案:

答案 0 :(得分:1)

您正在阅读Documents目录,正如您在帖子前面所说的那样,您的文件不在其中。而是它位于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。请记住,我的这个实现不会在应用程序运行时为刷新数据提供任何支持。

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