【问题标题】:Swift - read plist file to an array?Swift - 将 plist 文件读取到数组中?
【发布时间】:2016-08-17 04:14:56
【问题描述】:

我创建了一个从英语单词到西班牙语单词的迷你翻译。我想使用 englishArray.plist 而不是我的 englishArray = ["the cat"] 我怎样才能创建这个?

我还使用了 localizable.strings 来检索“el gato”的值“the cat”,但我想从englishArray.plist 中检索它

我从这个开始,但不确定我是否走在正确的道路上

let path = NSBundle.mainBundle().pathForResource("englishArray", ofType: "plist") 
let plistEnglishArray = NSArray(contentsOfFile: path!)

这是我的其余代码:

var englishArray: [String] = ["rainbow", "boots", "heart", "leaf", "umbrella", "tired", "angry", "cry", "the cat" ]


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.translateTextField.delegate = self
    picker.delegate = self
    picker.dataSource = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func translateButtonTapped(sender: UIButton) {

    let emptyString = self.translateTextField.text

    if (emptyString!.isEmpty) {

        print("please enter a word")

    }

    for transIndex in englishArray.indices {
        if englishArray[transIndex] == emptyString!.lowercaseString {

            //englishArray

            //translateLabel.text = "\(spanishArray[transIndex])"
            translateLabel.text = NSLocalizedString(emptyString!.lowercaseString, comment:"")


            print(emptyString)
            return

        }
    }
}

【问题讨论】:

  • 你的根对象是一个字典。您有两个选择:导入字典或修复您的 plist 文件

标签: arrays swift file nsarray nsbundle


【解决方案1】:

将您的root 对象更改为Array,然后

var myEnglishArray: [String] = []
if let URL = NSBundle.mainBundle().URLForResource("englishArray", withExtension: "plist") {
      if let englishFromPlist = NSArray(contentsOfURL: URL) as? [String] {
        myEnglishArray = englishFromPlist
      }
    }

【讨论】:

  • 你为什么不直接使用条件转换if let englishArray = NSArray(contentsOfURL: url) as? [String] { 转换你的 NSArray
  • 您不需要额外的数组和/或附加if let url = NSBundle.mainBundle().URLForResource("englishArray", withExtension: "plist"), englishArray = NSArray(contentsOfURL: url) as? [String] { for word in englishArray { print(word) } }
  • 这段代码是放在 viewDidLoad() 中的吗? @khuong291
  • 如果您需要将数组转换为数据,您可以使用 keyed archiver
  • 我不太确定您为什么要将 [String] 数组转换为另一个 [String]。为什么不只是myEnglishArray = englishFromPlist 而不是for-in
【解决方案2】:

这将读取您的包中名为“englishArray.plist”的资源并将其存储在不可变变量english 中。这将是一个可选的,您应该在使用前进行测试。

它使用闭包来读取文件并返回数组,这使您可以使用不可变值而不是可以更改的可变变量。尽可能使用不可变对象是个好主意 - 它们可以提高稳定性。

import Foundation

let english:[String]? = {
  guard let URL = NSBundle
    .mainBundle()
    .URLForResource("englishArray", withExtension: "plist") else {
      return nil
  }
  return NSArray(contentsOfURL: URL) as? [String]
}()

【讨论】:

    【解决方案3】:

    这是 swift 3 的解决方案。对于此解决方案,您无需更改 plist 结构中的类型(保持 Dictionary、Array 不变)。另请注意,由于 plist 中的数组名称也是englishArray,因此第二个if 语句中的(键值)参数也是englishArray。

    var myEnglishArray: [String] = []
       if let URL = Bundle.main.url(forResource: "englishArray", withExtension: "plist") {
          guard let englishFromPlist = NSDictionary(contentsOf: URL) else { return [] }
          if let englishArray = englishFromPlist.value(forKey: "englishArray") as? [String] {
             for myEnglish in englishArray {
                myEnglishArray.append(myEnglish)
             }
          }
       }
    

    【讨论】:

      【解决方案4】:

      斯威夫特 4

      你可以使用纯swift类型的Codable

      首先从bundle加载Plist文件然后使用PropertyListDecoder

      完整代码-

          func setData() {
              // location of plist file
              if let settingsURL = Bundle.main.path(forResource: "JsonPlist", ofType: "plist") {
      
                  do {
                      var settings: MySettings?
                      let data = try Data(contentsOf: URL(fileURLWithPath: settingsURL))
                          let decoder = PropertyListDecoder()
                      settings = try decoder.decode(MySettings.self, from: data)
                      print("array  is \(settings?.englishArray ?? [""])")//prints array  is ["Good morning", "Good afternoon"]
      
      
                  } catch {
                      print(error)
                  }
              }
          }
      }
      struct MySettings: Codable {
      
          var englishArray: [String]?
      
          init(from decoder: Decoder) throws {
              let values = try decoder.container(keyedBy: CodingKeys.self)
              englishArray = try values.decodeIfPresent([String].self, forKey: .englishArray)
      
          }
      }
      

      【讨论】:

        【解决方案5】:

        斯威夫特 4

        最简单的方法是

            let url = Bundle.main.url(forResource: "Sounds", withExtension: "plist")!
            let soundsData = try! Data(contentsOf: url)
            let myPlist = try! PropertyListSerialization.propertyList(from: soundsData, options: [], format: nil)
        

        对象 myPlist 是一个数组或字典,无论您用作 plist 的基础。

        【讨论】:

        • 假设您在 viewDidLoad() 中有此代码,那么您如何将 myPlist 变量共享给其他文件?
        猜你喜欢
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-25
        • 2012-02-04
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多